c# - How to make an object seek and decelerate to a stop exactly on a specified position? -


introduction

i trying create script (c# script in unity) controls point , click behaviour gameobject.

in essence, player - in end - control hot air balloon clicking on screen, whereby object start accelerate , move toward position of click. when @ specific distance of click position, hot air balloon should start accelerate in opposite direction (thus decelerating) , come complete halt @ position of click.

i have created functional , commented script (found @ bottom of post), moves gameobject towards position of click @ constant speed, , then, when within specific distance, starts slow down until stopping @ point.

i have created separately , functional script moves toward position of click while accelerating (getting kind of asteroids thrusting behaviour). can found @ bottom of post.

the problem

now problem i'm facing i've been working quite while find solution can take these 2 behaviours , implement them 1 working script, is, hot air balloon have accelerating behaviour while slowing down , stopping @ target position, visual example found here:

visual arrival behaviour demonstration

the question

my question becomes:

how can make arrival behaviour not using constant speeds, acceleration included in equation well? i've tried research problem experimenting own solutions, nothing seems work quite way should.

script attachments

point , click movement @ constant speeds arrival behaviour

using unityengine; using system.collections;  public class playercontrol : monobehaviour  {     // fields     transform cachedtransform;     vector3 currentmovementvector;     vector3 lastmovementvector;     vector3 currentpointtomoveto;     vector3 velocity;     int movementspeed;      vector3 clickscreenposition;     vector3 clickworldposition;      float slowingdistance = 8.0f;      vector3 desiredvelocity;      float maxspeed = 1000.0f;      // use initialization     void start ()      {         cachedtransform = transform;         currentmovementvector = new vector3(0, 0);         movementspeed = 50;         currentpointtomoveto = new vector3(0, 0);         velocity = new vector3(0, 0, 0);     }      // update called once per frame     void update ()      {         // retrive left click input         if (input.getmousebuttondown(0))         {             // retrive click of mouse in game world             clickscreenposition = input.mouseposition;              clickworldposition = camera.main.screentoworldpoint(new      vector3(clickscreenposition.x, clickscreenposition.y, 0));             currentpointtomoveto = clickworldposition;              currentpointtomoveto.z = 0;              // calculate current vector between player position , click             vector3 currentplayerposition = cachedtransform.position;              // find angle (in radians) between 2 positions (player position , click position)             float angle = mathf.atan2(clickworldposition.y - currentplayerposition.y, clickworldposition.x - currentplayerposition.x);              // find distance between 2 points             float distance = vector3.distance(currentplayerposition, clickworldposition);              // calculate components of new movemevent vector             float xcomponent = mathf.cos(angle) * distance;             float ycomponent = mathf.sin(angle) * distance;              // create new movement vector             vector3 newmovementvector = new vector3(xcomponent, ycomponent, 0);             newmovementvector.normalize();              currentmovementvector = newmovementvector;         }          float distancetoendpoint = vector3.distance(cachedtransform.position, currentpointtomoveto);          vector3 desiredvelocity = currentpointtomoveto - cachedtransform.position;          desiredvelocity.normalize();          if (distancetoendpoint < slowingdistance)         {             desiredvelocity *= movementspeed * distancetoendpoint/slowingdistance;         }         else         {             desiredvelocity *= movementspeed;         }          vector3 force = (desiredvelocity - currentmovementvector);         currentmovementvector += force;          cachedtransform.position += currentmovementvector * time.deltatime;     } } 

point , click movement using acceleration no arrival behaviour

using unityengine; using system.collections;  public class simpleacceleration : monobehaviour  {     vector3 velocity;     vector3 currentmovementvector;      vector3 clickscreenposition;     vector3 clickworldposition;      vector3 currentpointtomoveto;     transform cachedtransform;      float maxspeed;      // use initialization     void start ()      {         velocity = vector3.zero;         currentmovementvector = vector3.zero;         cachedtransform = transform;         maxspeed = 100.0f;     }      // update called once per frame     void update ()      {         // retrive left click input         if (input.getmousebuttondown(0))         {             // retrive click of mouse in game world             clickscreenposition = input.mouseposition;              clickworldposition = camera.main.screentoworldpoint(new vector3(clickscreenposition.x, clickscreenposition.y, 0));             currentpointtomoveto = clickworldposition;              // reset z position of clicking point 0             currentpointtomoveto.z = 0;              // calculate current vector between player position , click             vector3 currentplayerposition = cachedtransform.position;              // find angle (in radians) between 2 positions (player position , click position)             float angle = mathf.atan2(clickworldposition.y - currentplayerposition.y, clickworldposition.x - currentplayerposition.x);              // find distance between 2 points             float distance = vector3.distance(currentplayerposition, clickworldposition);              // calculate components of new movemevent vector             float xcomponent = mathf.cos(angle) * distance;             float ycomponent = mathf.sin(angle) * distance;              // create new movement vector             vector3 newmovementvector = new vector3(xcomponent, ycomponent, 0);             newmovementvector.normalize();              currentmovementvector = newmovementvector;         }          // calculate velocity         velocity += currentmovementvector * 2.0f * time.deltatime;          // if velocity above allowed limit, normalize , keep @ constant max speed when moving (instead of uniformly accelerating)         if (velocity.magnitude >= (maxspeed * time.deltatime))         {             velocity.normalize();             velocity *= maxspeed * time.deltatime;         }          // apply velocity gameobject position         cachedtransform.position += velocity;     } } 

adapt first script:

introduce variable velocity, in second script. set equal movementspeed in start(), , don't use movementspeed after that. do not proceed until works perfectly.

now introduce acceleration:

if (distancetoendpoint < slowingdistance) {    velocity *= distancetoendpoint/slowingdistance; } else {    velocity += direction * 2.0f * time.deltatime; } 

Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -