1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | using System.Collections; using System.Collections.Generic; using UnityEngine; // Author: 半夜逃避自己該做的東西其實自己已經火燒屁股的S🐺 // p.s. 我沒有twitter,去google找的話找到的不是我嘿 // 但是我還真的有用S🐺的名義活動,運氣好的話在世界的某處也許可以捕捉到我吧(ry public class RelativeVelocityDemo : MonoBehaviour { #region Unity Methods private void Update() { if (Input.GetKeyDown(KeyCode.W)) Translate(Vector3.forward); if (Input.GetKeyDown(KeyCode.S)) Translate(Vector3.back); if (Input.GetKeyDown(KeyCode.D)) Translate(Vector3.right); if (Input.GetKeyDown(KeyCode.A)) Translate(Vector3.left); if (Input.GetKeyDown(KeyCode.Space)) Translate(Vector3.up); if (Input.GetKeyDown(KeyCode.LeftShift)) Translate(Vector3.down); if (Input.GetKeyDown(KeyCode.LeftControl)) Translate(new Vector3(Random.Range(0f, 10f), Random.Range(0f, 10f), Random.Range(0f, 10f))); } #endregion #region Methods /// <summary> /// 假定上一個frame我進行了某種形式的位移 /// </summary> /// <param name="v">實際的位移量</param> void Translate(Vector3 v) { var lastPos = transform.position; var lastRot = transform.rotation; transform.Translate(v, Space.Self); //進行位移 var nowPos = transform.position; var nowRot = transform.rotation; Debug.LogFormat("Original transform velocity: {0}", v); Debug.LogFormat("lastPos: {0}, lastRot: {1}, nowPos:{2}, nowRot:{3}", lastPos, lastRot, nowPos, nowRot); Vector4 dv = nowPos - lastPos; //其實是Vector3,但是直接轉成Vector4來用 Vector4 lastForward = lastRot * Vector3.forward; Vector4 lastUp = lastRot * Vector3.up; Vector4 lastRight = lastRot * Vector3.right; // 最後一個是V4(0, 0, 0, 1)是基於矩陣運算的特性決定的,不這樣的話會什麼都算不出來 Matrix4x4 matrix = new Matrix4x4(lastRight, lastUp, lastForward, new Vector4(0, 0, 0, 1)); //這個如果算不出來他會給你0就是了,要小心(但理論上應該不會算不出來就是了) //利用矩陣特性Ax = y => A^-1 * y = x來求解的做法 //為什麼可以這樣做去查反(逆)矩陣的特性吧 Vector3 relativeVelocity = matrix.inverse * dv; //其實算出來是Vector4,但是轉型回Vector3(因為w沒有用到也沒有意義) //Debug.LogFormat("Vr: {0}, Vu: {1}, Vf{2}", lastRight, lastUp, lastForward); Debug.LogFormat("dv: {0}", dv); //Debug.LogFormat("matrix: \n{0}\ninverse: \n{1}", matrix, matrix.inverse); Debug.LogFormat("Relative Velocity {0}", relativeVelocity); //這應該就是你要的東西了 } #endregion } |
Direct link: https://paste.plurk.com/show/2593144