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 Rick74 · Oct 14, 2013 at 01:30 PM · javascriptlerpslerp

Slerp, lerp or something else?

So I'm trying to achieve the same effect that launching plants achieve in Plants versus Zombies. Where an object targets a moving enemy...get's tossed in the air and eventually hits it's target.

The hieght of the arc is dictated by the distance the object needs to travel to get to it's target. At first I thought this was a slerp, but perhaps this is something else.

here's a video showcasing the type of dynamic arch I'm trying to achieve.

gameplay video

My limited experience of a slerp has the speed the object travels varied to have it hit the target at the desired time. In the video, the speed is constant, and the arc of the object is adjusted to insure that the object hit's the target at the desired time.

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

3 Replies

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

Answer by robertbu · Oct 14, 2013 at 04:12 PM

It wouldn't take much to simulate the throw with some simple physics calculations, but for what is done in the video, I think a simple Sin() function will do the job. It is not only that the object is flying in an arc, but that the movement up/down under the influence of gravity need to look right. Here is a sample script. I've calculated the height as half of the distance traveled. You can adjust this for the specific feel of your throws. In looking at the video, it seemed that objects had a speed rather than a time. That is an object thrown from a further distance took more time. It was hard for me to tell. I've implement the code with speed, but you can just set 'time' to a fixed value if you want the object to travel in a fixed amount of time no matter what the distance. To test:

  • Create a new scene

  • Create a sphere at the origin

  • Scale the sphere down (0.4, 0.4 0,4)

  • Attach the following script

  • While running the app, click the left mouse button


    var speed = 4.0; private var lobbing = false;

    function Lob(dest : Vector3) { lobbing = true; var start = transform.position; var dist = (dest - transform.position).magnitude; var height = 0.5 * dist; var timer = 0.0; var time = dist / speed; var fraction = 0.0;

       do {
             fraction = timer / time;
             var pos = Vector3.Lerp(start, dest,  fraction);
             pos.y += Mathf.Sin(Mathf.PI * fraction) * height;
             transform.position = pos;
             timer += Time.deltaTime;
             yield;
         } while (fraction < 1.0);
         
         transform.position = dest;
         lobbing = false;
     }
     
     function Update () {
         if (!lobbing && Input.GetMouseButtonDown(0)) {
             var pos = Input.mousePosition;
             pos.z = 10;
             pos = Camera.main.ScreenToWorldPoint(pos);
             Lob(pos);
         }
     }
    
Comment
Add comment · Show 6 · 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 Rick74 · Oct 14, 2013 at 04:42 PM 0
Share

Hey Rob, thanks for looking into this!

I tried your code, and it's an interesting little trick, but the behaviour is different to what is happening in the video. In the video I count roughly 2 seconds from the time launched to impact. The height of the arch get's visibly taller the closer the target gets to the plant. The height of the arch is the variable, the time to impact is the constant. I'd like to say the speed is also constant, but it's hard to say.

Watching it again, I also noticed that the apex of the arc is roughly 2/3rds into the arc (favoring the target's side)

Did a quick sketch to show what it is I think I'm seeing here.

I also tried changing the variable variable "timer" to a fixed number like you suggested and the results had the spere snapping to the destination.

avatar image sed · Oct 14, 2013 at 04:50 PM 0
Share

A bezier curve with the control point closer to the enemy any1? ;)

avatar image robertbu · Oct 14, 2013 at 07:48 PM 1
Share

Your sketch is not working. It is 'time' you need to set to get a fixed time travel. So on line 10, just make 'time' equal some constant. As for the arc and where it is favored, you can skew the time used in the curve using another curve. Change line 16 to:

 pos.y += $$anonymous$$athf.Sin($$anonymous$$athf.PI * $$anonymous$$athf.Pow(fraction, power)) * height;

Declare a 'power' variable in the top of the file and set it to 1.25 to start. Adjust it as you see fit.

avatar image Rick74 · Oct 15, 2013 at 02:43 AM 0
Share

I made the changes as you instructed and in this code I'm still seeing the arc change height the further the distance from origin to the place you clicked.

In the video the arc gets taller as the distance traveled gets shorter. I'll try to upload the pic again.

Both the red and blue travel time is roughly 2 seconds.

To accommodate that the zombie is closer to the plant, the plant tosses the projectile higher in the air, creating a taller arc allowing it to hit the target at the 2 second mark.

In the blue line, the zombie is further away so the arc is shorter, to allow the projectile to hit it's target again at the 2 second mark.

I appreciate all the help you've given me on this so far!

alt text

avatar image robertbu · Oct 15, 2013 at 04:02 AM 0
Share

