Local Space AI Path, LocalSpaceRichAI equivalent for 2D

@aron_granberg I have implemented the above as described to try to get AIPath working on a rotating spherical world (see post: Falling through spherical world sometimes and navmesh rotation) and it’s mostly working. There are a couple of issues:

  1. The AI’s jerk every time the path is recalculated.
  2. To get this to work I made copies of the following scripts (and renamed them) in the project so that I could modify them (because they are now in the package manager):

AIPath -> AIPathPapaJ
PathInterpolateor -> PathInterpolateorPapaJ
AIPathAlignedToSurface -> AIPathAlignedToSurfacePapaJ

The problem I am having is that the renamed named scripts are crashing the inspector:

ArgumentException: acceleration
Pathfinding.EditorBase.FindProperty (System.String name) (at Library/PackageCache/com.arongranberg.astar@4.3.33/PackageTools/Editor/EditorBase.cs:124)
Pathfinding.EditorBase.PropertyField (System.String propertyPath, System.String label, System.String tooltip) (at Library/PackageCache/com.arongranberg.astar@4.3.33/PackageTools/Editor/EditorBase.cs:144)
Pathfinding.EditorBase.FloatField (System.String propertyPath, System.String label, System.String tooltip, System.Single min, System.Single max) (at Library/PackageCache/com.arongranberg.astar@4.3.33/PackageTools/Editor/EditorBase.cs:134)
Pathfinding.BaseAIEditor.Inspector () (at Library/PackageCache/com.arongranberg.astar@4.3.33/Editor/AIBaseEditor.cs:84)
Pathfinding.EditorBase.OnInspectorGUI () (at Library/PackageCache/com.arongranberg.astar@4.3.33/PackageTools/Editor/EditorBase.cs:94)
UnityEngine.Debug:LogException(Exception, Object)
Pathfinding.EditorBase:OnInspectorGUI() (at Library/PackageCache/com.arongranberg.astar@4.3.33/PackageTools/Editor/EditorBase.cs:96)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

Here is what I have going on is my script:

using UnityEngine;
using System.Collections.Generic;

namespace Pathfinding
{
    /// <summary>
    /// Movement script for curved worlds.
    /// This script inherits from AIPath, but adjusts its movement plane every frame using the ground normal.
    /// </summary>
    [HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_a_i_path_aligned_to_surface.php")]
    public class AIPathAlignedToSurfacePapaJ : AIPathPapaJ
    {

        /// <summary>Root of the object we are moving on</summary>
        public LocalSpaceGraph graph;

        protected override void Start()
        {
            GameObject go = GameObject.Find("Earth");
            if (go == null)
                return;
            graph = go.GetComponent<LocalSpaceGraph>();

            base.Start();
            movementPlane = new Util.SimpleMovementPlane(rotation);
        }

        protected override void OnUpdate(float dt)
        {
            base.OnUpdate(dt);
            UpdateMovementPlane();
        }

        protected override void ApplyGravity(float deltaTime)
        {
            // Apply gravity
            if (usingGravity)
            {
                // Gravity is relative to the current surface.
                // Only the normal direction is well defined however so x and z are ignored.
                verticalVelocity += float.IsNaN(gravity.x) ? Physics.gravity.y : gravity.y;
            }
            else
            {
                verticalVelocity = 0;
            }
        }

        protected override Vector3 ClampToNavmesh(Vector3 position, out bool positionChanged)
        {
            // This code clamps the AI to the sphere of radius 5.0f
            positionChanged = false;
            // Normalize position then scale to radius of sphere
            Vector3 newPosition = Vector3.Normalize(position) * 5.0f;
            if (newPosition != position) positionChanged = true; // not sure what this does
            //Debug.Log(position.ToString());
            return newPosition;
        }

        /// <summary>Find the world position of the ground below the character</summary>
        protected override void UpdateMovementPlane()
        {
            // Construct a new movement plane which has new normal
            // but is otherwise as similar to the previous plane as possible
            var normal = Vector3.Normalize(transform.position);

            var fwd = Vector3.Cross(movementPlane.rotation * Vector3.right, normal);

            if (fwd != Vector3.zero)
            {
                movementPlane = new Util.SimpleMovementPlane(Quaternion.LookRotation(fwd, normal));
                rvoController.movementPlane = movementPlane;
            }
            else
            {
                Debug.Log("APPathAlignedToSurfacePapaJ UpdateMovementPlane fwd Vector3.zero");
            }
        }
        void RefreshTransform()
        {
            graph.Refresh();
            interpolator.graphTransform = graph.transformation;
            movementPlane = graph.transformation.ToSimpleMovementPlane();
        }

        protected override void CalculatePathRequestEndpoints(out Vector3 start, out Vector3 end)
        {
            RefreshTransform();
            base.CalculatePathRequestEndpoints(out start, out end);
            start = graph.transformation.InverseTransform(start);
            end = graph.transformation.InverseTransform(end);
        }
    }
}

Any insight on where to look to fix the inspector would be helpful. I think I can figure out the jerking on my own.

Thanks,

Jacob

1 Like