# 一、背景

  • 以前的我

    /* 伪代码
    if( Press(ButtonSpace) )
    {
    	Jump();
    }
    */
    
    // 或者UE5的输入绑定
    EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
    

    很明显输入和游戏行为绑定死了,需求一变全部改!

  • 现在的我?

    • 受到《游戏编程模式》中命令模式的启发,决定重新设计上面的输入系统。

# 二、命令模式

  • 命令模式简介:发送者将请求以命令的形式包裹在命令对象中,并将命令传给接受者。顺序:调用者→命令→接受者。
  • 参考《游戏编程模式》- 命令模式
    • 命令就是面向对象的回调。
    • 上面 UE5 的代码,输入回调绑定的就是面向对象实例函数的回调,直接将输入跟游戏行为(ACharacter::Jump)耦合,很难再扩展。
  • 优点: 1、降低了系统耦合度(解耦发送者和命令接收者)。 2、新的命令可以很容易添加到系统中去

# 三、输入架构

Game Play Input Framework

  • 命令创建发送者:EnhancedInputComponent/UXXInputComp_Assistant
  • 命令:UXXInputCommand
  • 命令接收者 / 命令接受者:UObject*

# I、简介

  • 数据: UXXDataAsset_InputComp(编辑器可配置、可复用)
  • UXXInputComp_Assistant 根据数据绑定回调:UInputAction -> UXXInputCommand
  • 命令可以创建无数个,与 InpuAction 随心配!

# II、答疑解惑

  • UXXInputComp_Assistant 为什么不直接继承 EnhancedInputComponent?
    答:我其实也想继承的,毕竟没有多少代码,新创建一个 ActorComponent 实在不划算,但是 InputComponent 被设置了蓝图隐藏和 NotBlueprintable!
    我不想改引擎源码,所以只能创建一个新的组件去实现 InputAction->InputCommand 的绑定。

  • UXXInputComp_Assistant 为什么要单独区分 Actor、玩家和 UI,配置和绑定不都一样吗?
    答:1. UserWidget 不是一个 Actor,InputComponent 只是组合在里面!这就导致 Actor 和 UI 要分开处理,因为命令接收者 / 命令接受者不一样。
    2. 可能会有些特殊的功能,比如:玩家按键自定义

  • 命令也需要单独区分?
    答:是的。UI、Actor、玩家处理输入的逻辑不一样,比如:点击手柄的 A 按钮,UI 可能是确认,玩家可能是跳跃,Actor1 可能是消失,Actor2 可能是打开门...。

# 四、未来可期

  • NPC 的行为也靠相同接口的命令驱动会怎么样?(NPC 发送命令者可警戒系统、任务系统、周围环境...)
    • 最明显的是各个系统和 NPC 行为解耦了。
    • 再进一步是不是可以实现七十二变、夺舍等功能了,这也太棒了吧!(因为命令接口一模一样)。
編集日

*~( ̄▽ ̄)~[お茶]を一杯ください

XiaoLiang WeChat 支払う

WeChat 支払う

XiaoLiang Alipay

Alipay