It is really hard for me to see what is going on in the video. Different plants are shooting and new zombies are not necessarily on the same 'y' value of the board. To me, it almost looked like the height was the same (i.e. just set to a constant). But let's say you want the different size arcs as you describe. Change the height calculation in line 8 to:

 var height = 2.0 - heightFactor * dist;

$$anonymous$$ake heightFactor a variable and and set it 0.1. The 2.0 probably should be a variable as well (maxHeight), and set to 2.0 to start.

Show more comments
avatar image
1

Answer by Calum-McManus · Oct 14, 2013 at 02:16 PM

I've done something similar with making a character walk to a way point but walking in a curve to get there.

First you set up a vector 3 to give a direction from the spawn of the projectile to the enemy;

 Vector3 vDir = (enemy.transform.position - spawn.transform.position).normalized;

Then give the projectile speed;

 float fMovementDelta = (speed * Time.deltaTime) * transform.root.localScale.x;

Now tell it to move;

 projectile.transform.position += projectile.transform.forward * fMovementDelta;
             Vector3 vLocalPosition = projectile.transform.localPosition;
             vLocalPosition.y = 0;
             projectile.transform.localPosition = vLocalPosition;

Now the part you want, tell it to always have one of its axis facing the enemy;

 Quaternion qTo = Quaternion.LookRotation(vDir, transform.up);

Now tell it to curve using Quaternion.Lerp;

projectile.rotation = Quaterion.Lerp(projectile.transform, qTo, (speed*4)*Time.deltaTime);

Im sorry this is in C# but that's all i know in this depth, hopefully if you really cant use this someone can convert it for you. If there is any part of this you don't understand leave a comment and i will help as soon as i can :)

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 Rick74 · Oct 14, 2013 at 03:03 PM 0
Share

I like this as a possible solution. It sounds like allot of calculations, which has me scared if I wanna have many projectiles use this per frame. But perhaps their's just no avoiding this.

Can someone translate this to Java? I'm going to give it a shot, but I'm still learning Java, and I have zero experience with C#

Trying to translate this, this is what I have so far but it's coughing out a ton of errors so obviously it's way off...

 var vDir              :Vector3;
 var speed            :float = 5.0;
 
 var enemy            :Transform;
 var spawn            :Transform;
 var f$$anonymous$$ovementDelata :float;
 var qTo                :Quaternion;
 
 function Update ()
 {
     vDir = (enemy.transform.position - spawn.transform.position).normalized;
     f$$anonymous$$ovementDelta = (speed * Time.deltaTime) * transform.root.localScale.x;
     
     projectile.transform.position += projectile.transform.forward * f$$anonymous$$ovementDelta;
     
     Vector3.vLocalPosition = projectile.transform.localPosition;
     vLocalPosition.y = 0;
     projectile.transform.localPosition = vLocalPosition;
     
     qTo = Quaternion.LookRotation (vDir, transform.up);
     
     projectile.rotation = Quaternion.Lerp(projectile.transform, qTo, (speed*4)*Time.deltaTime);
 }
avatar image Gruffy · Nov 21, 2013 at 03:41 PM 1
Share

simples, there you go

 using UnityEngine;
 using System.Collections
 public class myClass : $$anonymous$$onoBehaviour
 { 
 
  public Vector3 vDir;
         public float speed = 5.0f;
          
         public Transform enemy;
         public Transform spawn;
         public float f$$anonymous$$ovementDelta;
         private Quaternion qTo :;
          
         void Update ()
         {
         vDir = (enemy.transform.position - spawn.transform.position).normalized;
         f$$anonymous$$ovementDelta = (speed * Time.deltaTime) * transform.root.localScale.x;
          
         projectile.transform.position += projectile.transform.forward * f$$anonymous$$ovementDelta;
          
         Vector3.vLocalPosition = projectile.transform.localPosition;
         vLocalPosition.y = 0;
         projectile.transform.localPosition = vLocalPosition;
          
         qTo = Quaternion.LookRotation (vDir, transform.up);
          
         projectile.rotation = Quaternion.Lerp(projectile.transform, qTo, (speed*4)*Time.deltaTime);
         }
 }
avatar image
0

Answer by sed · Oct 14, 2013 at 02:24 PM

Maybe you would be better off with moving your objects along a bezier curve?

http://answers.unity3d.com/questions/12689/moving-an-object-along-a-bezier-curve.html

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

With one control point (position of which you can make slightly random and dependant upon the distance between shooter and the target) you can achieve a similar effect.

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

17 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

Related Questions

How to Lerp or Slerp Time.timeScale change 1 Answer

How to use Lerp? 3 Answers

Moving player in an arc, from startPoint to endPoint 2 Answers

Use Lerp Position and Slerp Rotation together 0 Answers

Object lerping at start 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