骨架控制節點的基礎類別叫做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);
}
}
}
}
沒有留言:
張貼留言