What is the "cheapest performance" way to have actors check if the player is nearby to them?
I've got an action game with fairly large maps, and a bunch of things like creatures and moveable-barrels scattered around the map. (I've got say 50 monsters, and 30 moveable barrels in the scene, but only about 5-10 of each onscreen at once).
To improve performance, I wrap their behaviours inside a rule that checks how close the player is. But I'm concerned that the way I'm doing this, in itself, takes a bit of performance, and I'm wondering what is the best technique for doing this?
==========
My PLAYER_CHARACTER stores their PosX,Y to a global attribute at all times.
Then my MONSTER actors all do this...
Timer: Every 1 second
Change Attribute: self.DistanceFromPlayerX = self.position.X - game.PlayerPosX
Change Attribute: self.DistanceFromPlayerY = self.position.Y - game.PlayerPosY
Then I wrap all of their behaviours in a rule that first checks...
If...
self.DistanceFromPlayerX < game.PlayerPosX + 300
self.DistanceFromPlayerX > game.PlayerPosX - 300
self.DistanceFromPlayerY < game.PlayerPosY + 300
self.DistanceFromPlayerY > game.PlayerPosY - 300
Then do all the behaviours the actor should do.
==========
But this seems like a fairly inefficient way to do it! Does anyone have another way that's cheaper on the processor?
I tried using Magnitude instead, but it seems even less efficient.
Has anyone generally come up with a smart way to have lots of actors that "shut down" while they out of the vicinity of the player?
- Murray
To improve performance, I wrap their behaviours inside a rule that checks how close the player is. But I'm concerned that the way I'm doing this, in itself, takes a bit of performance, and I'm wondering what is the best technique for doing this?
==========
My PLAYER_CHARACTER stores their PosX,Y to a global attribute at all times.
Then my MONSTER actors all do this...
Timer: Every 1 second
Change Attribute: self.DistanceFromPlayerX = self.position.X - game.PlayerPosX
Change Attribute: self.DistanceFromPlayerY = self.position.Y - game.PlayerPosY
Then I wrap all of their behaviours in a rule that first checks...
If...
self.DistanceFromPlayerX < game.PlayerPosX + 300
self.DistanceFromPlayerX > game.PlayerPosX - 300
self.DistanceFromPlayerY < game.PlayerPosY + 300
self.DistanceFromPlayerY > game.PlayerPosY - 300
Then do all the behaviours the actor should do.
==========
But this seems like a fairly inefficient way to do it! Does anyone have another way that's cheaper on the processor?
I tried using Magnitude instead, but it seems even less efficient.
Has anyone generally come up with a smart way to have lots of actors that "shut down" while they out of the vicinity of the player?
- Murray
Comments
On the monster actor just create a self attribute (ie. distance) and give it the value at which you want the monster to react to the player.
On the player actor constrain his x and y position to game attributes.
Then create a rule that says:
When attribute self.distance ≤ to magnitude(self.poitionX-playerPositionX, self.positionY-playerPositionY)
--Do something
I'm not sure about the magnitude formula, but with a couple of tests you can figure it out.
Using this methods you avoid having a timer on every single monster and the rule is considerably smaller.
Similar, but a bit slower, I think. I lose a few more frames a second.
But thanks, I'll keep trying.
(I'm getting signed out constantly here, very annoying. I used to just be logged in constantly for weeks on end. Is that getting fixed soon? Makes using the forums quite frustrating).
then have a rule something like:
when the monster dies
Change Game.Integer to Self.ID
Put a rule that says
When Game.Integer = Self.ID-1
Start Movement
You can use this tactic in other ways too, you just gotta be creative with the attributes.
You could also put rules in the ground that the player walks on, or use invisible actors for areas and have a rule like:
When Player Overlaps or Collides with Area1
Change Area1.Boolean to true, otherwise False
Then add a rule to your monsters that are in "Area1" that is something like:
When Area1.Boolean =true
Start Movement
Repeat for additional areas...
Hope this helps