找回密码
 立即注册
查看: 481|回复: 0

Unreal IGameFrameworkInitStateInterface

[复制链接]
发表于 2023-3-23 11:33 | 显示全部楼层 |阅读模式
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
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 16:14 , Processed in 0.089904 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表