csharp Barrel Roll的脚本...解释如何使用Unity3d的Quaternion.Slerp(使用Coroutine代替)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp Barrel Roll的脚本...解释如何使用Unity3d的Quaternion.Slerp(使用Coroutine代替)相关的知识,希望对你有一定的参考价值。

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;
	}
}

以上是关于csharp Barrel Roll的脚本...解释如何使用Unity3d的Quaternion.Slerp(使用Coroutine代替)的主要内容,如果未能解决你的问题,请参考以下文章

Roll A Ball

飞控姿态解算中,欧拉角与四元数之间的转换

csharp Zip解压缩

Unity-2017.2官方实例教程Roll-a-ball

csharp 用于找到斐波纳契数列的迭代解的示例。从计算机编程基础与C#http://www.introprogr

csharp 用于找到斐波纳契数列的迭代解的示例。从计算机编程基础与C#http://www.introprogr