Hello!
I have been stumped on this for a while now, my goal is to have two Npcs (who are an instantiated scene of the main NPC tree) recognize each other and then change to the same state to interact i.e have a state to fight or two sit down next to one another. However the issue I am running into is while I know how to get the npcs to recognize one another, I dont know how to translate this to making them share the same state.
I had a theroy there could be signals to connect, or maybe store the information in a dictionary, but how to do this I am unsure, I am adding the code I am using to recgonize the NPCS and my state machine code.
func _on_interact_area_body_entered(body: Node3D) -> void:
print(Globals.alreadyemit)
if body.name == "Player":
Globals.play1 = true
$"../../Door/Interact".visible = true
if body.is_in_group("NPC"):
if body.has_method("_on_interacted()"):
print("Meow")
else:
pass
func _on_interacted()
pass
func generatenum():
if !Globals.is_following :
var randomstate = statechangerandom.randf_range(1,10)
if randomstate <= 3:
transitioned.emit(self, "walk")
elif randomstate <= 6:
transitioned.emit(self, "run")
else:
transitioned.emit(self, "stop")
elif !Globals.is_following and Globals.npcinteracting:
generateinteractions()
func generateinteractions():
print("bitch")
You could use signals, you could have the two NPCs call functions on each other directly, you could have some sort of global coordinator in the scene… there’s various ways you can do this.
What do you want to trigger them recognizing each other? Does one decide and the other responds? Do they need to be a certain distance away (this could be collision or range checks), or line of sight (raycast)?
Hi, thank you, so I want to make them choose a random state and have them both match it, I have tried used a signal system to make it so the first one recognizes the other and sends the signal to my state machine however it didnt seem to really work, they use an area3d_enter signal to detect if a NPC has entered, they all are part of the NPC group
How many NPCs do you have? You’re referencing some Globals. vars, so (assuming these refer to a global script…) bear in mind if you have multiple NPCs they may all be scribbling on these values and overwriting each other’s work.
Your generatenum() function won’t do anything if Globals.is_following is true.
I think if I were doing this, I’d do something like:
# partial NPC script, untested
enum Action { stop, walk, run }
var action: Action = Action.stop
func choose_next_action():
var rnd = randf_range(0.0, 1.0)
if rnd <= 0.3: action = Action.walk
elif rnd <= 0.6: action = Action.run
else: action = Action.stop
for npc in get_parent().get_children():
if npc != self && npc.is_in_group("NPCs"):
if npc.action == action:
npc.coordinate(self)
func coordinate(npc: Node):
print(str(self) + " & " + str(npc) + " are coordinating!")
# sync up, do stuff
I understand making them choose the next action, there are mutiple NPcs in the scene and where I am stuck is how to “log” or store who the two NPCs who looked at eachother and chose to interact will interact, I.e change from their walk/idle/run state to the interact one, sorry if this is confusing I hav ejust been so stuck
If you look at the example code, after they choose an action, there’s this:
That should scan the other NPCs and see if any has the same action as the action we just chose. At that point, it’ll call coordinate(), in which you have two NPCs (self and npc) who have the same action and are ready to interact.
So, in coordinate() you can set interacting = true and npc.interacting = true, you can have each of the two set an interacting_with var that refers to the other so they can find each other in code. Then in process() or whatever you can do something like:
if is_instance_valid(interacting_with): # Check if NPC got deleted...
# do interaction stuff; move towards, check if in range, do things...