• 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 igorpan · Jul 15, 2012 at 01:24 AM · speedaxistranslate

Slowly accelerate and slowly slow down while moving

I really can't figure how to do this. I tried many ways, drawing on paper, projecting vectors on axis etc.

Here is the deal:

I have a helicopter object. It has some simple AI code I wrote down, and basically, it just picks a random point in the world and flies towards it. Now, I can easily make it accelerate until it reaches some max speed, but how do I make it slow down as it reaches towards it's destination?

And thats one part of the problem, second part is: how do I get it's move speed per one axis? The reason I need this for is that helicopters lean as they move and I need to make angle dependant on movespeed per that axis.

I hope I explained my problem well enough.

I use C#, but I'm quite comfortable with JS too so it really doesn't matter in which language script is written.

Comment
Add comment · Show 3
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 Fattie · Jul 15, 2012 at 07:35 AM 0
Share

Igorpan - just a thought.

Have you considered to make a set-up, so that the helicopter is "automatic" -- what i mean is, you can set up the physics rig so that the chopper leans and so on completely automatically on it's own, the PhysX engine will do all that for you in a simulation.

Basically you make the helicopter a little point at the center of the blades, and you hang the body of the helicopter from that. it will swing and so on perfectly of it's own accord. it could work for you!

avatar image igorpan · Jul 16, 2012 at 12:09 AM 0
Share

Using physics is out of the question as with my current knowledge of Unity itself it would bring me more trouble than solutions :)

avatar image Fattie · Jul 16, 2012 at 06:50 AM 0
Share

"Using physics is out of the question as with my current knowledge of Unity..." ... In fact it is $$anonymous$$UCH EASIER to "turn on" the physics and let Unity do everything. All you do is basically add some colldiers, etc, and let unity do the job. So, just keep it in $$anonymous$$d for the future !!!! something to consider

1 Reply

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

Answer by aldonaletto · Jul 15, 2012 at 02:20 AM

EDITED: I changed my previous answer to something more complete (the script I used to test that answer)

You could define a distance value, and decelerate when entering this distance from the target point - by the way, the same trick can be used to accelerate. To lean according to the movement, you can use the current velocity and tilt a vector in its direction, making the helicopter follow this vector:

using UnityEngine; using System.Collections;

public class Helicopter : MonoBehaviour {

 public float maxVel = 30; // cruise speed
 public float startVel = 5; // speed at the starting point
 public float stopVel = 0.5f; // speed at the destination
 public float accDistance = 20; // acceleration/deceleration distance
 public float factor = 0.25f; // max inclination
 public float turnSpeed = 0.8f; // speed to turn/bank in the target direction

 Vector3 lastPos; // used to calculate current velocity

 void Start(){
     lastPos = transform.position;
     StartCoroutine(Fly()); // demo routine
 }

 // calculate bank/turn rotation at Update
 void Update(){
     // calculate the displacement since last frame:
     Vector3 dir = transform.position-lastPos;
     lastPos = transform.position; // update lastPos
     float dist = dir.magnitude;
     if (dist > 0.001f){ // if moved at least 0.001...
         dir /= dist; // normalize dir...
         float vel = dist/Time.deltaTime; // and calculate current velocity
         // bank in the direction of movement according to velocity
         Quaternion bankRot = Quaternion.LookRotation(dir+factor*Vector3.down*vel/maxVel);
         transform.rotation = Quaternion.Slerp(transform.rotation, bankRot, turnSpeed*Time.deltaTime);
     }
 }
 
 bool flying = false; // shows when FlyTo is running

 // coroutine that moves to the specified point:
 IEnumerator FlyTo(Vector3 targetPos){
     flying = true; // flying is true while moving to the target
     Vector3 startPos = transform.position;
     Vector3 dir = targetPos-startPos;
     float distTotal = dir.magnitude;
     dir /= distTotal; // normalize vector dir
     // calculate accDist even for short distances
     float accDist = Mathf.Min(accDistance, distTotal/2);
     do {
         float dist1 = Vector3.Distance(transform.position, startPos);
         float dist2 = distTotal-dist1;
         float speed = maxVel; // assume cruise speed
         if (dist1 < accDist){ // but if in acceleration range...
             // accelerate from startVel to maxVel
             speed = Mathf.Lerp(startVel, maxVel, dist1/accDist);
         }
         else
         if (dist2 < accDist){ // or in deceleration range...
             // fall from maxVel to stopVel
             speed = Mathf.Lerp(stopVel, maxVel, dist2/accDist);
         }
         // move according to current speed:
         transform.position = Vector3.MoveTowards(transform.position, targetPos, speed*Time.deltaTime);
         yield return 0; // let Unity breathe till next frame
     } while (transform.position != targetPos); // finish when target reached
     flying = false; // shows that flight has finished
 }

