| 010203040506070809101112131415161718192021 | [/font][/size][/align][align=left][size=4][font=宋體]//在日出和日落之間動畫弧線using UnityEngine;using System.Collections; public class example : MonoBehaviour { publicTransform sunrise; publicTransform sunset; voidUpdate() { //弧線的中心 Vector3 center = sunrise.position + sunset.position * 0.5f; //向下移動中心,垂直于弧線 center -=new Vector3(0, 1, 0); //相對于中心在弧線上插值 Vector3 riseRelCenter = sunrise.position - center; Vector3 setRelCenter = sunset.position - center; transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, Time.time); transform.position += center; }} |
咱們以a和b兩個向量來做插值,假設分10等份,代碼比較簡單,如下代碼[C#] 純文本查看 復制代碼?| 1234 | [/font][/align][align=left][font=宋體] for (inti = 1; i < 10; ++i) { Vector3 drawVec = Vector3.Slerp(a, b, 0.1f * i); Debug.DrawLine(Vector3.zero, drawVec, Color.yellow); } |
但是,你不能被表象所欺騙,這樣的效果雖然可以,但是卻無法控制插值的曲線,也就是那個弧度,雖然你可以調整向量a和向量b的值來調節弧度,比方說a(1,1,0),b(-1,1,0)效果如下,可以看到弧度已經明顯變平很多。
但是我們在實際運用這個函數的時候往往向量a和向量b是固定的,我們想要的是控制這個弧度,那么怎么辦呢,其實也就是改變畫這個弧度的中心點位置。上面兩個示意圖上面中心點我們都是用的坐標原點,我們現在想要在不改變a和a的情況下來改變插值的弧度,就只能自己找出一個中心點,這也就是官方實例中求中心點的由來了。[C#] 純文本查看 復制代碼?| 0102030405060708091011 | [/font][/align][align=left][font=宋體] //弧線的中心 Vector3 center = (a + b) * 0.5f; //我們把中心點向下移動中心,垂直于弧線 center -=new Vector3(0, 0.5f, 0); // 求出新的中心點到向量a和向量b的 Vector3 vecA = a - center; Vector3 vecB = b - center; for(int i = 0; i <= 10; ++i) { Vector3 drawVec = Vector3.Slerp(vecA, vecB, 0.1f * i); Debug.DrawLine(center, drawVec, Color.yellow); } |
(至于為什么要 求出新的中心點到向量a和向量b的vecA和vecB是因為,我們在球形插值的時候要的是兩個vector3,而這個vector3是要向量a和向量b到中心點的向量,如果我們不求出vecA和vecB的話不論你怎么插值,其實都是從坐標原點進行的插值,你是控制不了插值的弧度的。)從上面的效果圖我們可以看到插值出來的弧度開始和結束點并不是a、b兩點,而是這兩個點向下的偏移量,而這個偏移量正好是向量conter的負值,所以我們在求出drawVec之后需要對其做修正處理。在求出drawVec之后加上下面的代碼[C#] 純文本查看 復制代碼?drawVec += center; |
現在的效果圖就是我們想要的插值效果了,要想控制弧度,只用調節centor的偏移量就可以了。比方說我們加上這樣一條center -= newVector3(0, 2f, 0);可以看到效果如下
這個弧度是不是就更平了呢。好,看到現在還沒有睡著的同學們,我只能說一句你們有福了,下面可是大餐哦。上面咱們介紹的都是有局限性的,比方說向量a和向量b對于Y軸可是左右對稱的,并且X,Y軸的值也是相等的,這在實際運用中可是非常不常見的,現在咱們對向量a做一個比較小的改動看看,把向量a改為(2,1,0),那么效果如下所示
哇咔咔,居然還是好好的球形插值啊,哈哈,各位同學別激動,咱們把向量a的Y軸也調整一下看看,把a改為(2,4,0)效果如下圖所示
哇咔咔。。效果是不是非常明顯啊,說好的球形插值呢?怎么成了這個樣子!!哈哈,各位同學別著急啊,咱們這個球形插值和核心其實就是center點的位置,只要我們求的這個center點的位置在a和b連線中心點的垂線上面,那么就是一個完整的左右對稱的插值了。下面咱們加入如下代碼[C#] 純文本查看 復制代碼?| 1 | Vector3 centorPRoject = Vector3.Project(centor, mStart - mEnd);// 中心點在兩點之間的投影 centor = Vector3.MoveTowards(centor, centorProject, 1f);// 沿著投影方向移動移動距離(距離越大弧度越小) |
所以我們完整的運用Vector3.Slerp的代碼應該是這樣子滴[C#] 純文本查看 復制代碼?| 0102030405060708091011121314151617181920 | [/font][/align][align=left][font=宋體]//在日出和日落之間動畫弧線using UnityEngine;using System.Collections; public class example : MonoBehaviour { publicTransform sunrise; publicTransform sunset; voidUpdate() { //弧線的中心 Vector3 center = sunrise.position + sunset.position * 0.5f; Vector3 centorProject = Vector3.Project(centor, sunrise.position - sunset.position);// 中心點在兩點之間的投影 centor = Vector3.MoveTowards(centor, centorProject, 1f);// 沿著投影方向移動移動距離(距離越大弧度越小) //相對于中心在弧線上插值 Vector3 riseRelCenter = sunrise.position - center; Vector3 setRelCenter = sunset.position - center; transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, Time.time); transform.position += center; }} |
哇咔咔。。是不是又出問題了?還需要改代碼?NO!這是因為我們鎖定了視角方向來看的,看上面的2D選項是不是已經選擇了啊,哈哈。那么既然Z軸有值了我們就不能已平面視角來看了,等我們把2D鎖定給關閉了轉換個視角看看。
這樣看是不是就順眼多了呢?哈哈,至此我們的講解總算結束了,大家可以洗洗了,哈哈。。。等下!誰說可以睡了?我可沒說哦,難道大家對我說的都這么信嗎?有句古話說的好啊,盡信書則不如無書。。[C#] 純文本查看 復制代碼?centor = Vector3.MoveTowards(centor, centorProject, 1f);// 沿著投影方向移動移動距離(距離越大弧度越小) |
| 0102030405060708091011121314151617181920212223242526272829 | [/size][/font][/align][align=left][font=宋體][size=14.0pt] private Vector3 mStart =new Vector3(2, 4, -1); privateVector3 mEnd = newVector3(-1, 1, 2); // Update is called once per frame privatevoid Update() { Debug.DrawLine(newVector3(-100, 0, 0), newVector3(100, 0, 0), Color.green); Debug.DrawLine(newVector3(0, -100, 0), newVector3(0, 100, 0), Color.green); Debug.DrawLine(Vector3.zero, mStart, Color.red); Debug.DrawLine(Vector3.zero, mEnd, Color.red); Debug.DrawLine(mStart, mEnd, Color.red); Vector3 centor = (mStart + mEnd) * 0.5f; Vector3 centorProject = Vector3.Project(centor, mStart - mEnd);// 中心點在兩點之間的投影 centor = Vector3.MoveTowards(centor, centorProject, 1f); // 沿著投影方向移動移動距離(距離越大弧度越小) Debug.DrawLine(centor, mStart, Color.blue); Debug.DrawLine(centor, mEnd, Color.blue); Debug.Log(string.Format("{0} : {1}", Vector3.Distance(centor, mStart), Vector3.Distance(centor, mEnd))); for(int i = 1; i < 10; ++i) { Vector3 drawVec = Vector3.Slerp(mEnd - centor, mStart - centor, 0.1f * i); drawVec += centor; Debug.DrawLine(centor, drawVec, 5 == i ? Color.blue : Color.yellow); } } |
新聞熱點
疑難解答