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
1
Question by DayyanSisson · Dec 29, 2011 at 02:03 AM · guishootingcrosshairtargetingflight

Crosshair Targeting System

I'm making a space sim, and I need a targeting cursor in front of an enemy so the player can aim. Since when you fire a bullet, you need to fire ahead so the bullet actually hits it's target. It's hard at the moment to judge where to shoot based off your speed, the bullet's speed, and your distance from the target. So essentially there would be a little crosshair in front of the target where the player needs to shoot in order to hit it. Here's an example (What I'm talking about doesn't actually start till 2:35). I know I need to do some math to calculate where to place the GUI crosshair based off that target's distance, the target's speed, your speed, and the bullet's speed. I just don't know where to start. Any help would be appreciated.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by aldonaletto · Dec 30, 2011 at 03:04 AM

Actually, that game doesn't seem to do that - it seems to just draw a crosshair at some distance in the airplane's forward direction.
But if you want to find the position where to shoot taking into account the target velocity, there exists a "mathmagic" to do that: the function HitTime below calculates the time needed to a projectile with velocity speed to reach the target targ moving at velocity vel (if the target is moving away too fast to be reached, the function returns -1). Once the time is calculated, you can find the position to shoot using the target velocity, draw the crosshair and shoot in its direction.
In most cases you don't know the target velocity, but you can calculate it from the target positions over time. The calculated velocity is somewhat jerky, thus you must filter it in order to have a smooth behaviour - but this also makes the aim unreliable until the calculated velocity reaches a stable value.
You must fire the projectile by setting its rigidbody.velocity to bulletSpeed * direction.normalized (forget about AddForce - you will never get the correct speed).

// targ is the target transform, vel is its velocity vector, // and speed is the projectile speed. Returns the time needed // to reach the target, or -1 if it's not possible

function HitTime(targ: Transform, vel: Vector3, speed: float): float { var dist = targ.position - transform.position; var a = Vector3.Dot(vel, vel) - speed speed; var b = 2 Vector3.Dot(vel, dist); var c = Vector3.Dot(dist, dist); var det = b b - 4 a c; if (det >= 0) return 2 c / (Mathf.Sqrt(det) - b); else return -1; }

// that's an example code to test this function:

var guiCross: GUITexture; // drag the GUITexture crosshair here var target: Transform; // target transform var bulletSpeed: float = 10; // projectile speed

private var targetVel: Vector3; private var lastPos: Vector3;

function Update(){ if (target){ // if some target locked... // if you don't know the target velocity, calculate it var vel = (target.position - lastPos)/Time.deltaTime; lastPos = target.position; // filter the velocity to avoid a shaking crosshair targetVel = Vector3.Lerp(targetVel, vel, Time.deltaTime);

 // calculate the hit position:
 var t = HitTime(target, targetVel, bulletSpeed);
 if (t < 0){
   // target moving away too fast to be reached
   guiCross.enabled = false;
 } else {
   // target may be hit:
   guiCross.enabled = true;
   // calculate the position where the target will be hit
   var hitPos = target.position + t * targetVel;
   // calculate the crosshair position
   var crossPos = Camera.main.WorldToViewportPoint(hitPos);
   guiCross.transform.position = crossPos;
 }
 
 if (Input.GetButtonDown("Fire1")){
   var missile = GameObject.CreatePrimitive(PrimitiveType.Sphere);
   Destroy(missile, 20); // kill the missile after 20s
   missile.AddComponent(Rigidbody);
   missile.rigidbody.position = transform.position;
   missile.rigidbody.useGravity = false;
   
   // use this to shoot at the calculated point:
   var dir = hitPos - transform.position;
   missile.rigidbody.velocity = dir.normalized * bulletSpeed;
 }

} } CREDITS: I based the HitTime function in an interesting article about this subject, *Leading a target*.

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
avatar image
0

Answer by asafsitner · Dec 29, 2011 at 11:01 AM

Start with `Camera.WorldToScreenPoint();` Calculate the necessary targeting crosshair's position in 3D, then use the WorldToScreenPoint method to transfer it's position to a point on the screen.

How to calculate the crosshair's position, though?

Algorithm should be something like:

  1. Determine projectile's travel time from weapon position to enemy position through division of distance by speed and then again by average FPS

  2. Predict enemy's position by calculating it's position in the next frame, multiplied by the projectile's travel time (to predict rotation have a look at this answer - it's working great)

  3. Call Camera.WorldToScreenPoint(predictedPosition);

  4. Draw the crosshair through GUI

Comment
Add comment · Show 5 · 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 DayyanSisson · Dec 29, 2011 at 10:58 PM 0
Share

"Average FPS" being average frames-per-second or average feet-per-second (speed of bullet)? And also, how would I predict it's location in the next frame? Current location * speed / FPS?

avatar image DayyanSisson · Dec 29, 2011 at 11:47 PM 0
Share

And as for drawing the texture, how do I put it's position based off the predicted position, because I tried this :

 GUI.DrawTexture(new Rect(cursorScreenLocation), bulletTargetingCrosshair, Scale$$anonymous$$ode.ScaleToFit, true, 10.0F);

And this :

 GUI.DrawTexture(cursorScreenLocation, bulletTargetingCrosshair, Scale$$anonymous$$ode.ScaleToFit, true, 10.0F);

But I got errors both times.

avatar image JPB18 · Dec 30, 2011 at 01:20 AM 0
Share

Well, nighthawx349, you could use Pythagoras Theorem on that one. You would need the measure the distance between you and the target object, then calculate the travel time of the projectile, then multiply that value with the velocity of the target and there you would have the distance where you would need to place the "crosshair"... Something like this:

var TargetSpeed; var ProjSpeed; var TargetDist; var CrossDist;

CrossDist = (TargetDist/ProjSpeed) * TargetSpeed;

Hope I've helped =)

avatar image DayyanSisson · Dec 30, 2011 at 02:27 AM 0
Share

Well this is what I have here :

 //Component Check
         Combat other = plane.GetComponent<Combat>();
         PaperPlaneAI planeAI = target.GetComponent<PaperPlaneAI>();
         
         //Variable Check
         target = other.targetHit;
         targetSpeed = planeAI.speed;
         targetDistance = Vector3.Distance(target.transform.position, plane.position);
         Vector3 fwd = target.TransformDirection(Vector3.forward);
         
         //Next Steps
         bulletTravelTime = targetDistance/bulletVelocity;
         targetsNextLoc = fwd * targetSpeed/70;
         
         //Final Step
         cursorLocation = bulletTravelTime * targetsNextLoc;
         cursorScreenLocation = camera.WorldToScreenPoint(cursorLocation);
avatar image asafsitner · Dec 30, 2011 at 06:25 AM 0
Share

Average FPS as is Frames Per Second, as you're calculating positions from one frame to the next. It's basically Pythagoras's theorem, but the tricky part is predicting enemy's position. Luckily, a prediction solution already exists for networking lag compensation which you can probably dig and reuse (basically in both cases you're trying to extrapolate the Transform's movement).

A better example of what you're trying to achieve can be found in Black Prophecy

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

7 People are following this question.

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

Related Questions

Crosshair is not sticking with target position 0 Answers

Flight HUD - flight angles 0 Answers

Dealing with multiple crosshairs 0 Answers

Simple GUI In game 1 Answer

How do I go about using Hit.Test? 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