之前簡單講瞭一下怎麼實現自然的Lookat效果。
文章裡提到調整旋轉的策略時,提到“插值旋轉軸”和“限制歐拉角”兩種方法。在限制歐拉角方法的最後一段,因為嘗試調整骨骼節點的自旋轉(local-z),實現瞭一定程度的扭頭效果,當時突發奇想立瞭個旗試試新房45度,這次大半夜花瞭幾個小時嘗試一下效果(當然水文是早上爬起來寫的),就當是拔旗瞭。
雖然願意點進來看的肯定都知道什麼是新房45度(後面的篇幅和代碼裡都會用Shaft角度代指)。不過,這裡還是需要放個圖讓大傢有個直觀的視覺印象。萌娘百科
真正開始寫的時候,才發現原來的扭頭Trick並不足夠完成這種動作。多看幾遍這張動圖,除瞭小焰是比較正常的轉身,其他人的形態歸結起來就是“仰頭側臉看人”;胸腔橫向旋轉和頭部縱向旋轉的比例在小焰和黑儀兩個極端情況之間浮動。
我們姑且歸納這個形態的特性為“旋轉軸有向右後方偏移的傾向”,如此,就可以套用“插值旋轉軸”的方案,從向正上方插值變種為向右後方插值(向左看的時候)。基本內容需要看篇頭的文章鏈接,簡單修改代碼如下:
private void ShaftAngle_LerpAxis(int i, Vector3 forwardDirection, Vector3 lookatDirection,
out bool finish)
{
var config = lookatData.boneConfig[i];
var bone = boneArray[i];
var rotation = Quaternion.FromToRotation(forwardDirection, lookatDirection);
var position = bone.transform.position;
if (config.limitWeight > 0)
{
Vector3 axis;
float angle;
rotation.ToAngleAxis(out angle, out axis);
var isLookRight = Vector3.Cross(forwardDirection, lookatDirection).y > 0;
//改這個旋轉軸就成瞭
Vector3 normal = new Vector3(isLookRight ? -1 : 1, 0 , 1).normalized;
var newAxis = Vector3.Lerp(axis, normal, config.limitWeight);
var newAngle = Mathf.Min(angle - Vector3.Angle(axis, newAxis), config.limitAngle);
var lookRotation = Quaternion.AngleAxis(newAngle, newAxis);
bone.transform.rotation = lookRotation * bone.transform.rotation;
finish = false;
}
else
{
var lookRotation = rotation;
bone.transform.rotation = lookRotation * bone.transform.rotation;
finish = true;
}
}
6月10日,是我國香港樂壇傑出的音樂人黃傢駒的生日,為瞭紀念這位天才,我在這裡將我的油畫連環畫代表作《光輝歲月—beyond樂...
PDU(Power Distribution Unit),是將來自UPS的輸出電流分配到各個IT設備的末端配電設備,是連接供電等基礎設施與IT系統、關...