欧拉角
优点
缺点
万向节死锁
EulerDemo.cs
using UnityEngine;
using System.Collections;
/// <summary>
///
/// </summary>
public class EulerDemo : MonoBehaviour
{
public Vector3 euler;
private void OnGUI()
{
euler = transform.eulerAngles;
if (GUILayout.RepeatButton("沿X轴旋转"))
{
//Vector3 euler = transform.eulerAngles;
//欧拉角 没有 方向 和 大小的概念。
//x y z 沿某个轴的旋转角度
transform.eulerAngles += new Vector3(1, 0, 0);
}
if (GUILayout.RepeatButton("沿Y轴旋转"))
{
transform.eulerAngles += Vector3.up;
}
if (GUILayout.RepeatButton("沿Z轴旋转"))
{
transform.eulerAngles += Vector3.forward;
}
}
}
四元数
基本运算
优点
缺点
常用API
QuaternionDemo.cs
using UnityEngine;
using System.Collections;
/// <summary>
///
/// </summary>
public class QuaternionDemo : MonoBehaviour
{
private void Start()
{
//物体沿Y轴旋转50度
Vector3 axis = Vector3.up;
float rad = 50 * Mathf.Deg2Rad;
Quaternion qt = new Quaternion();
qt.x = Mathf.Sin(rad / 2) * axis.x;
qt.y = Mathf.Sin(rad / 2) * axis.y;
qt.z = Mathf.Sin(rad / 2) * axis.z;
qt.w = Mathf.Cos(rad / 2);
//transform.rotation = qt;
transform.rotation = Quaternion.Euler(0, 50, 0);
Debug.Log(transform.eulerAngles);
}
//计算
private void OnGUI()
{
if (GUILayout.RepeatButton("沿X轴旋转"))
{
transform.rotation *= Quaternion.Euler(1, 0, 0);
//transform.Rotate(1, 0, 0); //Rotate通过四元数实现
}
if (GUILayout.RepeatButton("沿Y轴旋转"))
{
transform.rotation *= Quaternion.Euler(0, 1, 0);
}
if (GUILayout.RepeatButton("沿Z轴旋转"))
{
transform.rotation *= Quaternion.Euler(0, 0, 1);
}
}
private void Update()
{
Demo01();
}
}
QuaternionAPI.cs
using UnityEngine;
using System.Collections;
/// <summary>
///
/// </summary>
public class QuaternionAPI : MonoBehaviour
{
private void Start()
{
Quaternion qt = transform.rotation;
//1. 四元数 --> 欧拉角
Vector3 euler = qt.eulerAngles;
//2.欧拉角 --> 四元数
Quaternion qt02 = Quaternion.Euler(0, 90, 0);
//3.轴 / 角 旋转
//transform.rotation = Quaternion.AngleAxis(30, Vector3.up);
//transform.localRotation = Quaternion.AngleAxis(30, Vector3.up);
}
public Transform target;
private void Update()
{
//4. 注视旋转
//Quaternion dir = Quaternion.LookRotation(target.position - transform.position);
//transform.rotation = dir;
//transform.LookAt(target.position);
//5.Lerp 差值旋转 由快到慢
//transform.rotation = Quaternion.Lerp(transform.rotation, dir, 0.1f);
//6.RotateTowards 匀速旋转
//transform.rotation = Quaternion.RotateTowards(transform.rotation, dir, 0.1f);
//Quaternion dir = Quaternion.Euler(0, 180, 0);
//transform.rotation = Quaternion.Lerp(transform.rotation, dir, 0.005f);
////7. 四元数计算角度差
//if (Quaternion.Angle(transform.rotation, dir) < 30)
// transform.rotation = dir;
//8. 从?到?的旋转
transform.rotation = Quaternion.FromToRotation(Vector3.right, target.position - transform.position);
}
}
练习一:计算物体右前方30度10m处坐标
向量法
//练习
private void Demo07()
{
//计算:前右方30度 10米处世界坐标
Vector3 localPos = new Vector3
(
10 * Mathf.Sin(30 * Mathf.Deg2Rad),
0,
10 * Mathf.Cos(30 * Mathf.Deg2Rad)
);
//TransformPoint()将点从自身坐标系转换到世界坐标系,在自身坐标系中物体自身就是原点
Vector3 worldPos = transform.TransformPoint(localPos);
Debug.DrawLine(transform.position, worldPos);
}
四元数法
private void Demo01()
{
//计算物体右前方30度10m处坐标
Vector3 worldPos =
transform.position + Quaternion.Euler(0, 30, 0) * transform.rotation * new Vector3(0, 0, 10);
Debug.DrawLine(transform.position, worldPos);
}
练习二:计算炸弹范围的判定(切点Demo)
using UnityEngine;
using System.Collections;
/// <summary>
/// 切点探测器
/// </summary>
public class TangentDetector : MonoBehaviour
{
private Vector3 leftTangent;
private Vector3 rightTangent;
private Transform playerTF;
private float radius;
private void Start()
{
GameObject playerGO = GameObject.FindWithTag("Player");
if (playerGO != null)
{
playerTF = playerGO.transform;
radius = playerGO.GetComponent<CapsuleCollider>().radius;
}
else
{
this.enabled = false;
}
}
public void CalaculateTangent()
{
Vector3 playerToExplosion = transform.position - playerTF.position;
Vector3 playerToExplosionRadius = playerToExplosion.normalized * radius;
float angle = Mathf.Acos(radius / playerToExplosion.magnitude) * Mathf.Rad2Deg;
rightTangent =playerTF .position + Quaternion.Euler(0, angle, 0) * playerToExplosionRadius;
leftTangent = playerTF.position + Quaternion.Euler(0, -angle, 0) * playerToExplosionRadius;
}
//**************测试**************
private void Update()
{
CalaculateTangent();
Debug.DrawLine(transform.position, leftTangent);
Debug.DrawLine(transform.position, rightTangent);
}
}
练习三:根据用户输入的方向旋转角色,并向前移动
重点->vector3.forward和transform.forward的区别
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
///
/// </summary>
public class CharcterMoto : MonoBehaviour
{
public float moveSpeed = 10;
public float rotateSpeed = 10;
private void Update()
{
float RL = Input.GetAxis("Horizontal");
float UD = Input.GetAxis("Vertical");
if (RL != 0 || UD != 0)
RotateView(RL, UD);
}
private void RotateView(float RL, float UD)
{
//创建一个向量,注视旋转,让自身的z轴对着这个向量。
Quaternion dir = Quaternion.LookRotation(new Vector3(RL, 0, UD));
//transform.rotation = dir;
//Lerp的使用,使得旋转更加自然。
transform.rotation = Quaternion.Lerp(transform.rotation, dir, rotateSpeed * Time.deltaTime);
//方法一:
transform.position += transform.forward * moveSpeed * Time.deltaTime;
//方法二:
//Translate中默认是移动被应用相对于自身轴,简单来说默认物体相对于自身向某方向移动多少距离,若规定Space.World则是相对于世界坐标。
//transform.Translate(0, 0, moveSpeed * Time.deltaTime);
//方法三
//transform.Translate(transform.forward * Time.deltaTime * moveSpeed, Space.World);
}
}