Hello i m trying to rotate my object smoothly over MouseButtonDown and rotate to identity position on MouseButtonUp and this code rotate my GameObject smoothly but it won't come back to identity position in time.
void Update ()
{
if (GameControls.Games.stateOfGame == GameControls.gameState.inStart || GameControls.Games.stateOfGame == GameControls.gameState.inPlay) {
if (Input.GetMouseButtonDown (0) || Input.GetKeyDown (KeyCode.Space)) {
StartCoroutine(FlyCat ());
}
if (Input.GetMouseButtonUp (0) || Input.GetKeyUp (KeyCode.Space)) {
StartCoroutine (ResetCat ());
}
}
}
IEnumerator FlyCat()
{
animate.enabled = false;
rigidbodyObject.bodyType = RigidbodyType2D.Dynamic;
tempTimer = 0.0f;
if (rigidbodyObject.position.y < maxUpperBorder) {
rigidbodyObject.velocity = Vector2.zero;
rigidbodyObject.AddForce (jumpForce);
while (tempTimer < 0.5f) {
tempTimer += Time.deltaTime;
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.Euler (rotationForce), Time.deltaTime * smooth);
}
rigidbodyObject.gravityScale = gravity;
yield return null;
}
if (InstantiateOnce == true) {
InstantiateOnce = false;
GameControls.Games.GamePlay ();
}
yield return null;
}
IEnumerator ResetCat()
{
while (tempTimer > 0f) {
Debug.Log (tempTimer);
tempTimer -= Time.deltaTime;
transform.rotation = Quaternion.Inverse (Quaternion.Euler(rotationForce));
}
transform.rotation = Quaternion.identity;
yield return null;
}
Answer
I'd usually approach it like this:
// Tracks whether we have a movement in progress.
Coroutine _currentMovement;
// Interrupts the current movement, if any, and starts a new one.
void StartMovement(IEnmumerator movement) {
if(_currentMovement != null)
StopCoroutine(_currentMovement);
_currentMovement = StartCoroutine(movement);
}
// I pass the duration of the transition as an argument.
// That way it's local to the coroutine and I don't get side-effects
// from modifying a shared member variable in other code.
// Let's also add a parameter for the position to blend back to.
IEnumerator BlendBack(Vector3 homePosition, float duration) {
// Keep track of where we started from.
Quaternion startRotation = transform.rotation;
Vector3 startPosition = transform.position;
// Over the course of duration seconds...
for(float time = 0f; time < duration; time += Time.deltaTime)
{
// Compute our progress through the transition, between 0 and 1
float t = time/duration;
// Blend smoothly between the start and end rotation using this progress.
transform.rotation = Quaternion.Slerp(startRotation, Quaternion.identity, t);
transform.position = Vector3.Lerp(startPosition, homePosition, t);
// Wait for the next frame.
yield return null;
}
// Finish any leftover fraction from the last run of the loop:
transform.rotation = Quaternion.identity;
transform.position = homePosition;
// Mark this movement as complete.
_currentMovement = null;
}
Or, if you're using physics, you can replace transform.rotation = ...
with rigidbody.MoveRotation(...)
and position
with MovePosition
By using StartMovement(BlendBack(homePosition, duration))
or StartMovement(SomeOtherMovementCoroutine(foo, bar))
you can transition from one move to another, without the two sets of movement logic overlapping & fighting over the object's transformation. ;)
No comments:
Post a Comment