變形節點的基礎類別叫做MorphNodeBase,其他的變形節點都會直接或間接繼承自此類別。它定義數個C++虛擬函式以供子類別擴充,以下列出重要的成員:
- NodeName [name] :使用者可自行定義的節點名稱。可以呼叫SkeletalMeshComponent的FindMorphNode()函式找到指名的變形節點。
- InitMorphNode(SkeletalMeshComponent) :動畫樹會呼叫此函式初始化變形節點。
- GetNodes(TArray<UMorphNodeBase*>& OutNodes):列出此節點和其下所有節點。
- GetActiveMorphs(TArray<FActiveMorph>& OutMorphs):列出以此節點算起子樹的所有節點裡,作用中的變形目標和其權重。
每個SkeletalMeshComponent會複製一份專用的動畫樹,所以即使許多模型使用同一個動畫樹範本,像是變形節點權重這種每個實例都要另記一份的資料,還是可以直接存放在變形節點上。大部分變形節點的功能是由C++實作,所以沒有原始碼授權的UDK使用者很難去擴充節點。
範例
以下程式碼展示如何自訂一個會隨生命值減少增加權重的變形節點:
class MyMorphNodeWeightByHealth extends MorphNodeWeightBase
native(Anim);
cpptext
{
// MorphNodeBase interface
virtual void GetActiveMorphs( TArray<FActiveMorph>& OutMorphs );
}
defaultproperties
{
NodeConns(0)=(ConnName=In)
}
先利用生命值計算目前權重,然後乘進子樹裡:
void UMyMorphNodeWeightByHealth::GetActiveMorphs( TArray<FActiveMorph>& OutMorphs )
{
FLOAT NodeWeight = 0.f;
// The weight is the ratio of current health to max health.
if( SkelComponent )
{
APawn* Pawn = Cast<APawn>( SkelComponent->GetOwner() );
if( Pawn && Pawn->HealthMax > KINDA_SMALL_NUMBER )
{
NodeWeight = Clamp( FLOAT(Pawn->HealthMax - Pawn->Health) / Pawn->HealthMax, 0.f, 1.f );
}
}
check( NodeConns.Num() == 1 );
FMorphNodeConn& Conn = NodeConns(0);
TArray<FActiveMorph> Morphs;
for(INT i=0; i<Conn.ChildNodes.Num(); i++)
{
if( Conn.ChildNodes(i) )
{
Morphs.Empty();
Conn.ChildNodes(i)->GetActiveMorphs(Morphs);
for(INT j=0; j<Morphs.Num(); j++)
{
OutMorphs.AddItem(FActiveMorph( Morphs(j).Target, Morphs(j).Weight * NodeWeight ));
}
}
}
}
沒有留言:
張貼留言