
向量的叉乘:
数学运算:a(ax,ay,az) x b(bx,by,bz) = c(aybz-azby,azbx-axby,axby-aybx)

几何意义:得到一个新的向量,同时垂直于a向量和b向量,垂直于ab向量所组成的平面,c向量是ab平面的法向量
左手螺旋定则:四指指向a,握向b,大拇指指向c
作用
1、求顺指针,逆时针关系(y>0,y<0)
2、求平面的法向量
四元数(威廉·哈密顿):
万向节死锁(Gimbal Lock):
四元数和欧拉角的优缺点:
欧拉角缺点:万向节死锁 http://v.youku.com/v_show/id_XNzkyOTIyMTI=.html
四元数:xyzw四个分量,w为实部
超复数:是由一个实部 + 三个虚部组成的,如4 + 2i + 3j + 4k
复数:实部 + 虚部,如3 + 2i,5 - 3i。复数的实部为零,即为虚数;虚部为零,即为实数。
----虚数:如果一个数的平方等于负一,那么这个数就是虚数单位,如x^2 = -1,3i,10k,9j
----实数:有理数和无理数的集合
--------有理数:有限的或者无限循环的,如1/3
--------无理数:无限不循环的小数,如PI,e,根号2
四元数中存储的是轴角对儿<n(x,y,z), theta>
x = n.x * sin(theta/2)
y = n.y * sin(theta/2)
z = n.z * sin(theta/2)
w = cos(theta/2)
比如:绕着y轴旋转90度:Quaternion(0,0.707,0,0.707)
1、我们用乘法来表示四元数的旋转量的叠加
欧拉角和四元数互转
public static Quaternion Euler(Vector3 euler);
public static Quaternion Euler(float x, float y, float z);
public static Quaternion LookRotation(Vector3 forward);
public static Quaternion LookRotation(Vector3 forward, [DefaultValue("Vector3.up")] Vector3 upwards);
插值:from + (to - from) * t
线性插值:
public static Vector3 Lerp(Vector3 a, Vector3 b, float t);
a:from是起始的位置
b:to是目标位置
t:在from到to之间插值
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LerpTest : MonoBehaviour
{
public Transform sphere;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
//API:Vector3.Lerp,线性插值,起始位置from,目标位置to,每次插剩余距离(from-to)的百分之多少t
transform.position = Vector3.Lerp(transform.position, sphere.position, 0.05f);
//Lerp的匀速移动
transform.position = Vector3.Lerp(transform.position, sphere.position, /Vector3.Distance(transform.position,sphere.position) * 0.05F);
//Lerp的匀速旋转
//API:Mathf.Lerp();
}
}
判断方位
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyLookPlayer : MonoBehaviour {
public Transform player;
public float result1;
public float result2;
// Use this for initialization
void Start () {
Vector3 forwardVector = transform.forward;
Vector3 enemy2Player = player.position - transform.position;
//result1 = enemy2Player.x * forwardVector.x + enemy2Player.y * forwardVector.y + enemy2Player.z + forwardVector.z;
result1 = Vector3.Dot(forwardVector, enemy2Player);
Vector3 result = Vector3.Cross(forwardVector, enemy2Player);
result2 = result.y;
} // Update is called once per frame
void Update () { }
public void OnGUI()
{
if (result1 > )
{
if (result2 > )
{
GUILayout.Label("玩家在我的方位:右前方");
}
else
{
GUILayout.Label("玩家在我的方位:左前方");
}
}
else
{
if (result2 > )
{
GUILayout.Label("玩家在我的方位:右后方");
}
else
{
GUILayout.Label("玩家在我的方位:左后方");
}
} }
}
路点移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FindPath : MonoBehaviour {
public Transform[] paths;
public Vector3 dir;
public float moveSpeed;
public float rotSpeed;
int index = ;
// Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
if (Vector3.Distance(paths[index].position, transform.position) <= 0.5f)
{
index++;
index %= paths.Length;
}
dir = paths[index].position - transform.position;
transform.Translate(dir *Time.deltaTime* moveSpeed,Space.World);
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation,/ Quaternion.Angle(transform.rotation, targetRotation)* rotSpeed);
}
}
用单例类来管理路点
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PathManager : MonoBehaviour {
//用单例类来管理路点
public static PathManager instanse = null;
public static PathManager Instanse
{
get
{
return instanse;
}
}
int index = ;
void Awake()
{
instanse = this;
}
// Use this for initialization
void Start () {
//transform.GetChild(1);
}
// Update is called once per frame
void Update () { }
public Vector3 GetCurrentPos()
{
return transform.GetChild(index).position;
}
public bool IsReached(Vector3 targetPos)
{
Vector3 currPos = GetCurrentPos();
//忽略路点的高度
currPos.y = targetPos.y;
//根据步径调整0.5f的值
return Vector3.Distance(currPos, targetPos) < 0.5f;
}
public void MoveNext()
{
index++;
//index = index % transform.childCount;
index %= transform.childCount;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class QuaternionTest : MonoBehaviour
{
public Transform girl;
// Use this for initialization
void Start()
{
//把旋转量赋值给transform.rotation
transform.rotation = new Quaternion(, Mathf.Sin( * Mathf.Deg2Rad), , Mathf.Cos( * Mathf.Deg2Rad));
//用乘法表示旋转量叠加
transform.rotation *= new Quaternion(, Mathf.Sin( * Mathf.Deg2Rad), , Mathf.Cos( * Mathf.Deg2Rad)); //API:Quaternion.AngleAxis,输入轴角对儿,返回四元数,如绕着y轴旋转90度
transform.rotation = Quaternion.AngleAxis(, Vector3.up);
//用乘法表示旋转量叠加,先绕着y轴旋转45度,再绕着y轴旋转90度,结果是-225(135)
transform.rotation = Quaternion.AngleAxis(, Vector3.up) * Quaternion.AngleAxis(, Vector3.up); //四元数不满足乘法交换律
//先绕着y轴旋转45度,再绕着x轴旋转45度,结果是(45,45,0)
transform.rotation = Quaternion.AngleAxis(, Vector3.up) * Quaternion.AngleAxis(, Vector3.right);
//先绕着x轴旋转45度,再绕着y轴旋转45度
transform.rotation = Quaternion.AngleAxis(, Vector3.right) * Quaternion.AngleAxis(, Vector3.up);
}
// Update is called once per frame
void Update()
{
//API:Quaternion LookRotation(Vector3 forward);
Vector3 dir = girl.position - transform.position;
//transform.rotation = Quaternion.LookRotation(dir);
//目标位置
Quaternion targetRotation = Quaternion.LookRotation(dir);
//Slerp球形插值,每次0.01f慢慢插
//transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 0.01f);
//
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, / Quaternion.Angle(transform.rotation, targetRotation));
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public float moveSpeed = ;
public float rotSpeed = ;
public float radius = ;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 targetPos = PathManager.Instanse.GetCurrentPos();
Vector3 moveDir = targetPos - transform.position;
moveDir.y = ;
//目标与主角y值一致
targetPos.y = transform.position.y;
//移动
transform.position = Vector3.Lerp(transform.position, targetPos, / Vector3.Distance(transform.position, targetPos) * moveSpeed);
//旋转
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(moveDir), / Quaternion.Angle(transform.rotation, Quaternion.LookRotation(moveDir)) * rotSpeed);
//画线
Debug.DrawLine(transform.position, targetPos, Color.green);
//判断是否达到
if (PathManager.Instanse.IsReached(transform.position))
{
PathManager.Instanse.MoveNext();
}
}
private void OnDrawGizmos()
{
Gizmos.color = new Color(, , , 0.3f);
Gizmos.DrawSphere(transform.position, radius);
}
}
补充内容
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class w06d3 : MonoBehaviour {
public Transform target;
public Transform cam;
public Vector3 camerPosOffset;
public float hOffset;
public float moveSpeed = ;
// 1、向量加法的几何意义
// 2、向量减法的几何意义
// 3、向量的点乘的几何意义
// a.b = a.x * b.x + a.y * b.y + a.z * b.z
// a.b = |a| * |b| * cos<a, b>
// a.b = (|b| * cos<a, b>) * |a|
// a.b = (|a| * cos<a, b>) * |b| a向量在b向量上的投影长度 * b向量的模长
// b是单位向量的话, a向量在b向量上的投影长度
// a、b 都是单位向量的话,两个向量的夹角的余弦值
void Start () { if( Vector3.Angle(transform.forward, target.position - transform.position) < )
{
}
} void Update () {
cam.position = transform.position + camerPosOffset;
cam.LookAt(transform.position + Vector3.up * hOffset);
transform.Translate((target.position - transform.position).normalized * moveSpeed * Time.deltaTime, Space.World); }
private void OnTriggerEnter(Collider other)
{ }
private void OnCollisionEnter(Collision collision)
{ }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pool<T> where T : UnityEngine.Object
{
public readonly int Capacity = ;
List<T> items = new List<T>();
public Pool(int capacity = )
{
this.Capacity = capacity;
}
public bool Push(T item)
{
if (items.Count >= Capacity - ) return false;
items.Add(item); return true;
}
public T Pop()
{
if (items.Count == ) return default(T);
T item = items[items.Count - ];
items.RemoveAt(items.Count - );
return item;
}
}