Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 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

Is this a ho$$anonymous$$g missile or do you target a fixed position? Do you want the arc to always be up or are you looking for something more organic?

avatar image Li0nSword · Feb 26, 2014 at 05:52 PM 0
Share

The position is dynamic as the player can continue moving as the missile homes. I'm looking for something fairly simple, so even if it arced only as the enemy shot the rocket and then straightens out would be perfectly fine.

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 something like

 this.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

This worked very well. Thanks!

avatar image kendyb · Jan 08, 2015 at 03:10 PM 1
Share

another clear explanation of bezier curves: http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/

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 this waypoints instead of using a formula, just add 4, the first, your origin, second and third, at 1 third 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 something like this

 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;
     
     while (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

This is giving me a close effect. I'm sure with a bit more tweaking I can get what i'm looking for.

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. Meanwhile, 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

While this is true it's actually more complicated / complex that way First of all reinventing the wheel for a lerp is pretty pointless. You can use Vector3.Lerp ins$$anonymous$$d of your "LinearInterpolate".


Calling lerp 3 times is rather inefficient. For a quadratic bezier you should just use a bezier implementation like "Hamdullahshah" posted in his answer. So your answer is the same as Hamdullahshah's answer just less efficient. Also you may want to rethink about your variable names. line1 and line2 do not store lines. They are points. Also "duration" is not a duration. It could be called "time", "progress" or "fraction". Duration describes a usually constant amount of time usually in seconds. The "t" / "time" value of a lerp or a bezier curve is just the interpolation value

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 this 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 this 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.

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

Set custom policy for mono developer 0 Answers

In App Purchase Implementation for Android and iPhone 1 Answer

Determine Texture Size 0 Answers

OnTriggerStay2D calculate Stay Time before calling other method 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