逻辑状态机

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

实现过程:

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



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



[UE4]逻辑状态机组件的更多相关文章

  1. 【UE4 设计模式】组件模式 Components Pattern

    概述 描述 在单一实体跨越了多个领域时,为了保持领域之间相互解耦,可以将每部分代码放入各自的组件类中,将实体简化为组件的容器. 套路 参考 UE4中的 Componet 组件使用方式 使用场景 有一个 ...

  2. [UE4]自定义MovementComponent组件

    自定义Movement组件 目的:实现自定义轨迹如抛物线,线性,定点等运动方式,作为组件控制绑定对象的运动. 基类:UMovementComponent 过程: 1.创建UCustomMovement ...

  3. vue应用或者是项目其实就是 实例(完成基本逻辑) + 组件(单文件组件,全局组件,局部组件,内置组件)来完成 ;

    以上! 组件里面包含HTML,css, js,也就是一个完整的功能!

  4. [UE4]自动旋转组件

  5. Unity Animator动画状态机 深入理解(一)

    接触Unity以来就已经有了Animator,Animation用的少,不过也大概理解他俩之间的一个区别于联系. 图中其实就是Animator和Animation之间的区别于联系了,啊!你肯定会告诉我 ...

  6. Quick StateMachine状态机

    状态机quick中是一个亮点,假设我们做一款RPG游戏,一个角色通常会拥有idle,attack,walk.run,death这些状态,假设游戏角色的状态採用分支条件推断的话.会造成很庞大而难以维护. ...

  7. 【JAVASCRIPT】React学习-如何构建一个组件

    摘要 react 学习包括几个部分: 文本渲染 JSX 语法 组件化思想 数据流 组件化思想 组件就是 UI + UI 交互逻辑,组件有三个常规map , 分别为state 状态 . props 数据 ...

  8. UE4杂记

    一些学习UE4时的笔记,转载请注明出处. ☆ UE4逻辑 Actor 是由 AActor 类派生而来的类实例:能被放入游戏世界场景的所有游戏性对象的基础类.对象是继承自 UObject 类的类实例:虚 ...

  9. Unityclient框架笔记二(组件实体开发模式的思考)

    Unity的Entity-Component-System实现的很美丽,很灵活.许多文章也对这样的组件实体的开发模式倍加推崇.由于它契合这么一条规则:优先使用组合而不是继承. 可是实际开发过程中,限制 ...

随机推荐

  1. 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇

    驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...

  2. Git相关知识

    一些有用的链接: https://www.git-scm.com/ http://nvie.com/posts/a-successful-git-branching-model/ Git开发模式: 建 ...

  3. C语言获取时间

    转载:http://www.cnblogs.com/fzhe/archive/2012/11/06/2757858.html C语言获取系统时间的几种方式   C语言中如何获取时间?精度如何? 1 使 ...

  4. logback logback.xml常用配置详解(三) <filter>

    <filter>: 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一.返回DENY,日志将立即被抛弃不再经过其他过滤器:返回NEUTRAL,有序列表 ...

  5. 图片缩放应用(nearest / bilinear / three-order interpolate)

    typedef xPixel PIXELCOLORRGB; double Sinxx(double value){ if (value < 0) value = -value; if (valu ...

  6. 一次疏忽导致的bug

    NBB_PUT_SHORT 这个宏是按char* 类型算指针的实际工作中,没有注意这一点,输入指针类型 强转为了 SHORT* 导致 填充的内容错误 这是第一次在工作中遇到 指针类型相关的问题值得记录 ...

  7. ubuntu14.04 安装系统

    p { margin-bottom: 0.1in; line-height: 120% } code.cjk { font-family: "Droid Sans Fallback" ...

  8. 接入百度语音SDK的步骤

    1.导入依赖库 SystemConfiguration.framework AudioToolbox.framework UIkit.framework AVFoundation.framework ...

  9. Java动手动脑(二)

    1>类的对象实例化 由于main为静态类型,所以在调用函数时也必须调用静态方法,如上代码中的求平方数的静态方法,如何在静态main中调用非静态类的方法呢? 静态方法只能直接访问静态成员,无法访问 ...

  10. Reverse链表 递归实现

    #include<iostream> struct node{ int payload; node* next; }; void bianli(node* head){ node* ite ...