How to define a variable as another variable only once without updating it constantly?

Godot Version

4.2.1 (Steam)


So I am trying to work on the algorithm of an enemy that follows the player in a 3d maze. However, I don’t want the enemy to always know where the player is if it can’t see the player, so I want to make it in a way that it only follows the player if it sees the player, or if it hasn’t reached a spot that it has last saw the player in. But here is my problem: To store the location of the last seen player position, in the enemy script i created a Vector3 variable lastseenplayerpos that is defined as 0, 0, 0 until it sees the player and updates that. But the way I update the lastseenplayerpos variable is this:
if seesplayer:
lastseenplayerpos = playerpos
#The playerpos variable is updated by the level script

But when I do this, the last seen playerpos ALWAYS equals the players real position, even if it can no longer see the player, since the lastseenplayerpos is defined as playerpos. So I need a way to define a variable as another variable only ONCE without constantly updating it to that variable. So if the enemy sees the player and the playerpos is Vector3(0,10,0), then the lastseenplayerpos should be Vector3(0,10,0), but if the player moves out of sight to Vector3(0,11,0), then lastseenplayerpos should still be Vector3(0,10,0), not Vector3(0,11,0).

Please help, I am a total noob and can’t find anything online.

There’s definitely something wrong with the seesplayer(). From a blind perspective, I can guess that you are not reseting a global bool to false, so the game thinks is always true after seeing it once. If this is the case, just make sure to put the bool locally false (so it’s reseted every frame, or really, is created every frame as false)

Oh wait, I typoed in my question - seesplayer is actually a bool variable, not a function.But I have a function update_seesplayer() that is called in _physics_process(), and it works by having a ray cast and if it is colliding with an entity in group player, seesplayer = true. I could have sworn there was also an else: that set seesplayer to false, but I will chack when I get home, I’m on my phone right now.

Ok never mind I am just stupid and forgot to write the else:. Sorry for wasting time!

I agree with @feref28

If seesplayer:
  lastseenplayerpos = playerpos

If this is what you do, we just need ensure seesplayer updates before player position changes to be out of sight.

I guess it depends on how often you check the vision. If it’s every frame, it could be hard to say without knowing if movement transition is quantized or continuous based, as well as if the vision is really blocked.

Yeah it is in a function update_seesplayer() that is called in _physics_process()

Could you describe the player movement and how you do vision detection and the obstacle in which blocks vision?

If player movement is continuous then the last seen position will most likely end up being larger than expected since even a small portion of the player sticking out from a corner will update the last seen position. (I’m not sure what can be done here as this seems to me as expected; you could tune the detection by creating a smaller, separate hitbox just for the being seen system)

If movement is quantized, like a grid board jumping immediately to next space, then we should check to see how your vision system is working. Because if its raycasting we need to make sure the collision layer for the ray will hit both the player and the obstacle. Otherwise it could pass right through the obstacle if it’s not in the same collision layer and not being checked by the ray.

Well, my problem is solved (I was just being stupid), but, yes, the vision raycast has the same collision mask as both the player and terrain

1 Like