- Home /
Need to stop rotation of cylinder after a certain number of rotations
I have created a slot machine with three reels. Each reel is made up of a 3d cylinder. Each reel has a rotating animation script attached. This script will make the reels begin to rotate. I have created some GUI (Graphic User Interface) buttons that have a control script attached. When the spin GUI button is pressed it triggers the rotate script. Also I have a stop GUI button and when pressed the reels stop. Right now the all spin,
What I am trying to do is to get these reels to stop sequentially. So all the reels will start spinning and then the first one will stop, the the second, and then the third. What we need to so is figure out a way to modify the rotate script to rotate for a certain amount of rotations and then stop or be able to rotate for a certain amount of time. So the first would stop, then the second, and then the third.
This is the rotating script attached to the reels/cylinders....
var speedforChange: int;
function Update () { amtToMove = speedforChange * Time.deltaTime; if(ControlScript.triggerGo == 1){
transform.Rotate(0, speedforChange*Time.deltaTime,0);
}
}
This is the control script for the GUI buttons....
static var triggerGo: int;
function OnGUI () { //Make a background box GUI.Box (Rect (500,10,100,90), "SLOT");
//Make the first button if (GUI.Button (Rect(510,40,80,20), "Spin")){ triggerGo = 1; // Assign the other clip and play it
print(triggerGo);
}
//Make the second button if (GUI.Button (Rect(510,70,80,20), "Stop")){ triggerGo = 0; print(triggerGo);
}
}
I am very new to scripting. Is there someone that can help add onto these codes that can help me modify the rotations either by number of rotations or a set time. Thanks
Answer by skovacs1 · Sep 14, 2010 at 08:44 PM
You can use some co-routines to drive your actions here in order to wait a set amount of time. You could alternatively use timers or time value checking. Here I use some general state variables.
SpinControl.js
//Here I assume all of your spinners are tagged *Spinner* static var changeDuration = 2; //How long to change states in seconds enum SlotState {Stopped, Starting, Spinning, Stopping}; static var state = SlotState.Stopped;
function OnGUI () { GUI.Box(Rect(500,10,100,90), "SLOT"); //Make a background box if(GUI.Button(Rect(510,40,80,20), "Spin") && state == SlotState.Stopped) Spin(); if(GUI.Button(Rect(510,70,80,20), "Stop") && state == SlotState.Spinning) Stop(); }
function Spin() { state = SlotState.Starting; for(var spinner : GameObject in GameObject.FindGameObjectsWithTag("Spinner")) spinner.GetComponent(SpinnerScript).state = SlotState.Starting; yield WaitForSeconds(changeDuration); state = SlotState.Spinning; }
function Stop() { state = SlotState.Stopping; //If the order matters, you could do name checking or store the slots as variables //in this script and then reference them specifically - whatever floats your boat. for(var spinner : GameObject in GameObject.FindGameObjectsWithTag("Spinner")) { spinner.GetComponent(SpinnerScript).state = SlotState.Stopping; yield WaitForSeconds(changeDuration 0.75); //Slow down part way } yield WaitForSeconds(changeDuration 0.25); //Slow the rest of the way state = SlotState.Stopped; }
SpinnerScript.js
//degrees per second var maxSpeed : int = 15; var currentSpeed : int = 0;
var state = SlotState.Stopped;
function Update () { if(state == SlotState.Starting) { //accelerate currentSpeed += maxSpeed Time.deltaTime / SpinControl.changeDuration; if(currentSpeed >= maxSpeed) { currentSpeed = maxSpeed; state = SlotState.Spinning; } } else if (state == SlotState.Stopping) { //decelerate currentSpeed -= maxSpeed Time.deltaTime / SpinControl.changeDuration; if(currentSpeed <= 0) { currentSpeed = 0; state = SlotState.Stopped; } } transform.Rotate(0, currentSpeed*Time.deltaTime,0); }
What was with the amtToMove variable that you don't use here?
Since your question title was about a certain number of rotations, I'll assume you meant to use it that way. To stop after a certain number of rotations you could do something like calling the Stop function when the spinner reaches n rotations. Here I do it in the spinner, but you could do it in the SpinControl.
SpinControl.js
//Here I assume all of your spinners are tagged *Spinner* static var changeDuration = 2; //How long to change states in seconds enum SlotState {Stopped, Starting, Spinning, Stopping}; static var state = SlotState.Stopped;
function OnGUI () { GUI.Box(Rect(500,10,100,90), "SLOT"); //Make a background box if(GUI.Button(Rect(510,40,80,20), "Spin") && state == SlotState.Stopped) Spin(); if(GUI.Button(Rect(510,70,80,20), "Stop") && state == SlotState.Spinning) Stop(); }
function Spin() { state = SlotState.Starting; for(var spinner : GameObject in GameObject.FindGameObjectsWithTag("Spinner")) spinner.GetComponent(SpinnerScript).state = SlotState.Starting; yield WaitForSeconds(changeDuration); state = SlotState.Spinning; }
static function Stop() { if(state != SlotState.Spinning) return; state = SlotState.Stopping; for(var spinner : GameObject in GameObject.FindGameObjectsWithTag("Spinner")) { spinner.GetComponent(SpinnerScript).state = SlotState.Stopping; yield WaitForSeconds(changeDuration 0.75); //Slow down part way } yield WaitForSeconds(changeDuration 0.25); //Slow the rest of the way state = SlotState.Stopped; }
SpinnerScript.js
//degrees per second var maxSpeed : int = 15; var currentSpeed : int = 0;
var maxRotations : int = 30; var rotations : int = 0; var state = SlotState.Stopped;
function Update () { if(state == SlotState.Starting) { //accelerate rotations = 0; currentSpeed += maxSpeed Time.deltaTime / SpinControl.changeDuration; if(currentSpeed >= maxSpeed) { currentSpeed = maxSpeed; state = SlotState.Spinning; } } else if (state == SlotState.Stopping) { //decelerate currentSpeed -= maxSpeed Time.deltaTime / SpinControl.changeDuration; if(currentSpeed <= 0) { currentSpeed = 0; state = SlotState.Stopped; } } transform.Rotate(0, currentSpeed*Time.deltaTime,0); rotations += currentSpeed*Time.deltaTime / 360; if(state == SlotState.Spinning && rotations >= maxRotations) SpinControl.Stop(); }
Answer by Dan Jimenez · Sep 15, 2010 at 11:47 PM
This worked great. Thank you so much for all your help.
This should be posted as a comment, not a separate answer. If skovacs1 has solved your question, please mark it as correct (tick the box beneath the up/down arrows next to his post). This will help keep UnityAnswers clean and useful!
Your answer
Follow this Question
Related Questions
Attach image to button 1 Answer
Script for a GUI button to change an object's rotation? 1 Answer
On-screen button press 1 Answer
Move GUI elements. 0 Answers
Can I use a movie texture with alpha as a GUI object? 1 Answer