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.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #34360

    jax
    Participant

    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.

    #34361

    prime
    Keymaster

    Here’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.

    #34377

    jax
    Participant

    Thanks 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;
        }
    }
    #34382

    prime
    Keymaster

    Hmm. 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;
        }
    }
    #34383

    prime
    Keymaster

    Keep 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.

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.