 // example routine: fly to 3 different points in sequence
 IEnumerator Fly(){
     Vector3 p0 = transform.position;
     Vector3 p1 = p0 + new Vector3(150, 0, 200);
     Vector3 p2 = p1 - new Vector3(-220, 0, 300);
     while (true){
         StartCoroutine(FlyTo(p1)); // fly to point 1
         while (flying) yield return 0; // wait flight to finish
         yield return new WaitForSeconds(5); // rest for 5 seconds
         StartCoroutine(FlyTo(p2));
         while (flying) yield return 0;
         yield return new WaitForSeconds(5);
         StartCoroutine(FlyTo(p0));
         while (flying) yield return 0;
         yield return new WaitForSeconds(5);
     }
 }

}

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 igorpan · Jul 16, 2012 at 12:07 AM 0
Share

Whoa! Almost worked instantly! This is so well writen and explained with comments, but I'm very new to Unity and have never used Quaternions. Unfortunately, that is the only part of this script that doesn't function well in my case. It does what it should, but it looks like it uses wrong axis. I tried "playing" with it, but without positive results.

Game is actually 2-dimensional as all objects will be placed on X=0.

What I need for this heli to do actually sounds very simple, here is the idea: http://www.igorpantovic.tk/randomStuff/heli.png It would just slowly lean and slowly return to neutral 0 angle.

Here is screencapture of what is actually happening: http://www.igorpantovic.tk/randomStuff/sc.mp4

I tought the problem might be in the fact that my Helicopter model is rotated by 270 degrees on Y axis by default placement in the scene so I made it 0 degrees, but it still rotates wrong.

I guess it just needs some angle offset to be added to that rotation part but I can't seem to figure it out on my own yet.

avatar image aldonaletto · Jul 16, 2012 at 02:47 AM 0
Share

This script aligns the forward direction (blue axis) to the direction it's moving - but the blue axis is the right side, what makes it fly laterally to the target. A possible solution is to change this line:

 Quaternion bankRot = Quaternion.LookRotation(dir+factor*Vector3.down*vel/maxVel);

to this:

 Quaternion bankRot = Quaternion.FromToRotation(Vector3.left, dir+factor*Vector3.down*vel/maxVel); 

Another possible problem: when the target is at a different height, the helicopter may become inclined in its direction even when stopped. If this happens, add these lines right before the line changed:

 dir.y = 0; // kill height difference
 dir.Normalize(); // normalize the modified dir
 Quaternion bankRot = Quaternion.FromToRotation(Vector3.left, dir+factor*Vector3.down*vel/maxVel); 
 ...
avatar image igorpan · Jul 18, 2012 at 10:58 AM 0
Share

Almost, your script would work perfectly for a game in 3D world, but I think you didn't understand that my needs were quite more primitive than in the rotation part. Anyway, I managed to modify it to work by just shortening it, and it is a bit "manual", but it works :)

Here is what made it work as I wanted in the rotation part:

 // calculate bank/turn rotation at Update
 void Update(){
     // calculate the displacement since last frame:
     Vector3 dir = transform.position-lastPos;
     lastPos = transform.position; // update lastPos
     Vector3 speed = dir/Time.deltaTime;
     targetVector = transform.position + new Vector3(0,-speed.z*factor,5);
     transform.LookAt(targetVector);
 }

And just an addition that somebody might find useful:

 bool repeatFlightRoute = true;

 IEnumerator FlySequence(Vector3[] points, float $$anonymous$$WaitSeconds = 0, float maxWaitSeconds = 0) {
     for (int i=0; i < points.Length; i++)
     {
         float pauseTime = $$anonymous$$WaitSeconds + Random.value*(maxWaitSeconds-$$anonymous$$WaitSeconds);
         StartCoroutine(FlyTo (points[i]));
         while (flying) yield return 0;
         yield return new WaitForSeconds(pauseTime);
         if (i == points.Length - 1 && repeatFlightRoute) i = -1;
     }
 }

Thank you so much for your help!

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

6 People are following this question.

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

Related Questions

How do I determine mouse speed on the x and z axis? 0 Answers

How to determine the axis specific speed (or velocity) of a kinematic object? 0 Answers

Issue regarding Rigidbody2D 0 Answers

Moving an object based on the position of another object 2 Answers

Translating in world space only on y axis? 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