News › Forums › General Discussion › Question - Check players distance from ai
This topic contains 4 replies, has 2 voices, and was last updated by prime 1 month, 2 weeks ago.
-
AuthorPosts
-
November 19, 2022 at 8:47 pm #34360
Hello, I am currently working on setting up an ai where I need a constraint to check if the player is within a certain range of the ai or not. Would anyone be able to give me an example of code/some information on how I can do this? I originally thought of setting a variable up in memory, and having a script constantly update that variable with the player’s vector 3 position, however I am not sure how to do that either.
November 19, 2022 at 9:11 pm #34361Here’s an example of a custom action that checks to see if an object is within a certain distance range:
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; using RAIN.Representation; using RAIN.Motion; [RAINAction("Distance Check")] public class DistanceCheck : RAINAction { public Expression Target = new Expression(); public Expression GreaterThan = new Expression(); public Expression LessThan = new Expression(); public override ActionResult Execute(AI ai) { if (Target.IsValid && Target.IsVariable) { MoveLookTarget tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, Target.VariableName); float tDistance = (tTarget.Position - ai.Kinematic.Position).magnitude; if (GreaterThan.IsValid && (tDistance <= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; if (LessThan.IsValid && (tDistance >= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; } return ActionResult.SUCCESS; } }
You can use it in the behavior tree and set values for min distance, max distance, and the name of the variable that holds the player position/game object.
November 20, 2022 at 12:29 pm #34377Thanks for that, however I am running into other problems with it. Would there be a way to do that it a custom decision instead? I tried modifying that code to be used in a decision, however it keeps giving me failure. The reason for using a custom decision instead of action, is I want to tell the ai to play a different animation when it it close enough to the player and also run an action to damage the player.
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; using RAIN.Representation; using RAIN.Motion; [RAINDecision] public class CheckDistance : RAINDecision { public Expression Target = new Expression(); public Expression GreaterThan = new Expression(); public Expression LessThan = new Expression(); public override ActionResult Execute(AI ai) { if (Target.IsValid && Target.IsVariable) { MoveLookTarget tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, Target.VariableName); float tDistance = (tTarget.Position - ai.Kinematic.Position).magnitude; if (GreaterThan.IsValid && (tDistance <= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; if (LessThan.IsValid && (tDistance >= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; } return ActionResult.SUCCESS; } }
November 20, 2022 at 4:18 pm #34382Hmm. Here’s a custom decision that will only run if the target is at a certain distance. If the test passes, it acts like a sequencer:
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; using RAIN.Representation; using RAIN.Motion; [RAINDecision("Do When Distance")] public class DoWhenDistance : RAINDecision { private int _lastRunning = 0; public Expression Target = new Expression(); public Expression GreaterThan = new Expression(); public Expression LessThan = new Expression(); public override void Start(RAIN.Core.AI ai) { base.Start(ai); _lastRunning = 0; } public override ActionResult Execute(RAIN.Core.AI ai) { ActionResult tResult = ActionResult.SUCCESS; if (Target.IsValid && Target.IsVariable) { MoveLookTarget tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, Target.VariableName); float tDistance = (tTarget.Position - ai.Kinematic.Position).magnitude; if (GreaterThan.IsValid && (tDistance <= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; if (LessThan.IsValid && (tDistance >= GreaterThan.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory))) return ActionResult.FAILURE; } for (; _lastRunning < _children.Count; _lastRunning++) { tResult = _children[_lastRunning].Run(ai); if (tResult != ActionResult.SUCCESS) break; } return tResult; } }
November 20, 2022 at 4:19 pm #34383Keep in mind that you may want to do something totally different and straightforward. You could just decide to evaluate the distance to the target and set it as a variable in AI memory. Then use regular BT structures (like Constraint nodes or Evaluate Expression nodes) to make decisions.
-
AuthorPosts
You must be logged in to reply to this topic.