骨架控制節點的基礎類別叫做SkelControlBase,其他的骨架控制節點都會直接或間接繼承自此類別。它定義數個C++虛擬函式以供子類別擴充,以下列出重要的成員:
- GetAffectedBones(BoneIndex, SkeletalMeshComponent, OutBoneIndices):可覆寫此函式傳回要修改的骨頭之索引值。
- CalculateNewBoneTransforms(BoneIndex, SkeletalMeshComponent, OutBoneAtoms):可覆寫此函式傳回修改後的骨頭位置和方向。傳回的陣列必須和GetAffectedBones()相對應。
- CalculateNewBoneScales(BoneIndex, SkeletalMeshComponent, OutBoneScales):可覆寫此函式傳回修改後的骨頭縮放值。傳回的陣列必須和GetAffectedBones()相對應。
- GetBoneScale(BoneIndex, SkeletalMeshComponent):可覆寫此函式傳回此骨架控制的骨頭縮放值。
- TickSkelControl(DeltaSeconds, SkeletalMeshComponent):可覆寫此函式每畫面更新骨架控制節點。
範例
原本SkelControlBase就有提供BoneScale欄位變更縮放值,不過子骨架也會跟著縮放,以下程式碼展示如何自訂一個可以不縮放子骨架的骨架控制節點:
class MySkelControl_Scale extends SkelControlBase native(Anim); var() bool bScaleChildren; cpptext { // SkelControlBase interface virtual void GetAffectedBones(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<INT>& OutBoneIndices); virtual void CalculateNewBoneScales(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FLOAT>& OutBoneScales); }GetAffectedBones()需要一併列出子骨架以便在CalculateNewBoneScales()修改:
void UMySkelControl_Scale::GetAffectedBones(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<INT>& OutBoneIndices) { check( OutBoneIndices.Num() == 0 ); check( SkelComp->SkeletalMesh ); OutBoneIndices.AddItem(BoneIndex); if( ! bScaleChildren && BoneScale > KINDA_SMALL_NUMBER ) { USkeletalMesh* SKelMesh = SkelComp->SkeletalMesh; INT BoneCount = SkelMesh->RefSkeleton.Num(); for(INT i=BoneIndex+1; i<BoneCount; i++) { if( SkelMesh->RefSkeleton(i).ParentIndex = BoneIndex ) { OutBoneIndices.AddItem(i); } } } }將子骨架的縮放值設為倒數,抵消母骨頭的縮放效果:
void UMySkelControl_Scale::CalculateNewBoneScales(INT BoneIndex, USkeletalMeshComponent* SkelComp, TArray<FLOAT>& OutBoneScales) { check( OutBoneScales.Num() == 0 ); check( SkelComp->SkeletalMesh ); // The output array must correspond to the one output by GetAffectedBones(). // The scale of this bone is applied in USkeletalMeshComponent::ApplyControllersForBoneIndex(), // so do not scale it again. OutBoneScales.AddItem(1.f); if( ! bScaleChildren && BoneScale > KINDA_SMALL_NUMBER ) { FLOAT InverseBoneScale = 1.f / BoneScale; USkeletalMesh* SKelMesh = SkelComp->SkeletalMesh; INT BoneCount = SkelMesh->RefSkeleton.Num(); for(INT i=BoneIndex+1; i<BoneCount; i++) { if( SkelMesh->RefSkeleton(i).ParentIndex = BoneIndex ) { OutBoneScales.AddItem(InverseBoneScale); } } } }
沒有留言:
張貼留言