News › Forums › RAIN › Sample Projects, How To, and Code › Behavior Tree example requests: Enemy search for the lost player
Tagged: Behavior Tree, Custom Action, last known position
This topic contains 4 replies, has 2 voices, and was last updated by book 11 months, 3 weeks ago.
-
AuthorPosts
-
July 15, 2022 at 7:20 am #31574
Hi Everyone!
I have a sensor on my enemy. When he sees the player he chases after him until the player is no longer in the sensor, then the enemy goes back to his waypoints or whatever he was doing.What is the best way of having the enemy keep going in the direction the player went for a while. When the enemy’s sensor no longer detects the player, I want him to go towards the last place he saw the player and search around that area.
I tried and failed! and now I don’t know how to do it!!
Please Help!July 16, 2022 at 6:06 pm #31773Probably the easiest way to handle this is with a custom action, and it only needs to do one small thing: copy the current position of your target to new variable. Drop this code into a new CSharp file in your project and you can add a custom action to your behavior tree that points to it. You would put this right after a successful detect of the player.
using RAIN.Action; using RAIN.Core; using RAIN.Entities.Aspects; using UnityEngine; [RAINAction] public class StoreLastPosition : RAINAction { public StoreLastPosition() { actionName = "StoreLastPosition"; } public override ActionResult Execute(AI ai) { // If you use the Aspect Variable property //RAINAspect tPlayerAspect = ai.WorkingMemory.GetItem<RAINAspect>("playerAspect"); // If you use the Mount Point Variable property //Transform tPlayerMount = ai.WorkingMemory.GetItem<Transform>("playerMount"); // If you use the Form Variable property GameObject tPlayerForm = ai.WorkingMemory.GetItem<GameObject>("playerForm"); // Store the last position in our memory for use later ai.WorkingMemory.SetItem<Vector3>("playerLastPosition", tPlayerForm.transform.position); return ActionResult.SUCCESS; } }
This will give you a new variable (playerLastPosition) to use in a move node when you no longer detect the player. Let me know if you need any help with it.
July 17, 2022 at 9:27 am #31797Thanks Sigil. Yes I got something like that working, albeit in a different way. After the player ran out of the enemy’s sensor, the enemy would go into SEARCH mode and the custom action below is called. It just looks for the player gameobject and sets a waypoint to go there. It seems to work. It’s probably not the best way but I was just guessing.
What I’m really trying to figure out next is how I can get the enemy to search around that area that he spotted the player in. I have two ideas in my head and I don’t know how to do either of them.
Number 1 have the enemy instantiate a waypoint network at the point that he last saw the player. This could make it look like he’s searching around that area. But how could you make sure each point of the waypoint were spawned in good positions. i.e: not in a wall, or not out off the navigation mesh, or any other erroneous positions they could start in.
Number 2 have 4 or 5 waypoint networks already premade in the scene that would be used for searching in different areas. The enemy, when searching, then chooses the nearest waypoint network to search in after last seeing the player. So if there is a room with 4 zones, each zone has it’s own waypoint network and if the enemy last seen the player in zone two for example, the enemy calculates that the nearest waypoint network is in zone two, so it uses that set of waypoints to use for searching.
Number looks like a less error prone way of doing it.public override void Start(AI ai) { base.Start(ai); player = GameObject.Find("Player").transform; } public override ActionResult Execute(AI ai) { WaypointSet myWayPoint = new WaypointSet(); wayPoint1.position = player.transform.position; myWayPoint.AddWaypointAtLocation(player.transform.position, "Two", -1); ai.WorkingMemory.SetItem("varWayPoint", myWayPoint); return ActionResult.SUCCESS; }
July 21, 2022 at 9:47 pm #32111Sorry I didn’t get back to this sooner, the idea I came up with is similar to your second option.
If you have the networks in place ahead of time you can use a Waypoint Patrol node whenever you go into an alarmed mode. Normally you just put a Move node inside the Waypoint Patrol, but you can also put additional behavior tree logic. So for instance (using shorthand here):
Sequencer Evaluate Expression (if alarmed) Waypoint Patrol (use the quoted name of your Waypoint Route) Move (move to the Move Target Variable specified in the Waypoint Patrol) Random Evaluate Expression (just have it return success) Animate (play a looking around animation)
So what this will do for you is this:
If the AI is currently alarmed, patrol the Waypoint Route specified. After successfully reaching each waypoint randomly choose to either do nothing (the Evaluate Expression that just returns) or to play an animation (Animate). Then head on to the next waypoint.
The patrol will repeat forever, so you can put the whole thing in a parallel, making the AI only patrol for a limited time, like so:
Sequencer Evaluate Expression Parallel (set Succeed to any Timer (like 10 seconds, or random(7, 10) would work too) Waypoint Patrol Move Random ...
Let me know if you need more info, Behavior Trees can be complex sometimes (and we’re working on making the documentation better).
July 25, 2022 at 11:06 am #32330Hi Sigil, thanks for replying.
But I don’t need the enemy to go to random waypoints. I want him to choose the NEAREST waypoint system (to search) from the last place that he saw the player.
-
AuthorPosts
You must be logged in to reply to this topic.