• 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 DMCH · Feb 28, 2013 at 03:10 PM · 2dturretaccuracy

How to get turrets to lead enemies : Topdown 2d

Hello,

Thanks for reading. I'm Having some difficulty figuring out the code to have turrets lead their targets. My old code just had the turrets tracking the enemies, so when they fired, they were less likely to hit fast moving enemies.

What I'm stuck on at the minute is figuring out what direction the target is moving, and how fast. (Line 10 of first code block)

Here's what I've got so far

 // Get the distance to the enemy
 float distanceToEnemy = Vector3.Distance(targetPosition, transform.position);
 Debug.Log ("TurretGunScript.RotateTurret: Distance to enemy : " + distanceToEnemy);
         
 // Get the amount of time it will take for bullet to hit enemy
 float timeToHit = distanceToEnemy/bulletSpeed;
 Debug.Log ("TurretGunScript.RotateTurret: Bullet travel time : " + timeToHit);
         
 // Get the movement vector of enemy ??
         
 // Multiply movement vector by time to hit to get the direction the turret should be facing
         
 // Rotate turret to face that position
 Quaternion neededRotation = Quaternion.LookRotation(direction);
 transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);


This is how the targets move:

 rigidbody.AddForce (targetDirection.normalized * moveSpeed * Time.deltaTime);
 transform.position = new Vector3(transform.position.x, 0, transform.position.z);

This is how bullets move:

 transform.Translate(0, 0, moveSpeed * Time.deltaTime);
 transform.position = new Vector3(transform.position.x, 0 , transform.position.z);

Thanks in advance!

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
Best Answer

Answer by Owen-Reynolds · Feb 28, 2013 at 04:57 PM

Basic idea is to see what direction/speed the target is moving, guess how many seconds it will take to hit, then use seconds*movement to estimate where the target will be:

 float secsFlightTime = (target.position - turret.position).magnitude / bulletSpeed;
 Vector3 targetMvPerSec = target.rigidbody.velocity; // since you physics to move
 targetMovePerSec.y=0; // since your code says they stay flat
 Vector3 estHitPos = target.position + targetMovePerSec*secsFlightTime;

The math will be wrong for two reasons. One is you can't know the actual flight seconds to where you'll hit without already knowing where you'll hit. So you just estimate based on current position. For faraway slow things, it works great. Otherwise, looping 2 or 3 times gets you really close (use estHitPos to re-figure flightTime and get a new estHitPos... .)

The other is your objects are constantly accelerating (AddForce.) If friction or something causes them to have a mostly constant speed, it should be OK.

Comment
Add comment · Show 3 · 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 DMCH · Feb 28, 2013 at 05:44 PM 0
Share

Thanks Owen. The code works well. I managed to figure out a cludge solution, but had to multiply a variable by 1.5 to get the correct lead amount. I wouldn't $$anonymous$$d trying to understand why, so if you feel like looking at it, please let me know : ) Thanks again!

This is the value I had to multiply:

 Vector3 targetVelocity = (target.rigidbody.velocity * timeToHit) * 1.5f; // This compensates for some descrepancy, presumably in bulletSpeed

This is the complete code:

         // Get the distance to the enemy
         float distanceToEnemy = Vector3.Distance(targetPosition, transform.position);
         Debug.Log ("TurretGunScript.RotateTurret: Distance to enemy : " + distanceToEnemy);
         
         // Get the amount of time it will take for bullet to hit enemy
         float timeToHit = distanceToEnemy/bulletSpeed;
         Debug.Log ("TurretGunScript.RotateTurret: Bullet travel time : " + timeToHit);
         
         // Get the velocity of the target rigidbody and multiply by amount of time to hit
         Vector3 targetVelocity = (target.rigidbody.velocity * timeToHit) * 1.5f; // This compensates for some descrepancy, presumably in bulletSpeed
         
         // Add the velocity * time to the target's curret position
         Vector3 finalPos = targetPosition + targetVelocity;
         
         // Get the direction to aim the turret
         Vector3 aimDirection = finalPos - bulletSpawn0.transform.position;
         
         // Rotate turret to face that position
         Quaternion neededRotation = Quaternion.LookRotation(aimDirection);
         transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);


avatar image Owen-Reynolds · Feb 28, 2013 at 06:07 PM 1
Share

The target's velocity is probably bobbing up and down each frame (AddForce, then friction or drag in the physics step.) Your code is probably running 1st, before the AddForce script, getting a "too low" velocity (but running after might give a "too high.")

For real, the velocity is currentPos-pos1SecondAgo. But that's a pain to remember. If you're a space rock, rigidbody.velocity is your real speed. Otherwise it's just an estimate (this trick fires way to high if someone has just jumped.)

avatar image DMCH · Feb 28, 2013 at 07:33 PM 0
Share

Thanks, Owen!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

10 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

Related Questions

Assets/Scripts/PlayerController.cs(32,49): error CS0126: An object of a type convertible to `float' is required for the return statement 1 Answer

World space to pixel space accuracy 1 Answer

ScreenToWorldPoint not accurate 0 Answers

2D Animation does not start 1 Answer

flip scale of a tank but turret aim wrong 0 Answers


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