- Home /
How to return an object back to it's original position when the player steps off it?
I'm trying to get a platform to move to a certain point when the player steps on it and then have it move back when the player steps off. I've gotten quite close but frustration overwhelmed me. Thank you for any help.
Could you include some code? It should be as simple as storing the start position and then perfor$$anonymous$$g a Vector3.Lerp to the start position or if using waypoints, moving along them in reverse.
Alright I will. I was trying not to use waypoints but if it's easier then that's fine.
Waypoints are easier for platforms that follow a path. I don't know enough about what you're doing from the information included to tell you what's best for your project. All I said was that if you were using waypoints, you would follow them in reverse
Answer by skovacs1 · Nov 15, 2010 at 08:36 PM
Having seen what you posted in your "Answer?", there are several things that you should consider that will make your life much easier.
ReturningPlatform.js
var endPoint : Vector3 = Vector3.zero; private var startPoint : Vector3 = Vector3.zero; var duration : float = 2.0f; private var step : float = 0.0f; private var onPlatform : boolean = false;
function Start() { startPoint = transform.position; }
function FixedUpdate() { var delta : float = (Time.deltaTime / duration); if(onPlatform) step += delta; else step -= delta; step = Mathf.Clamp01(step); rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, step)); //Or rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, // Mathf.SmoothStep(0.0f,1.0f,step))); }
function OnCollisionEnter(hit : Collision) { if(hit.gameObject.tag == "Player") onPlatform = true; }
function OnCollisionExit(hit : Collision) { if(hit.gameObject.tag == "Player") onPlatform = false; }
If you want it to smoothly start and stop when the player gets on and off mid-flight, then you'd best slow it down before starting up again to avoid sudden changes. This can be easily done by using some adjustments to step's interpolation in those cases, using more state information than just on/off platform, including something like some interpolation state float or some such to see how far you've interpolated from the last motion to the new one.
To create a ping-pong platform is pretty much the same:
PingPongPlatform.js
var endPoint : Vector3 = Vector3.zero; private var startPoint : Vector3 = Vector3.zero; var duration : float = 2.0f; private var step : float = 0.0f; private var movingBack : boolean = false;
function Start() { startPoint = transform.position; }
function FixedUpdate() { var delta : float = (Time.deltaTime / duration); if(movingBack) step -= delta; else step += delta; step = Mathf.Clamp01(step); rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, step)); //Or rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, // Mathf.SmoothStep(0.0f,1.0f,step))); if(step == 1.0f) movingBack = true; else if(step == 0.0f) movingBack = false; }
If you want to trigger/continue motion only on player collision like some sort of a switch, you could do something like:
SwitchPlatform.js
var endPoint : Vector3 = Vector3.zero; private var startPoint : Vector3 = Vector3.zero; var duration : float = 2.0f; var sensitivity : float = 0.1f; //step away to switch direction private var step : float = 0.0f; private var onPlatform : boolean = false; private var movingBack : boolean = false;
function Start() { startPoint = transform.position; }
function FixedUpdate() { if(onPlatform) { var delta : float = (Time.deltaTime / duration); if(movingBack) step -= delta; else step += delta; step = Mathf.Clamp01(step); rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, step)); //Or rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, // Mathf.SmoothStep(0.0f,1.0f,step))); } }
function OnCollisionEnter(hit : Collision) { if(hit.gameObject.tag == "Player") { onPlatform = true; if(step >= 1.0f-sensitivity) movingBack = true; else if(step <= sensitivity) movingBack = false; //Or if you have sensitivity be a distance, you could do: //if((transform.position-endPoint).magnitude < sensitivity) // movingBack = true; //else if((transform.position-startPoint).magnitude < sensitivity) // movingBack = false; } }
function OnCollisionExit(hit : Collision) { if(hit.gameObject.tag == "Player") onPlatform = false; }
To soften up mid-movement jumps on and off-the platform, you could again add inertia and manipulate the step changes by some function, etc.
Thank you very much! That really helped. To be honest it didn't work exactly but it gave me a huge boost in the right direction and I got it to work on my own. I just want to confirm something to make sure I understand it. When you put step = $$anonymous$$athf.Clamp01(step), do you put step in the parenthesis because you want to return the values to itself? Also, I saw on another Answer that I'm not allowed to treat this as a forum so if this comment is wrong to put here say so and I'll delete it. Thank you so much for the help!
Yeah. Sorry about the typos in the script. I posted that answer during my break and didn't have time to test it. I have made the small corrections to the scripts to make them do as they should. I set step = $$anonymous$$athf.Clamp01(step) to force step to be between 0 and 1 because I am adding/subtracting deltaTime every frame and it could go over or under, meaning that when you switch directions, it will have to wait the amount of time it's over by. Asking for information on a posted answer is not really treating UnityAnswers like a forum.
You could optimize it a bit with 'if(onPlatform && step != 1.0f) step = $$anonymous$$athf.Clamp01(step+delta); else if(step != 0.0f) step = $$anonymous$$athf.Clamp01(step-delta);' for the saved cost of an addition, a subtraction and an assignment or something like that per FixedUpdate. You could further optimize it by checking your clamp manually like so: 'if(onPlatform && step != 1.0f) { step += delta; if(step > 1.0f) step = 1.0f;} else if(step != 0.0f) {step -= delta; if(step < 0.0f) step = 0.0f;}'. You could negate the need to clamp in FixedUpdate at all by moving it to the OnCollision... functions.
Yeah that's fine. I fixed the typos but I guess the lack of testing is what was making it not work. haha Thank you though. I'll also mess with those optimization techniques. Just to let you know what I did...I used a trigger object. When the player steps off the platform and into the trigger it tells the platform to go back to its original position. It worked very well. Still, I'm going to try those techniques. $$anonymous$$uch appreciated. By the way, do you think I should still post the code I used?
Answer by dre38w · Nov 15, 2010 at 04:38 PM
It's very messy so I apologize for that. I was testing quite a bit.
var speed : Vector3 = Vector3(0, 0, 2); //var initPos : Vector3;
private var onPlat : boolean = false;
var endPoint : Vector3;
var duration : float = 2;
var startPoint : Vector3;
//private var startTime : float;
function Start(){ //startPoint = transform.position; //startTime = Time.deltaTime; }
function FixedUpdate(){ if (onPlat) rigidbody.MovePosition(Vector3.Lerp(startPoint, endPoint, (Time.time duration))); else rigidbody.MovePosition(Vector3.Lerp(transform.position, startPoint, (Time.time duration))); }
function OnCollisionEnter(hit : Collision) { if (hit.gameObject.tag == "Player") { onPlat = true; //rigidbody.MovePosition(rigidbody.position + speed * Time.deltaTime); //transform.position = Vector3.Lerp(startPoint, endPoint, // (Time.time+startTime) / duration); } else onPlat = false; }
/function OnCollisionExit() { onPlat = false; //transform.position = Vector3.Lerp(startPoint, endPoint, // (Time.time-startTime) / duration); }/
/function MoveBack() { if(!onPlat) { transform.position = Vector3.Lerp(startPoint, endPoint, (Time.time-startTime) / duration); //rigidbody.MovePosition(rigidbody.position - speed Time.deltaTime); //transform.position.z = initPos.z + // Mathf.Clamp01(Time.time * platformSpeed, transform.position.z); } }
function OnCollisionExit() { if(!onPlat) { rigidbody.MovePosition(rigidbody.position - speed Time.deltaTime); transform.position.z = initPos.z + Mathf.PingPong(Time.time platformSpeed, transform.position.z); } }*/
Is this an answer to your question? If you just wanted to post code, you should add it to the question.
I didn't realize there was an Edit button. haha Sorry about that.
Your answer
![](https://koobas.hobune.stream/wayback/20220613083121im_/https://answers.unity.com/themes/thub/images/avi.jpg)