Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by DevMerlin · Jan 03, 2019 at 10:13 AM · c#aipathfindingpathfollowing

How can I prevent a character from ignoring it's waypoint path?

I have a problem where my character is navigating via path generated from an A* map. That itself works fine, however every so often it seems like the character "trips", and ignores the path, continuing forward.

Due to the style of the game, the character is moving by jumping forward - think in a Frogger fashion, but under control of AI most times, and using it's own gravity system. I've tried multiple methods to eliminate this "trip", but so far haven't found anything that is actually sticking.

Additionally, what's frustrating is that 80% of the time, it works flawlessly. Then at a seemingly random 20%, it trips and just keeps going in it's current direction, eventually falling off the map. At this point, I can't tell what's wrong - I've re-written the script twice. The first version used a Finite State Machine. If anyone could spot the issue, I would be grateful.

 public class Character : MonoBehaviour {
 
     public GameObject[] CharacterList;
 
     private float lockHeight = 0;
 
     [SerializeField]
     private float gravity = 9.89f;
 
     public float jumpForce = 2f;
     public float forwardSpeed = 2f;
     public float distanceToTarget;
 
     public Vector3 activeWaypoint;
 
     public List<Node> waypointPath;
 
     private Vector3 moveDirection = Vector3.zero;
     private Transform transformCache;
     private Quaternion rotationPoint;
 
     // Rotation Points //
     private Vector3 rotateWest = new Vector3(0, 180, 0);
     private Vector3 rotateEast = new Vector3(0, 0, 0);
     private Vector3 rotateSouth = new Vector3(0, 90, 0);
     private Vector3 rotateNorth = new Vector3(0, 270, 0);
     public Vector3 directionToTarget = Vector3.zero;
 
     public towardsDirection facingDirection = towardsDirection.South;
 
     public towardsDirection FacingDirection
     {
         get
         {
             return facingDirection;
         }
         set
         {
             facingDirection = value;
             changeFacingDirection();
         }
     }
 
     public bool underPlayerControl = false;
     public bool isReady = false;
     public bool characterActive = false;
     public bool isPathRandom = true;
     public bool onContact = false;
     public bool hitTarget = false;
     public bool canMove = false;
     public bool isMoving = false;
     
     public bool isThinking = false;
 
     [SerializeField]
     Vector3 heading = Vector3.zero;
     [SerializeField]
     float distance = 0;
     [SerializeField]
     Vector3 direction = Vector3.zero;
 
     [SerializeField]
     Vector3 lastDirection = Vector3.zero;
     
     // Use this for initialization
     void Start ()
     {
         rotationPoint = Quaternion.identity;
         transformCache = GetComponent<Transform>();
     }
 
     public void Init(bool upc = false, int rezSpecies = 0)
     {
         underPlayerControl = upc;
         changeCharacter(rezSpecies);
         isReady = true;
     }
 
 
     public void changeCharacter(int species = 0)
     {
         foreach(GameObject got in CharacterList)
         {
             if (got.activeSelf)
             {
                 got.SetActive(false);
             }
         }
 
         CharacterList[species].SetActive(true);
     }
 
     public void readyCharacter()
     {
         characterActive = true;
         compareNeeds();
     }
 
     private void compareNeeds()
     {
         isThinking = true;
         canMove = false;
         Vector3 targetPoint = Vector3.zero;
 
         // Is at end of path? 
 
         if (waypointPath != null)
         {
             if (waypointPath.Count == 0)
             {
                 if (isPathRandom)
                 {
                     getRandomPath();
                 }
             } else {
                 moveToNextWaypoint();
             }
         }
         else
         {
             if (isPathRandom)
             {
                 getRandomPath();
             } else {
 
             }
         }
     }
 
     public void getRandomPath()
     {
         Vector3 randomPosition = GridObject.Instance.returnRandomTarget();
         PathRequestManager.RequestPath(transform.position, randomPosition, onPathFound);
     }
 
     public void getPath(Vector3 startPosition, Vector3 endPosition)
     {
         PathRequestManager.RequestPath(startPosition, endPosition, onPathFound);
     }
 
     public void onPathFound(List<Node> path, bool success)
     {
         waypointPath = path;
         moveToNextWaypoint();
     }
 
     private void moveToNextWaypoint()
     {
         activeWaypoint = waypointPath.PopAt(0).worldPosition;
         turnToNextWaypoint();
     }
     
     private void Update()
     {
         if (isReady)
         {
             distanceToTarget = Vector3.Distance(transform.position, activeWaypoint);
 
             if (distanceToTarget <= 1.5f)
             {
                 if (!isThinking)
                 {
                     compareNeeds();
                 }
             }
 
             if (canMove)
             {
                 jumpForward();
             }
 
             moveEngine();
         }
     }
     
     private void moveEngine()
     {
         RaycastHit rayHit;
         Ray raycast = new Ray(transformCache.position, Vector3.down);
 
         if (Physics.Raycast(raycast, out rayHit, 0.2f))
         {
             if (rayHit.transform.tag == "Solid")
             {
                 Vector3 hit = rayHit.point;
                 lockHeight = hit.y;
             }
         }
 
         if (onContact)
         {
             if (!isMoving)
             {
                 moveDirection = Vector3.zero;
             }
         }
         else
         {
             moveDirection.y -= gravity * Time.deltaTime;
         }
 
         transformCache.Translate(moveDirection * Time.deltaTime);
     }
 
     private void LateUpdate()
     {
         Vector3 lockPosition = transformCache.position;
         if (transformCache.position.y <= lockHeight)
         {
             lockPosition.y = lockHeight;
             onContact = true;
             isMoving = false;
         } else {
             lockHeight = -100;
             onContact = false;
         }
 
         transformCache.position = lockPosition;
     }
 
     public void turnToNextWaypoint()
     {
         heading = transform.position - activeWaypoint;
         distance = heading.magnitude;
         directionToTarget = heading / distance;
 
         if (directionToTarget.x > 0.4f)
         {
             FacingDirection = towardsDirection.West;
         } else if (directionToTarget.x < -0.4f)
         {
             FacingDirection = towardsDirection.East;
         }
 
         if (directionToTarget.z > 0.4f)
         {
             FacingDirection = towardsDirection.South;
         } else if (directionToTarget.z < -0.4f)
         {
             FacingDirection = towardsDirection.North;
         }
 
         canMove = true;
         isThinking = false;
     }
 
     public void changeFacingDirection()
     {
         if (transformCache)
         {
             switch (facingDirection)
             {
                 case towardsDirection.North:
                     rotationPoint.eulerAngles = rotateNorth;
                     transformCache.rotation = rotationPoint;
                     break;
                 case towardsDirection.South:
                     rotationPoint.eulerAngles = rotateSouth;
                     transformCache.rotation = rotationPoint;
                     break;
                 case towardsDirection.East:
                     rotationPoint.eulerAngles = rotateEast;
                     transformCache.rotation = rotationPoint;
                     break;
                 case towardsDirection.West:
                     rotationPoint.eulerAngles = rotateWest;
                     transformCache.rotation = rotationPoint;
                     break;
             }
         }
     }
 
     public void jumpForward()
     {
         if (onContact)
         {
             isMoving = true;
             moveDirection.y = jumpForce;
             moveDirection.x = forwardSpeed;
         }
     }
   
     private void OnDrawGizmos()
     {
         if (activeWaypoint != Vector3.zero)
         {
             Gizmos.color = Color.black;
             Gizmos.DrawWireSphere(activeWaypoint, 0.4f);
         }
 
         if (waypointPath != null)
         {
             foreach(Node n in waypointPath)
             {
                 Gizmos.color = Color.red;
                 Gizmos.DrawWireSphere(n.worldPosition, 0.4f);
             }
 
         }
     }
    
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Nocktion · Jan 03, 2019 at 11:21 AM

Try decreasing the direction threshold. I mean you check every direction with a threshold of 0.4f but what if the direction to the target is 0.399f? In this case the character won't turn in the right direction.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DevMerlin · Jan 03, 2019 at 01:39 PM 0
Share

No dice. I set it down to 0.2f and changed the distance test threshold to 0.60f. It's still showing the same behavior. That's what's been baffling about the stumble here. It happens at see$$anonymous$$gly random.

One thing I'd like to do is potentially keep the character constrained to the map area, and have it stop if it runs up against the 'wall' of the edge. This usually won't be visible to the player, and if it is, a forward ray cast will stop it going through solid objects.

avatar image DevMerlin · Jan 03, 2019 at 02:34 PM 0
Share

I may have to redesign it so that the movement is not based on direction, and the character is treated more like a sprite with the movement 'faked'. All movement is technically - and should be - grid based, anyway, even if the grid is dynamic.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

597 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Make player follow a waypoint path but still be able to control player movement 1 Answer

Boids/Flocking Tutorial 0 Answers

Set AI Destination Setter target from Script 2 Answers

How to get an AI enemy character to stop moving and freeze animation when the FPS camera is looking at it? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges