Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 ThePersister · Jun 01, 2015 at 01:42 PM · movementpositionenemyspeedprediction

Predict enemy position in X seconds?

Below you can see a method that tries to predict the enemy movement in X seconds, but it's not accurate enough, if you could find any messups in my code I'd really appreciate it!

Details:

  • The enemy walks across a path defined by A* Pathfinding.

  • I have every waypoint of that path in an array.

  • Comments explain what I'm doing in the method.

  • The enemy moves at a perfectly constant speed.

Possible downfalls:

  • I'm assuming that boundEnemy.Speed is a distance per second variable for this to work.

Actual Code:

     /// <summary>
     /// Calculates the position of this enemy in x amount of seconds and returns it.
     /// </summary>
     /// <param name="seconds">Amount of seconds we're predicting ahead.</param>
     /// <returns></returns>
     public Vector3 GetPositionIn(float seconds)
     {
         // Setup variables
         float distanceExpected = boundEnemy.Speed * seconds;
         int expectedTargetWaypoint = currentWaypoint;
         float distanceToCover = 0;
 
         while (true)
         {
             // if statement prevents the error when using expectedTargetWaypoint - 1.
             if (expectedTargetWaypoint == 0)
             {
                 // Distance from start to first waypoint
                 distanceToCover = Vector3.Distance(transform.position, path.vectorPath[expectedTargetWaypoint]);
             }
             else
             {
                 // Distance from current Waypoint to the Next
                 distanceToCover = Vector3.Distance(path.vectorPath[expectedTargetWaypoint - 1], path.vectorPath[expectedTargetWaypoint]);
             }
 
             // Will you make it to the next waypoint?
             if (distanceExpected - distanceToCover > 0)
             {
                 distanceExpected -= distanceToCover;
                 expectedTargetWaypoint++;
 
                 // Made it to the finish, return finish point.
                 if (expectedTargetWaypoint >= path.vectorPath.Count) 
                     return path.vectorPath[expectedTargetWaypoint -1];
             }
             else
             {
                 // return the position where we expect this enemy to be after xSeconds at this constant speed.
                 // if statement prevents the error when using expectedTargetWaypoint - 1.
                 if (expectedTargetWaypoint == 0)
                 {
                     // return a point between A and B depending on the percentage of its full distance we expect to cover.
                     return Vector3.Lerp(transform.position, path.vectorPath[expectedTargetWaypoint], distanceExpected / distanceToCover);
                 }
                 else
                 {
                     // return a point between A and B depending on the percentage of its full distance we expect to cover.
                     return Vector3.Lerp(path.vectorPath[expectedTargetWaypoint -1], path.vectorPath[expectedTargetWaypoint], distanceExpected / distanceToCover);
                 }
             }
         }
     }
Comment
Add comment · Show 2
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 tanoshimi · Jun 01, 2015 at 04:12 PM 0
Share

Your logic seems sound. What do you mean by "not accurate enough"? Can you provide examples of a simple set of waypoints, the enemy's current position, and the lookahead "seconds" value that you provide that does not give the answer you expect?

avatar image ThePersister · Jun 01, 2015 at 08:13 PM 0
Share

Sure, I'll get back on it tommorow morning, I've made a straight movement level so the data is more logical, and I'll implement some gizmos / debugging for us to get a better idea. :)

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by ThePersister · Jun 02, 2015 at 10:09 AM

I've solved it! See code at far bottom of this post :)

The logic was almost sound, but not close enough ;) Making a straight level, I noticed how every bullet my tower would shoot would land just beyond the waypoint the enemy had lastly passed.

Example A. Blue sphere = enemy. Red sphere = targetPos for bullet. Yellow sphere = bullet itself.

Somehow the picture did not show up correctly.

I ran through my code with some debugs, and then I realised that the current position of the enemy would not be taken into account if and only if the prediction hadn't reached the target waypoint or beyond, this line right here:

 return Vector3.Lerp(path.vectorPath[expectedTargetWaypoint -1], path.vectorPath[expectedTargetWaypoint], distanceExpected / distanceToCover);

Does not take the current position into account, which is no problem, as long as we have to look from the target waypoint and onward, but if we look at the last waypoint, say, waypoint 0, and the enemy has already passed that, then we should be calculating from where the enemy currently is, like from enemy to target with expected distance, instead of from A to B with expected distance, disregarding the enemy.

This fancy talk all rounds up in the code below, the debugs aren't necessary. Note new bool "isPredictingFurtherThanTargetWaypoint" and its usages.

     /// <summary>
     /// Calculates the position of this enemy in x amount of seconds and returns it.
     /// </summary>
     /// <param name="seconds">Amount of seconds we're predicting ahead.</param>
     /// <returns></returns>
     public Vector3 GetPositionIn(float seconds)
     {
         // Setup variables
         float distanceExpected = boundEnemy.Speed * seconds;
         int expectedTargetWaypoint = currentWaypoint;
         bool isPredictingFurtherThanTargetWaypoint = false;
         float distanceToCover = 0;
 
         while (true)
         {
             // if statement prevents the error when using expectedTargetWaypoint - 1.
             if (expectedTargetWaypoint == 0)
             {
                 // Distance from start to first waypoint
                 distanceToCover = Vector3.Distance(transform.position, path.vectorPath[expectedTargetWaypoint]);
             }
             else
             {
                 // Distance from current Waypoint to the Next
                 distanceToCover = Vector3.Distance(path.vectorPath[expectedTargetWaypoint - 1], path.vectorPath[expectedTargetWaypoint]);
             }
 
             // Will you make it to the next waypoint?
             if (distanceExpected - distanceToCover > 0)
             {
                 distanceExpected -= distanceToCover;
                 expectedTargetWaypoint++;
                 isPredictingFurtherThanTargetWaypoint = true;
 
                 // Made it to the finish, return finish point.
                 if (expectedTargetWaypoint >= path.vectorPath.Count)
                     return path.vectorPath[path.vectorPath.Count - 1];
             }
             else
             {
                 // return the position where we expect this enemy to be after xSeconds at this constant speed.
                 // if statement prevents the error when using expectedTargetWaypoint - 1.
                 if (!isPredictingFurtherThanTargetWaypoint)
                 {
                     Debug.Log("Distance Expected: " + distanceExpected + ", Distance to Cover: " + distanceToCover + ", result: " + (distanceExpected / distanceToCover));
 
                     // return a point between A and B depending on the percentage of its full distance we expect to cover.
                     return Vector3.Lerp(transform.position, path.vectorPath[expectedTargetWaypoint], distanceExpected / distanceToCover);
                 }
                 else
                 {
                     Debug.Log("Distance Expected: " + distanceExpected + ", Distance to Cover: " + distanceToCover + ", result: " + (distanceExpected / distanceToCover));
                     // return a point between A and B depending on the percentage of its full distance we expect to cover.
                     return Vector3.Lerp(path.vectorPath[expectedTargetWaypoint -1], path.vectorPath[expectedTargetWaypoint], distanceExpected / distanceToCover);
                 }
             }
         }
     }


Thank you for your interest in this post and the help you've given :) Some good old debugging and gizmos got the job done.

Gl with your own programming tasks, back to work! :)


straightissue.png (162.4 kB)
Comment
Add comment · 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

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

21 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

Related Questions

How to adjust speed of an object when it is moved by changing its position ??? 0 Answers

Enemy Approaching player and then stopping in front?? 1 Answer

Moving an Object to the vector of other objects on button press using a vector3 array? 0 Answers

How to Have Projectile Reset to Initial Position Relative to Parent 1 Answer

Enemy AI Movement Decision Making 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