zoukankan      html  css  js  c++  java
  • [UE4]逻辑状态机组件

    逻辑状态机

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

    实现过程:

    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的状态:



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



  • 相关阅读:
    JAVA 设计的七大原则
    电脑开机一支黑屏 ,只有鼠标
    oracle 创建表空间 、用户 、赋权、建表
    input 标签禁止输入
    input框限制只能输入正整数、字母、小数、汉字
    LINUX 解压文件
    LINUX vim 修改文件 退出
    layui table表格字段过长,展示不完整时,鼠标放到上面展示完整信息
    全网最全JS正则表达式 校验数字
    《学习笔记》基於NOPI開發 ExeclHelper工具類
  • 原文地址:https://www.cnblogs.com/corgi/p/5405449.html
Copyright © 2011-2022 走看看