|
IGameFrameworkInitStateInterface位于Unreal ModularGameplay插件中,用于解决当obj 初始化时的状态时序关系问题,比如一个obj在初始化前必须要求另一个obj达到某个状态。就可以用这个来保证,改接口在Lyra项目中被用于进行角色PawnExtensionComp和HeroComp的初始化同步。
下面是一些使用注意事项:
1.需要给相关依赖的所有obj实现以下东西:
给需要实现init状态时序需求的object继承IGameFrameworkInitStateInterface接口 完成一个由Tag构成的状态链,用于标识obj已经初始化到什么程度了 实现接口GetFeatureName(),用于描述这个时序需求的依赖类(通常为UObject)的Feature名称,这里注意即使同一个Feature的不同模块依然需要标记为不同的名字,因为OnActorInitStateChanged回调是依据Feature名的状态变化来发送的。相对应的BindOnActorInitStateChanged时输入的Feature名称应该是其依赖模块/Obj的那个Feature名字。 实现接口CanChangeInitState(),用于判断不同状态Tag是否可以切换到下一个状态,可以自己实现一些条件,如果需要实现依赖则可以使用。默认为true,所以如果该obj不需要依赖其他obj则无需实现。
//关键函数
UGameFrameworkComponentManager->HasFeatureReachedInitState();
//该函数接受Actor,一个Feature name和一个state tag,用于判断这个Actor的这个Feature是否达到该状态。
实现接口HandleChangeInitState(),根据current和next实现,状态转换时所需要的逻辑,如果不需要则可以不实现。 实现接口OnActorInitStateChanged(Param),等待回调,一般会根据参数Param判断是否达到某个状态,如果达到推荐调用CheckDefaultInitialization继续ContinueInitStateChain(),这里如果未bind是不会回调回来的。所以需要给有依赖的obj实现BindOnActorInitStateChanged 实现接口CheckDefaultInitialization(),将Tag构成的状态链传入并调用ContinueInitStateChain()
2.Object在OnRegister()时调用RegisterInitStateFeature(); 这里UGameFrameworkComponentManager会调用RegisterFeatureImplementer注册这个Object所属的Actor(或者它本身如果它是Actor的话),原理是UGameFrameworkComponentManager维护了一个Map用于存储所有注册Actor,Obj和他们的Status的对应关系。
/** Actors that were registered as tracking feature state */
TMap<FObjectKey, FActorFeatureData> ActorFeatureMap;
struct FActorFeatureData
{
/** Actor class for cross referencing with the class callbacks */
TWeakObjectPtr<UClass> ActorClass;//存了注册Actor的Class
/** All active features */
TArray<FActorFeatureState> RegisteredStates;
/** All delegates bound to this actor */
TArray<FActorFeatureRegisteredDelegate> RegisteredDelegates;
};
/** State for a specific object implementing an actor feature, should this be in a map instead of an array? */
struct FActorFeatureState
{
FActorFeatureState(FName InFeatureName) : FeatureName(InFeatureName) {}
/** The feature this is tracking */
FName FeatureName;
/** The state when it was last registered */
FGameplayTag CurrentState;
/** The object implementing this feature, this can be null */
TWeakObjectPtr<UObject> Implementer;
};
FObjectKey是基于Actor生成的Key:FObjectKey(Actor)
3.BeginPlay的时候 调用BindOnActorInitStateChanged绑定回调,第一个参数为你需要依赖的Object的Feature名。可以绑定多个。 之后Manager会调用RegisterAndCallForActorInitState为Interface的成员ActorInitStateChangedHandle保存其他Obj实现的OnActorInitStateChanged回调。 调用TryToChangeInitState,传入InitState_Spawned即最初始状态,通告大家你已经spawn出来了。 之后调用重写的CheckDefaultInitialization(包含状态转换链),Manager会调用ContinueInitStateChain并给入你的链。
4.ContinueInitStateChain,会根据你目前的State调用CanChangeInitState判断是否可以进入下一个State 如果可以,则调用HandleChangeInitState,实现状态转换的逻辑,并实现状态转换,之后Manager会调用ChangeFeatureInitState实现状态转换。并更新CurrentState到下一个状态。继续判断是否能进入下一个状态。 如果不可以,则BeginPlay结束。等待OnActorInitStateChanged回调回来继续ContinueInitStateChain |
|