Last active
April 25, 2017 16:46
-
-
Save jirevwe/b36174d88e30ac067726bb2ad80b6099 to your computer and use it in GitHub Desktop.
Script for Barrel Roll... Explains how to use Unity3d's Quaternion.Slerp (Use a Coroutine instead)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Collections; | |
using System.Linq; | |
using UnityEngine; | |
public class Player : MonoBehaviour { | |
[SerializeField] | |
float flippedTime = 0f; | |
float startFlip = 0f; | |
[SerializeField] | |
float acceleration = 1f; | |
[SerializeField] | |
bool here = false; | |
[SerializeField] | |
float rotate = 0f; | |
List<Cannon> cannons = new List<Cannon>(); | |
Quaternion startRotation = Quaternion.identity; | |
Vector3 flipVector = Vector3.zero; | |
void Start () { | |
cannons = GetComponentsInChildren<Cannon>().ToList(); | |
} | |
void Update () { | |
transform.Translate (Vector3.right * acceleration, Space.Self); | |
if (Input.GetKey (KeyCode.LeftArrow)) { | |
transform.rotation *= Quaternion.AngleAxis(-rotate * Time.deltaTime, Vector3.forward); | |
} | |
else if(Input.GetKey (KeyCode.RightArrow)){ | |
transform.rotation *= Quaternion.AngleAxis(rotate * Time.deltaTime, Vector3.forward); | |
} | |
if(Input.GetKey(KeyCode.Space)){ | |
foreach(var cannon in cannons){ | |
if(cannon.currentFireTime >= cannon.fireRate) | |
cannon.Fire(); | |
} | |
} | |
if(flippedTime >= 1f && !here){ | |
here = true; | |
var rotation = transform.localEulerAngles; | |
rotation.x += 180f; | |
rotation.z *= -1f; | |
StartRotate(rotation); | |
} | |
} | |
// Rotate the object from it's current rotation to "newRotation" over "duration" seconds | |
void StartRotate(Vector3 newRotation, float duration = 0.5f) { | |
if (SlerpRotation != null) // if the rotate coroutine is currently running, so let's stop it and begin rotating to the new rotation. | |
StopCoroutine(SlerpRotation); | |
SlerpRotation = Rotate(newRotation, duration); | |
StartCoroutine(SlerpRotation); | |
} | |
void LateUpdate(){ | |
//rotate | |
if(GetQuadrant(transform.localEulerAngles.z) == 2 || GetQuadrant(transform.localEulerAngles.z) == 3){ | |
flippedTime = Time.timeSinceLevelLoad - startFlip; | |
}else{ | |
flippedTime = 0f; | |
startFlip = Time.timeSinceLevelLoad; | |
} | |
} | |
IEnumerator SlerpRotation = null; | |
IEnumerator Rotate(Vector3 newRotation, float duration) { | |
Quaternion startRotation = transform.rotation; // You need to cache the current rotation so that you aren't slerping from the updated rotation each time | |
Quaternion endRotation = Quaternion.Euler(newRotation); | |
for (float elapsed = 0f; elapsed < duration; elapsed += Time.deltaTime) { | |
float t = elapsed / duration; // This is the normalized time. It will move from 0 to 1 over the duration of the loop. | |
transform.rotation = Quaternion.Slerp(startRotation, endRotation, t); | |
yield return null; | |
} | |
flippedTime = 0f; here = false; | |
transform.rotation = endRotation; // finally, set the rotation to the end rotation | |
SlerpRotation = null; // Clear out the IEnumerator variable so we can tell that the coroutine has ended. | |
} | |
float GetQuadrant(float angle){ | |
if (angle <= 90){ | |
return 1; | |
}else if (angle > 90 && angle <= 180){ | |
return 2; | |
} | |
else if (angle > 180 && angle <= 270){ | |
return 3; | |
} | |
else if (angle > 270){ | |
return 4; | |
} | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment