Final IK學(xué)習(xí)筆記5:Aim IK

AimIK求解器是CCD算法的一種修改,它旋轉(zhuǎn)骨骼層次結(jié)構(gòu)以使子層朝向目標(biāo)。它與基本的內(nèi)置Animator.SetLookAtPosition或LookAtIK功能不同,因?yàn)樗軌驕?zhǔn)確地瞄準(zhǔn)未與層次結(jié)構(gòu)的主軸對(duì)齊的目標(biāo)。

AimIK可以產(chǎn)生非常穩(wěn)定和自然的重新定位角色動(dòng)畫,因此在武器瞄準(zhǔn)系統(tǒng)中具有很大的潛力。通過AimIK,我們可以設(shè)置單個(gè)前向瞄準(zhǔn)姿勢(shì)或動(dòng)畫,以瞄準(zhǔn)目標(biāo)(甚至幾乎在角色后面的目標(biāo))。只有位于180度偏移的四元數(shù)奇點(diǎn),求解器無法知道轉(zhuǎn)向脊柱的方向。就像LookAtIK一樣,AimIK提供了clampWeight屬性,以避免出現(xiàn)奇點(diǎn)問題。

AimIK也適用于旋轉(zhuǎn)限制,但是如果鏈?zhǔn)艿絿?yán)格約束,它比其他受約束的求解器更容易卡住。


AimIK求解器

使用步驟:

  • 設(shè)置角色的Animator/Animation以播放瞄準(zhǔn)前進(jìn)動(dòng)畫/姿勢(shì)
  • 將AimIK組件添加到角色中
  • 將spine骨骼分配給組件中的“ Bones”,逐個(gè)降序排列(父項(xiàng)優(yōu)先)。
  • 指定目標(biāo)Transform(您想要瞄準(zhǔn)目標(biāo)的Transform)。 它可能是槍,手骨或只是手上的空游戲?qū)ο?/li>
  • 確保Axis表示您希望瞄準(zhǔn)目標(biāo)的Aim Transform的局部軸。 例如,如果槍的(z)軸指向它的槍管,則需要將軸設(shè)置為(0,0,1)。
  • 將weight設(shè)置為1,按“Play”
  • 在場(chǎng)景視圖中移動(dòng)目標(biāo)以查看AimIK的更新

組件參數(shù):

  • timeStep - 如果為零,將更新每個(gè)LateUpdate()中的求解器,用于骨骼帶動(dòng)畫時(shí)的情況。 如果大于零,將按頻率更新,以便求解器將在所有對(duì)象上同時(shí)到達(dá)其目標(biāo)。
  • fixTransforms - 如果為true,則將解算器使用的所有Transforms修復(fù)為每個(gè)Update中的初始狀態(tài)。 這可以防止沒有動(dòng)畫骨骼和animator的剔除的問題,并且性能成本很低。

求解參數(shù):

  • target - 目標(biāo)物體。如果已分配,則解算器IKPosition將自動(dòng)設(shè)置為目標(biāo)的位置。
  • poleTarget - 如果已分配,將自動(dòng)將polePosition設(shè)置為此Transform的位置。 IKSolverAim.polePosition使Aim Transform的另一個(gè)軸(poleAxis)朝向IKSolverAim.polePosition。
  • Aim transform - (目標(biāo)變換)我們想要瞄準(zhǔn)IKPosition的變換(通常是槍或手電筒,在上圖中表示為粉紅色圓錐)。
  • axis - 要將目標(biāo)指向IKPosition的Aim Transform的局部坐標(biāo)的軸。例如,如果槍的藍(lán)色(z)軸指向它的槍管,則需要將軸設(shè)置為(0,0,1)。
  • poleAxis - 希望保持面向IKSolverAim.polePosition的Aim Transform的局部坐標(biāo)的軸
  • weight - 混合IK效果的權(quán)重
  • poleWeight - 保持AimTransform的poleAxis朝向polePosition的權(quán)重
  • tolerance - 距離最后到達(dá)角度的最小偏移量。如果與先前達(dá)到的角度的差異小于容差,則將停止求解。如果容差為零,將迭代直到maxIterations。
  • maxIterations - 每幀最大迭代次數(shù)。如果tolerance為0,則將一直迭代直到maxIterations
  • clampWeight - solver的旋轉(zhuǎn)取值。 0是自由旋轉(zhuǎn),1是完全固定到?jīng)]有效果。
  • clampSmoothing - 正弦平滑迭代次數(shù)。
  • bones - 用于將目標(biāo)變換定向到目標(biāo)的骨骼。所有骨骼都需要是Aim Transform的直接父節(jié)點(diǎn),并按降序排序。您可以跳過層次結(jié)構(gòu)中的骨骼,也可以包含Aim Transform本身。骨骼層次結(jié)構(gòu)不能分支,這意味著您無法從雙手分配骨骼。骨骼權(quán)重決定了混合層次結(jié)構(gòu)的強(qiáng)度。


    AimIK組件

腳本參考如下:

改變目標(biāo):

public AimIK aimIK;
void LateUpdate () {
    aimIK.solver.IKPosition = something;
}

使用Pole:
在制作武器瞄準(zhǔn)設(shè)置時(shí),polePosition可能會(huì)有所幫助。 假設(shè)我們有一把槍,局部坐標(biāo)的Z軸朝向它的槍管,局部坐標(biāo)的Y軸朝上。 在這種情況下,我們必須將AimIK的“Axis”設(shè)置為(0,0,1),將“Pole Axis”設(shè)置為(0,1,0)。 如果我們現(xiàn)在播放場(chǎng)景并將“ Weight”和“Pole Weight設(shè)置為1,我們將有2個(gè)控制點(diǎn),一個(gè)用于瞄準(zhǔn)目標(biāo),另一個(gè)用于扭轉(zhuǎn)槍和角色的身體。

通過腳本調(diào)整Pole:

public AimIK aimIK;
void LateUpdate () {
    aimIK.solver.transform = something;
    aimIK.solver.axis = localAxisOfTheTransformToAimAtTheTarget;
}

在運(yùn)行時(shí)添加AimIK:

public AimIK aimIK;
public Transform[] newBones;
void Change() {
    aimIK.solver.SetChain(newBones, aim.transform);
}

使用具有旋轉(zhuǎn)限制的AimIK:
有時(shí)需要限制AimIK對(duì)其鏈中一個(gè)骨骼的影響。 通常當(dāng)您希望在瞄準(zhǔn)單手武器的過程中使用肘關(guān)節(jié)時(shí),或者當(dāng)您希望限制脊椎骨的旋轉(zhuǎn)僅是扭轉(zhuǎn)時(shí)。 如果您剛剛將RotationLimit組件添加到骨骼中,它也會(huì)干擾動(dòng)畫(保持脊柱僵硬),而不僅僅是IK。 您可以通過在AimIK解決之前設(shè)置每幀旋轉(zhuǎn)為默認(rèn)來使RotationLimit對(duì)AimIK產(chǎn)生影響。

public AimIK aimIK;
void LateUpdate() {
    // Set current animated localRotation as default local rotation for the rotation limits so they will not interfere with the animation, but only the IK
    for (int i = 0; i < aimIK.solver.bones.Length; i++) {
        if (aimIK.solver.bones[i].rotationLimit != null) {
            aimIK.solver.bones[i].rotationLimit.SetDefaultLocalRotation();
        }
    }
}

請(qǐng)注意,每個(gè)RotationLimit都會(huì)降低求解器平滑到達(dá)目標(biāo)的概率。
由于FinalIK 0.4引入了polePosition和poleWeight,因此在大多數(shù)情況下,通過使用Pole來保持身體直立,可以避免對(duì)角色使用旋轉(zhuǎn)限制。

骨骼權(quán)重
“Bones”中的每個(gè)骨骼都有一個(gè)權(quán)重參數(shù)。它決定了在求解過程中使用的骨骼的比重。 例如,如果你不希望某個(gè)脊椎骨彎得太多,你可以減輕它的權(quán)重。

雙手武器的瞄準(zhǔn):
當(dāng)使用雙手武器時(shí),我們只能在AimIK骨骼層次結(jié)構(gòu)中使用脊柱骨骼(雙手的共同父節(jié)點(diǎn))。如果我們使用手臂骨骼,另一只手會(huì)松動(dòng)與物體的接觸。有時(shí)只使用脊柱骨骼是不夠的,因?yàn)榧怪鶗?huì)過度彎曲而角色變成不自然的姿勢(shì)。我們可以通過在AimIK上添加一些手臂骨骼(握住物體的手臂),在AimIK完成后,使用FullBodyBipedIK或LimbIK將另一只手放回原位。

重定向動(dòng)畫:
AimIK非常適合保持物體穩(wěn)定地瞄準(zhǔn)目標(biāo)。有時(shí)這些物體在動(dòng)畫中有很多擺動(dòng)動(dòng)作,例如擺動(dòng)劍,并且在揮桿過程中使用AimIK來保持劍定位在某個(gè)位置是不好的。它會(huì)通過彎曲層次結(jié)構(gòu)的其余部分來保持劍的方向,并以不必要的方式干擾動(dòng)畫。仍然可以使用AimIK重定向搖擺動(dòng)畫,如劍術(shù)或拳擊,但是需要一些技巧,可以參考這個(gè)視頻。

在瞄準(zhǔn)時(shí)換武器或者重新加載動(dòng)畫:
當(dāng)AimIK權(quán)重為1時(shí),solver將始終保持武器朝向目標(biāo)。換武器或重新加載動(dòng)畫時(shí),這可能是不必要的。我們可以動(dòng)態(tài)更改AimIK的Axis來克服這個(gè)問題。

void LateUpdate() {
        aimIK.solver.axis = aimIK.solver.transform.InverseTransformDirection(character.forward);
}

通過上面的代碼,無論動(dòng)畫中武器的方向如何,它都是默認(rèn)的前向瞄準(zhǔn)方向。 “Character.forward”是沒有任何后坐力時(shí)武器瞄準(zhǔn)的方向(保持方向在角色空間中以使武器與角色一起旋轉(zhuǎn))。如果你當(dāng)前正在播放“瞄準(zhǔn)右邊”的動(dòng)畫, 你應(yīng)該把它設(shè)置為“character.right”。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容