How to animate a spinning wheel?
Hello. I am working on a simple project where a roulette wheel spins for a few seconds then slows to a stop using a coroutine. When I tun the program the wheel only moves a few pixels then stops. I'm thinking it has something to do with the way my IEnumerator is set up but I am not sure how to go about fixing it. The code is posted below. Thanks for any help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WheelController : MonoBehaviour
{
float rotSpeed = 0;
public float activeRotSpeed = 20f;
public float rotDecrease = 0.90f;
// Start is called before the first frame update
void Start()
{
this.rotSpeed = activeRotSpeed;
}
IEnumerator WheelCon()
{
transform.Rotate(0, 0, this.rotSpeed);
yield return new WaitForSeconds(5);
this.rotSpeed *= rotDecrease;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
StartCoroutine(WheelCon());
}
}
}
Comment
Answer by andrew-lukasik · Aug 03, 2021 at 09:22 AM
Coroutine:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WheelController : MonoBehaviour
{
[SerializeField] AnimationCurve _spinCurve = new AnimationCurve(
new Keyframe( 0f , 0f , -1f , 0f ) ,
new Keyframe( 0.1f , 1f , -1f , 0f ) ,
new Keyframe( 0.8f , 1f , -1f , 0f ) ,
new Keyframe( 1f , 0f , -1f , 0f )
);
[SerializeField] float _spinAmplitude = 200f;// stretches spin curve vertically
[SerializeField] float _spinDuration = 5f;// stretches spin curve horizontally
void Update ()
{
if( Input.GetMouseButtonDown(0) )
{
StartCoroutine( StartSpinning() );
}
}
IEnumerator StartSpinning ()
{
float spinStartTime = Time.time;
while( ( Time.time - spinStartTime ) < _spinDuration )
{
float curveTime = ( Time.time - spinStartTime ) / _spinDuration;
float degrees = _spinCurve.Evaluate( curveTime ) * _spinAmplitude;
if( Mathf.Abs(degrees)>0 )
{
transform.Rotate( 0 , 0 , degrees * Time.deltaTime , Space.Self );
}
yield return null;
}
}
}
No coroutine:
using UnityEngine;
public class WheelController : MonoBehaviour
{
[SerializeField] AnimationCurve _spinCurve = new AnimationCurve(
new Keyframe( 0f , 0f , -1f , 0f ) ,
new Keyframe( 0.1f , 1f , -1f , 0f ) ,
new Keyframe( 0.8f , 1f , -1f , 0f ) ,
new Keyframe( 1f , 0f , -1f , 0f )
);
[SerializeField] float _spinAmplitude = 200f;// stretches spin curve vertically
[SerializeField] float _spinDuration = 5f;// stretches spin curve horizontally
float _spinStartTime = -1000;
void Update ()
{
if( Input.GetMouseButtonDown(0) )
{
_spinStartTime = Time.time;
}
float curveTime = ( Time.time - _spinStartTime ) / _spinDuration;
float degrees = _spinCurve.Evaluate( curveTime ) * _spinAmplitude;
if( Mathf.Abs(degrees)>0 )
{
transform.Rotate( 0 , 0 , degrees * Time.deltaTime , Space.Self );
}
}
}
You're welcome! I added coroutine implementation too, you can choose either one.