Using custom A* movement script within Behavior Designer

ARSailor

New member
Hello!

I'm trying to use a custom A* movement script with Behavior designer.

I've turned the entire movement script into an action, the script produces no errors in Play, and looking at the behavior tree it shows success's throughout, but my enemy does not move at all nor to my player.

The target player function does work, or at least it shows the variable selecting my player's collider.

I am sure I'm missing something elegantly simplistic but am finding myself at my wits end after looking through the various documents/other forum posts on such a subject. Have I just gone completely wrong with the below script?


C#:
using UnityEngine;
using Pathfinding;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;

public class NonPlayerPhysicsMovement : Action
{
    [SerializeField] [Range(0, 5000000)] private float sailForce = 100000f;
    [SerializeField] private float maxAngularVelocity = 0.50f;
    [SerializeField] private float yAxisP, yAxisI, yAxisD;

    private PID yAxisPIDController;

    private Rigidbody rb;

    public SharedGameObject target;
    //public Transform targetPosition = null;
    private Seeker seeker;
    public Path path;
    public float nextWaypointDistance = 20;
    private int currentWaypoint = 0;
    public bool reachedEndOfPath;
    
    public void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
        rb.maxAngularVelocity = maxAngularVelocity;

        yAxisPIDController = new PID(yAxisP, yAxisI, yAxisD);

        seeker = gameObject.GetComponent<Seeker>();
        seeker.StartPath(transform.position, target.Value.transform.position, OnPathComplete);
        //InvokeRepeating("UpdatePath", 0f, .5f);
    }

    public void OnPathComplete(Path p)
    {
        // Debug.Log("A path was calculated. Did it fail with an error? " + p.error);
        if (!p.error)
        {
            path = p;
            currentWaypoint = 0;
        }
    }

    void UpdatePath()
    {
        if (seeker.IsDone())
        {
            seeker.StartPath(rb.position, target.Value.transform.position, OnPathComplete);
        }
    }

    public void Update()
    {
        yAxisPIDController.Kp = yAxisP;
        yAxisPIDController.Ki = yAxisI;
        yAxisPIDController.Kd = yAxisD;
    }

    void FixedUpdate()
    {
        UpdatePath();
        if (path == null)
        {
            return;
        }
        if (currentWaypoint >= path.vectorPath.Count)
        {
            reachedEndOfPath = true;
            return;
        } else
        {
            reachedEndOfPath = false;
        }
        reachedEndOfPath = false;
        float distanceToWaypoint;

        while (true)
        {
            distanceToWaypoint = Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]);
            if (distanceToWaypoint < nextWaypointDistance)
            {
                if (currentWaypoint + 1 < path.vectorPath.Count)
                {
                    currentWaypoint++;
                } else
                {
                    reachedEndOfPath = true;
                    break;
                }
            } else
            {
                break;
            }
        }


        var targetDirection = (path.vectorPath[currentWaypoint] - transform.position).normalized;
        Vector3 rotationDirection = Vector3.RotateTowards(transform.forward, targetDirection, 360, 0.00f);
        Quaternion targetRotation = Quaternion.LookRotation(rotationDirection);


        float yAngleError = Mathf.DeltaAngle(transform.rotation.eulerAngles.y, targetRotation.eulerAngles.y);
        float yTorqueCorrection = yAxisPIDController.GetOutput(yAngleError, Time.fixedDeltaTime);
        // Debug.Log(yAngleError + "," + yTorqueCorrection);

        rb.AddRelativeTorque((yTorqueCorrection * Vector3.up));
        rb.AddRelativeForce((Vector3.forward) * sailForce); /// * Time.fixedDeltaTime
    }
}
 
Hello again.

To state the somewhat obvious, that attempted conversion of my MonoBehavior custom A* movement script into a Behavior Designer task, was laughably incorrect and also an unnecessary step. In the end the custom Movement script simply needed to receive the shared variable(s), in this case the chosen GameObject to be chased, the Player.

The solution was to make a custom variable assigning/setting Action Task, to reference said custom movement script and apply the appropriate target and resulting Transform. That particular task will follow after the Can See Object finds the player, therefore setting the "SharedGameObject" variable for the tree, and this setter Action Task can now speak to the custom movement script.

One key point is that the custom movement script is disabled initially on the enemy GameObject, otherwise it will not work and throw null reference errors (due to my super basic movement script, again not suggested as any example to use).

Leaving this here and setting to resolved.

Code:
using UnityEngine;
using Pathfinding;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;

public class SetTargetMovementTask : Action
{
    public SharedGameObject target;

    AstarAI customMove;

    public override void OnAwake()
    {
        customMove = GetComponent<AstarAI>();
        
    }

    public override void OnStart()
    {
        customMove.m_target = target.Value;
        customMove.targetPosition = target.Value.transform;
        customMove.enabled = true;
    }
}
 
Top