- Home /
Using a GUI button to stop a gameobject movement
Hi,
I'm trying to use a GUI button to stop the scripted movement of a gameObject.
This is the deal: I have an elevator moving from one floor to another when the player presses a button on the elevator panel. I'm using this code:
while(elevatorHeight > triggerHeight) { elevatorHeight = Mathf.Ceil(elevator.transform.position.y); triggerHeight = Mathf.Ceil(trigger.transform.position.y); elevator.transform.Translate(Vector3(0, 0 , -speed*Time.deltaTime)); yield; }
while(elevatorHeight < triggerHeight)
{
elevatorHeight = Mathf.Floor(elevator.transform.position.y);
triggerHeight = Mathf.Ceil(trigger.transform.position.y);
elevator.transform.Translate(Vector3(0, 0 , speed*Time.deltaTime));
yield;
}
Now I need to create a GUI button able to stop the elevator movement at any point and then resume it's movement.
How can I do this?
Thanks for any help
Answer by Motionreactor · Mar 03, 2010 at 02:51 PM
Ok, I've written a complete script for you because I thought it important to help illustrate a more flexible approach to the problem:
Drop this script onto the elevator:
var elevatorSpeed : float; var floor1Height : float; var floor2Height : float; var floor3Height : float;
private var elevator : GameObject; private var elevatorActive : boolean; private var elevatorDestination : float;
function Start() { // initialise variables which must have a value, otherwise errors ensue elevator = this.gameObject; elevatorActive = false; elevatorDestination = elevator.transform.position.y; }
function Update() { if(elevatorActive) { MoveElevator(); } }
function MoveElevator() { // Move the elevator elevator.transform.position.y = Mathf.Lerp(elevator.transform.position.y, elevatorDestination, elevatorSpeed * Time.deltaTime);
// Disable the elevator if it is within a very small margin of the destination, ie it is 'close enough' so stop
if(Mathf.Abs(elevator.transform.position.y - elevatorDestination) < 0.01)
{
print("stopped elevator");
elevatorActive = false;
}
}
function GoToFloor(floorNum : int) { switch(floorNum) { case 1: elevatorDestination = floor1Height; break; case 2: elevatorDestination = floor2Height; break; case 3: elevatorDestination = floor3Height; break; default: elevatorDestination = floor1Height; break; }
elevatorActive = true;
}
function StopElevator() { elevatorActive = false; }
function ResumeElevator() { elevatorActive = true; }
Now all you have to do is set the speed and floor variables in the component.
To 'trigger' the elevator from another script on another object, such as a trigger of course:
GameObject.Find("Elevator").GetComponent("ElevatorScript").GoToFloor(1);
...and of course emergency stop:
GameObject.Find("Elevator").GetComponent("ElevatorScript").StopElevator();
...and resume from stopped position (even if halfway between floors):
GameObject.Find("Elevator").GetComponent("ElevatorScript").ResumeElevator();
Voila! ...and all without a pesky while() loop in sight! (nasty things for beginners!)
An alternative way to move the elevator with a clamped speed, limited to a maximum is a case of changing a variable:
var elevatorSpeed : float;
becomes:
var elevatorMaxSpeed : float;
...and the move function :
function MoveElevator() { // Calculate difference between current position and desired position var elevatorVelocity = elevatorDestination - elevator.transform.position.y;
// Limit the velocity by clamping it to positive or negative maximum velocity
elevatorVelocity = Mathf.Clamp(elevatorVelocity, -elevatorMaxSpeed, elevatorMaxSpeed);
// Move the elevator
elevator.transform.position.y += elevatorVelocity * Time.deltaTime; // += accomodates positive or negative movement and Time.deltaTime gives us some smoothing
// Disable the elevator if it is within a very small margin of the destination, ie it is 'close enough' so stop
if(Mathf.Abs(elevator.transform.position.y - elevatorDestination) < 0.01)
{
print("stopped elevator");
elevatorActive = false;
}
}
I set the max speed to a fairly low value 0.5 in my case.
I may have used some things unfamiliar to you, let me know if you need help deciphering this.
@$$anonymous$$otionreactor, Nice and elegant... :) I need to start using $$anonymous$$athf.Lerp
like.. everywhere :)
I still find Lerp uncomfortable to use, and have to frequently check how to use it. For years I've been writing my own interpolation in other languages, so using Lerp feels like cheating!
@$$anonymous$$otionreactor unfortunately I can't test this script right now.. and never really used Lerp in Unity yet.. Can you tell me if the elevator is moving at the exact speed all the time..? (Is speed the same when going from f1 > f4 with going f1 > f2)
Thanks a lot..I'm gonna test the script in a $$anonymous$$ute, I will give you some feedback in a while..thanks once again
Answer by Ashkan_gc · Mar 03, 2010 at 01:48 PM
you should write something like this
function OnGUI ()
{
if (GUI.Button (Rect(30,30,100,100),str) == true)
{
if (str == "pause")
{
str="resume";
speed=0;
}
else
{
speed=10;
str="pause";
}
}
}
you should define the str string var in your script and set it's default value to "pause". 10 is a sample value for speed. set it to what you want.
I understood $$anonymous$$otion's script perfectly... but I must admit yours eludes me... for example, indentation would be a nice addition to the clarity of your script
Answer by duck · Mar 03, 2010 at 01:48 PM
You should probably have your button panels set a variable on your elevator which is the "destination height". Then, make it so your elevator is always trying to reach the destination height if it's not already there. (It looks like you may already have something like this in your "triggerHeight" variable). If you rename it to "destinationHeight" it might make more sense.
You could then cancel the movement of the elevator by simply setting the "destinationHeight" to the elevator's current height.
I have a trigger on each floor, thats why I'm using the triggerHeight variable. The script compares the elevator position with the trigger it's trying to reach and moves it up or down until it reaches the destination.
I understand that by setting the elevator position to the same as the trigger, the elevator would stop. The problem is that I have 5 different triggers (5 floors), and the elevator could be trying to reach any of them.
So should I put that code on the elevator script or the GUI? If it's in the elevator script, how can I link it with the GUI button?
Thanks a lot
I think Ashkan's solution of setting the speed to zero is a better idea, given the requirement of being able to restart the motion towards the target.
Your answer

Follow this Question
Related Questions
My Buttons are dissapearing 0 Answers
GUI Button not displaying an icon 3 Answers
Is it possible to detect which GUIStyleState is used? 2 Answers
GUI Button make text bigger. 2 Answers
Touches aren't working on Android 1 Answer