[UE4]逻辑状态机组件

来源:互联网 发布:visio mac 官方中文版 编辑:程序博客网 时间:2024/06/11 06:08

逻辑状态机

为了实现对目标状态的控制,以及广播改变状态后的事件,可在蓝图中继续处理不同状态下的行为。

实现过程:

1.继承ActorComponent实现LogicStateMachine;

2.被击中时触发设置状态;

3.状态进入/退出时触发事件。

主要代码

LogicStateMachine.h

/**author : Jia Zhipeng*class : LogicStateMachine*///use enum metadata to save priorityUENUM(BlueprintType)enum LogicStateEnum{LS_Default = 0 UMETA(DisplayName = "Default", Priority = 1),LS_FrozenUMETA(DisplayName = "Frozen", Priority = 1),LS_Fly UMETA(DisplayName = "Fly", Priority = 1),LS_OnGround UMETA(DisplayName = "OnGround", Priority = 1),LS_Faint UMETA(DisplayName = "Faint", Priority = 1),LS_BackUMETA(DisplayName = "Back", Priority = 1),LogicStateNum  UMETA(Hidden),};DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FChangeStateSignature, LogicStateEnum, LogicState);UCLASS(ClassGroup = LogicState, meta = (BlueprintSpawnableComponent), ShowCategories = (LogicState))class CLIENT_API ULogicStateMachine : public UActorComponent{GENERATED_UCLASS_BODY()public://After during time, state will be reset to default.UFUNCTION(BlueprintCallable, Category = LogicStateMachine)bool SetState(LogicStateEnum NewState, float DuringTime=1.0f);//Event used in BPUPROPERTY(BlueprintAssignable, Category = LogicStateMachine)FChangeStateSignature OnEnterLogicState;UPROPERTY(BlueprintAssignable, Category = LogicStateMachine)FChangeStateSignature OnRefreshLogicState;UPROPERTY(BlueprintAssignable, Category = LogicStateMachine)FChangeStateSignature OnExitLogicState;virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;virtual void OnRegister() override;float GetElapsedTime() { return ElapsedTime; }void SetElapsedTime(float Time) {ElapsedTime = Time;}private:LogicStateEnum CurrentState;//On currentState timefloat ElapsedTime;//after this time, it will be reset to Defaultfloat ResetToDefaultTime;};

LogicStateMachine.cpp

/**author : Jia Zhipeng*class : LogicStateMachine*///主要改变状态代码bool ULogicStateMachine::SetState(LogicStateEnum NewState, float DuringTime){int NewStatePriority = 0;int CurrentStatePriority = 0;const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("LogicStateEnum"), true);FString str = EnumPtr->GetMetaData(TEXT("Priority"), CurrentState);if (!str.IsEmpty())CurrentStatePriority = FCString::Atoi(*str);str = EnumPtr->GetMetaData(TEXT("Priority"), NewState);if (!str.IsEmpty())NewStatePriority = FCString::Atoi(*str);//根据优先级判断是否改变/刷新状态if ( (NewState != LogicStateEnum::LS_Default) && (NewStatePriority<CurrentStatePriority))return false;//Time recordElapsedTime = 0;ResetToDefaultTime = DuringTime;//状态相同则刷新,不同则退出旧状态,进入新状态if (NewState == CurrentState)OnRefreshLogicState.Broadcast(CurrentState);if (NewState != CurrentState){OnExitLogicState.Broadcast(CurrentState);}CurrentState = NewState;OnEnterLogicState.Broadcast(CurrentState);return true;}


蓝图使用

添加LogicStateMachine组件后,选中组件添加相关触发事件:



击中时改变目标Actor的状态:



进入相应状态改变后的行为:如击飞,击退。



0 0
原创粉丝点击