Closed TheFunnyBrain closed 1 year ago
Yeah that is a very useful feature, if you do it, please do it as a Node, and name it something like
LockComponent Or TargetingSystem
I advise adding additional stuff for it like : Object Targeting (useful for games with Pickup system) Enemy Targeting. Allies Targeting.
And then export a variable in this TargetingComponent
@export var TargetingRaycast :Raycast3D
Use this variable or something similar for detecting the above stuff. So by this, we should have an advanced targeting system, while being optional and customizable.
What do you think ?
Another ideas that could help :
The Targeting/Locking system can be made as follows so we can apply it to the examples above.
First Node :
TargetingComponent, will be added to the player, handles all targeting functions, and has a Placeholder functions aka "Virtual Functions" That can be used to do specific actions in other components.
And this component also got 5 signals, I will just write example code :
extends Node
class_name TargetingComponent
@export var detection_raycast : RayCast3D
@export var detectable_object_group : String = "detectable_object" # we can use the node group feature in Godot
@export var detectable_player_group : String = "player" # I am calling any Enemy/AI/Ally a player
var detected_object : Node3D
var detected_player : Node3D
signal object_detected(object: Node3D)
signal enemy_detected(object: Node3D)
signal ally_detected(object: Node3D)
signal player_detected(object: Node3D)
signal detected(object: Node3D) #this activates for all
func _process(delta):
if detection_raycast.is_colliding():
if detected_player == detection_raycast.get_collider() or detected_object == detection_raycast.get_collider():
return
if detection_raycast.get_collider().is_in_group(detectable_object_group):
detected_object = detection_raycast.get_collider()
detected.emit(detected_object)
object_detected.emit(detected_object)
return
if detection_raycast.get_collider().is_in_group(detectable_player_group):
detected_player = detection_raycast.get_collider()
detected.emit(detected_player)
player_detected.emit(detected_player)
if false: #Needs a Specific check to know if this player is enemy or not
enemy_detected.emit(detected_player)
if false: #Needs a Specific check to know if this player is ally or not
ally_detected.emit(detected_player)
return
And so on in the process functions, we make if conditions to emit specific signals.
In Godot Signals can be connected to any function, so you can connect signal from this node to a function in another code that handles what the player will do when there is a lockable/intractable object/player.
Edit : I wrote all of the code from my memory, and on my mobile, so expect it to need fixes in Godot Engine.
Edit 2 : I just realized that I never did a check in the code to not emit the signal unless the interactable object changes, now this code will keep emitting the signal every frame when the player is looking to the object.
Edit 3 : I noticed some typos in the code, so some adjustmenst, still it may need testing.
Edit 4 : expanded the code
Perhaps we need also to have a Team System, Not an actual Team System but I mean something to classify objects and players, useful for most games.
something like :
enum {NATURAL_OBJECT=0}
var team_id : int = 0
so we can assign a number for the team_id to seperate players/AI in teams.
and leave at 0 for natural object that can be picked up, or non-violent AI.
For now I am not sure if the team system should be in the TargetingComponent, or have a seperate Component.
Just Pushed a new commit
it contains a CombatComponent, so we can use this one for Damaging the Player Health, and Assigning Teams
also the damage function can be used with Natural Objects to register a physics hit or something
so the CombatComponent is made for a lot not only players.
I will work on the Firearms example to also showcase the usage of CombatComponent.
for now you can look at its code.
@TheFunnyBrain
Lol, I JUST REALIZED I UNDERSTOOD Lock system wrong, resulting me working on another features, LOL.
but now I understand your game LOCK System.
still it will help.
in my game the lock system was using one Variable called in_game, your idea is much better.
Please add this system, as it will help a lot of games that will use this Template, plus, it may help turn this Template into a whole Demo, because it will make Menus work flawlessly with this template.
@TheFunnyBrain
I made this PlayerController Script : https://github.com/ywmaa/Advanced-Movement-System-Godot/commit/c3ef313d57a67dd08ff472ef30bd0424fce5fb75#diff-2642a77dfb50662044ce692d38d2067a604e56aafbe6372b1dce31a50d6c576f
So you can add the system you meant here.
Awesome! :) Thank you :)
I have added the feature to PlayerGamePlayComponent in a local branch, but it's no trouble to throw it over :)
I'm just trying to work out how best to get the locks connected to the player, but as an optional component. Initially it's as a preloaded .gd script, so I'm going to try and turn it into a proper node that can be there or not. :)
It's strange migrating from Unity, where I'd do something like a null check or even trygetcomponent at launch. :) That said, I am really getting a kick out of the friendliness of GDScripts - is so simple with handling things like dictionaries!
I am also looking to try and make it support signals, so that we could for example have debug UI.
I've rewritten it in nodes, added a nullcheck etc, so hopefully it'll do the trick. :)
Would I be okay to add a pause key (e.g. the 'p' key) to test the system works? :) It's doing absolutely nothing presently, which is exactly as intended - so I guess the next test is to add a lock, see what happens.
Would I be okay to add a pause key (e.g. the 'p' key) to test the system works?
Yes, no problem, actually you should consider adding a way so the users of the template know that this feature exists.
for me the Pause Key "p" is good enough, and I may add a simple Pause screen for it in the future.
That sounds perfect! :) I've added the 'p' key in for now, and hopefully I can add a small UI element to tell the user what's happening. :)
I did notice an amusing side effect of my implementation - the player walks, or runs indefinitely whilst locked! I'll resolve that now, I think it might be that I need to switch the character to an idle state. :)
I'm guessing physics might also be a consideration, but I won't get ahead of myself for now. Quite frankly, I'm astonished any of my GDScript is working on day 2, it is a nice feeling.
I saw your scripts, and you are a good user of GD script.
Keep going 👍
Thank you :) That's really encouraging to hear, it's a nice jump, and I'm having fun. I have a perpetual fear of wading into someone's project, and busting things through lack of knowledge.
I've made a pull request now, and I can fix any issues, add anything, change things etc. :)
For the company I work for, we make use of a lock system, to restrict player movement whilst using UI, or in a cutscene.
The way we found best, is a privately settable Dictionary of strings.
Locks.AddLock("TalkingToCompanionA")
Locks.RemoveLock("TalkingToCompanionA")
Input can then check locks.count/locks.length etc with a property or method, e.g.
The strings are set by developers, and help with debugging as we can print out what's going on.
The collection is important, as it means multiple things can manipulate the locks without unlocking things unintentionally
e.g. A player is on a pause menu, fast travels, then return to the pause menu without the fast travel's locks interfering with the pause menu still needing the player to be immobile after the animation.
This one is something I'd be happy to work on, but only if it's useful. :)