• 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 Li0nSword · Feb 26, 2014 at 03:22 PM · unity4.3

How can I make a missile home to an enemy in arc fashion? (Unity 4.3 2D)

I am building a 2D game and i've managed to make homing missiles with the following code:

Vector2 destination = player.transform.position - transform.position; lastPos = destination; float angle = Mathf.Atan2(destination.y, destination.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

destination.Normalize (); transform.position += new Vector3 (destination.x, destination.y, 0) speed Time.deltaTime;

I've made it so that the rocket simply travels in a straight line towards the player. Can anyone guide me in the right direction to make the rocket travel in an arc towards the player instead of a straight line.

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 robertbu · Feb 26, 2014 at 04:30 PM 0
Share
avatar image Li0nSword · Feb 26, 2014 at 05:52 PM 0
Share

5 Replies

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

Answer by Hamdullahshah · Feb 26, 2014 at 04:34 PM

Use a bezier curve of two point

     private Vector3 CalculateBezierPoint (float t, Vector3 startPosition, Vector3 endPosition, Vector3 controlPoint) {
         float u = 1 - t;
         float uu = u * u;
 
         Vector3 point = uu * startPosition;
         point += 2 * u * t * controlPoint;
         point += t * t * endPosition;
 
         return point;
     }

Call it from update somet$$anonymous$$ng like

 t$$anonymous$$s.transform.position = CalculateBezierPoint(currentDuration/duration,startPos,endPos,cp);
 
 currentDuration += Time.deltaTime;

where "duration" is total time.

More info on wikipedia for bezier curves: http://en.wikipedia.org/wiki/File:Bezier_2_big.gif

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 Li0nSword · Feb 26, 2014 at 06:56 PM 0
Share
avatar image kendyb · Jan 08, 2015 at 03:10 PM 1
Share
avatar image
0

Answer by poncho · Feb 26, 2014 at 04:35 PM

I suggest, using iTween, where you set your waypoints, the easiest way to define t$$anonymous$$s waypoints instead of using a formula, just add 4, the first, your origin, second and t$$anonymous$$rd, at 1 t$$anonymous$$rd between origin and destiny but with the y above them depending on how your desired arc is, and the fourth your destiny, itween WILL interpolate the movements, after defining that you could play a little with the type of movement, as linear, cuadratic, spring, etc, the code for i tween is somet$$anonymous$$ng like t$$anonymous$$s

 public Transform[] waypoints;
 public float m_speed = 1.0f;
 public GameObject player1;
 private int i = 0;
 private bool moving = false;
  
 public void Update() {
 if (!moving && i < waypoints.Length - 1) {
 i++;
 moving = true;
 iTween.MoveTo(player1,iTween.Hash("position",waypoints[i],"speed",m_speed,"easetype","linear", "oncompletetarget",gameObject, "oncomplete", "Done"));
 }
  
 }
  
 public void Done() {
 moving = false;
 }

  
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 robertbu · Feb 26, 2014 at 05:02 PM

And another solution to add to the mix. Use the Sin() function to calculate a loft for the missile over the distance traveled. Take the script below and attach to a sphere in the scene. Click the mouse to shoot the sphere to that position:

 #pragma strict
  
 var traveling = false;
 
 function Update() {
     if (!traveling && Input.GetMouseButtonDown(0)) {
         var pos = Input.mousePosition;
         pos.z = 10.0;
         pos = Camera.main.ScreenToWorldPoint(pos);
         ArcToTarget(pos, 0.35, 1.0);
     }
  } 
  
 function ArcToTarget(targetPos : Vector3, arcFraction : float, time : float) {
     traveling = true;
     var startPos = transform.position;
     var timer = 0.0;
     var arcDist = (targetPos - startPos).magnitude * arcFraction;
     
     w$$anonymous$$le (timer < time) {
         var pos = Vector3.Lerp(startPos, targetPos, timer / time);
         pos.y += Mathf.Sin(Mathf.PI * timer / time) * arcDist;
         transform.position =  pos;
         timer += Time.deltaTime;
         yield;
     }
     transform.position = targetPos;
     traveling = false;
 }
Comment
Add comment · Show 1 · 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 Li0nSword · Feb 26, 2014 at 06:58 PM 0
Share
avatar image
0

Answer by Thorizo · Oct 03, 2018 at 09:26 PM

Let's assume we have 3 points: A (start), B (middle) and C (end). We linearly interpolate over time between A and B, as well as B and C. Meanw$$anonymous$$le, we interpolate between the result of the two. The code presented below should work perfectly. Simply call QuadraticCurve in the Update() method. Subsequently, increment the time as we want to go from 0 to 1: time += Time.deltaTime;

 private Vector3 LinearInterpolate(Vector3 start, Vector3 end, float time)
 {
     return start + (end - start) * time;
 }
 
 private Vector3 QuadraticCurve(Vector3 start, Vector3 middle, Vector3 end, float time)
 {
     Vector3 line1 = LinearInterpolate(start, middle, time);
     Vector3 line2 = LinearInterpolate(middle, end, time);
     return LinearInterpolate(line1, line2, time);
 }
 private void Update()
 {
     transform.position = QuadraticCurve(startPoint, middlePoint, endPoint, 
     duration);
     durtation += Time.deltaTime;
 }

Comment
Add comment · Show 1 · 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 Bunny83 · Oct 04, 2018 at 01:26 AM 0
Share
avatar image
0

Answer by terresquall · Feb 10, 2020 at 05:42 AM

You can use a sine curve for that. Attach the script below to your projectile, and use Projectile.Spawn() to spawn a projectile that will home in on its target. You can set arcFactor to adjust the height and speed to adjust how fast it travels. For an explanation of the math involved, you can look at t$$anonymous$$s article where the script was taken from: https://blog.terresquall.com/2019/11/coding-projectiles-for-your-tower-defense-game-part-2/

 public class Projectile : MonoBehaviour {
     public float speed = 8.5f; // Speed of projectile.
     public float radius = 1f; // Collision radius.
     float radiusSq; // Radius squared; optimisation.
     Transform target; // Who we are homing at.
 
     Vector3 currentPosition; // Store the current position we are at.
     float distanceTravelled; // Record the distance travelled.
 
     public float arcFactor = 0.5f; // Higher number means bigger arc.
     Vector3 origin; // To store where the projectile first spawned.
 
     void OnEnable() {
         // Pre-compute the value. 
         radiusSq = radius * radius;
         origin = currentPosition = transform.position;
     }
     
     void Update() {
         // If there is no target, destroy itself and end execution.
         if ( !target ) {
             Destroy(gameObject);
             // Write your own code to spawn an explosion / splat effect.
             return; // Stops executing t$$anonymous$$s function.
         }
 
         // Move ourselves towards the target at every frame.
         Vector3 direction = target.position - currentPosition;
         currentPosition += direction.normalized * speed * Time.deltaTime;
         distanceTravelled += speed * Time.deltaTime; // Record the distance we are travelling.
 
         // Set our position to <currentPosition>, and add a height offset to it.
         float totalDistance = Vector3.Distance(origin, target.position);
         float heightOffset = arcFactor * totalDistance * Mathf.Sin( distanceTravelled * Mathf.PI / totalDistance );
         transform.position = currentPosition + new Vector3( 0, 0, heightOffset );
 
         // Destroy the projectile if it is close to the target.
         if ( direction.sqrMagnitude < radiusSq ) {
             Destroy(gameObject);
             // Write your own code to spawn an explosion / splat effect.
             // Write your own code to deal damage to the .
         }  
     }
 
     // So that other scripts can use Projectile.Spawn to spawn a projectile.
     public static Projectile Spawn(GameObject prefab, Vector3 position, Quaternion rotation, Transform target) {
         // Spawn a GameObject based on a prefab, and returns its Projectile component.
         GameObject go = Instantiate(prefab, position, rotation);
         Projectile p = go.GetComponent<Projectile>();
 
         // Rightfully, we should throw an error here instead of fixing the error for the user. 
         if(!p) p = go.AddComponent<Projectile>();
 
         // Set the projectile's target, so that it can work.
         p.target = target;
         return p; 
     }
 }
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.

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

24 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

Related Questions

A node in a childnode? 1 Answer

Game support for landscape and portrait 0 Answers

Background Sprite Setting 0 Answers

Retrieve Continuous Touch Coordinate 0 Answers

Know Which Button is Clicked 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