逻辑状态机
为了实现对目标状态的控制,以及广播改变状态后的事件,可在蓝图中继续处理不同状态下的行为。
实现过程:
1.继承ActorComponent实现LogicStateMachine;
2.被击中时触发设置状态;
3.状态进入/退出时触发事件。
主要代码
LogicStateMachine.h
- /*
- *author : Jia Zhipeng
- *class : LogicStateMachine
- */
- //use enum metadata to save priority
- UENUM(BlueprintType)
- enum LogicStateEnum
- {
- LS_Default = 0 UMETA(DisplayName = "Default", Priority = 1),
- LS_Frozen UMETA(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_Back UMETA(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 BP
- UPROPERTY(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 time
- float ElapsedTime;
- //after this time, it will be reset to Default
- float 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 record
- ElapsedTime = 0;
- ResetToDefaultTime = DuringTime;
- //状态相同则刷新,不同则退出旧状态,进入新状态
- if (NewState == CurrentState)
- OnRefreshLogicState.Broadcast(CurrentState);
- if (NewState != CurrentState)
- {
- OnExitLogicState.Broadcast(CurrentState);
- }
- CurrentState = NewState;
- OnEnterLogicState.Broadcast(CurrentState);
- return true;
- }
蓝图使用
添加LogicStateMachine组件后,选中组件添加相关触发事件:
击中时改变目标Actor的状态:
进入相应状态改变后的行为:如击飞,击退。