State

Tulenber 20 March, 2020 ⸱ Beginner ⸱ 4 min ⸱

Witcher在这里做什么?

今天的帖子将继续在名为"Unity and Singleton"的文章中提出的主题,并讨论可以在任何游戏中找到的模式,包括桌面-State。该模板承担了游戏行业中最重要的角色之一。它在游戏等方面非常普遍,例如人工智能-状态决定执行的动作,动画-状态决定要显示的动画序列,用户界面-窗口之间的转换,甚至是对话系统(带有Witcher的您好图片!)。如果仔细观察,游戏几乎完全是可控制的序列,因此可以用这种模式来描述。

理论与实践

模式是编程中非常流行的主题,因此,有关常规信息,您可以参考以下精彩的或此文章

从实际的角度来看,与单例(几乎在所有语言中都具有相当典型的实现)不同,状态可以具有相当独特的外观。 根据目的,它可能很大(用于描述事件),也可以采取简单的switch(在UI中添加字段)的形式。 因此,带来一个可以复制的实现没有任何意义。 对于典型示例,您可以参考以上理论文章或在Internet上搜索。

好了,一旦理论和实践都结束了,就让我们进入娱乐部分。

Unity

在现代游戏引擎中,大部分工作都花在了创建工具上,这些工具可供所有不太熟悉编程的人使用。在Unity中,一种机制就是称为"Mecanim"的机制。正如您可能想象的那样,它的主要目标是基于状态机创建动画。 让我们看看是否可以应用此机制以一般方式实现任务。

例如,让我们创建一个简单的文本场景,该文本在鼠标按钮上的“活动”“已暂停”状态之间切换 点击。

  1. 创建一个场景并在其上放置带有文本的UI元素

  2. 创建资产AnimatorController-这是我们状态机的模板对象
    Open Test Runner

  3. "Animator"标签上(您可以双击我们的新资产,也可以通过Window> Animation> Animator)创建两个 声明“有效”“已暂停”
    Open Test Runner

  4. 通过单击状态,可以添加过渡。 双向连接状态
    Open Test Runner

  5. 切换到“参数”面板并创建"Switch State"触发器
    Open Test Runner

  6. 在检查器中突出显示“活动” “已暂停” 之间的过渡,关闭"Has Exit Time"参数; 将"Transition Duration"设置为零; 添加"Conditions” - “Switch State”。对从“已暂停” “有效”
    Open Test Runner

  7. 创建一个名为"Game"的脚本

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    public class Game : MonoBehaviour
    {
        [SerializeField] private Text text = null;
    
        private Animator _animator = null;
    
        // 在第一帧更新之前调用开始
        void Start()
        {
            _animator = GetComponent<Animator>();
        }
    
        // 每帧调用一次更新
        void Update()
        {
            if (_animator.GetCurrentAnimatorStateInfo(0).IsName("Active"))
            {
                text.text = "Active";
            }
    
            if (Input.GetMouseButtonDown(0))
            {
                _animator.SetTrigger("Switch State");
            }
        }
    
        public void SwitchToPause()
        {
            text.text = "Paused";
        }
    }
    

  8. 创建"PauseState"脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public class PauseState : StateMachineBehaviour
    {
        public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            base.OnStateEnter(animator, stateInfo, layerIndex);
            
            animator.gameObject.GetComponent<Game>().SwitchToPause();
        }
    }
    

  9. 在舞台上创建一个空对象,然后向其中添加"Game"脚本,设置将显示当前状态的文本,然后添加"Animator"组件,并将在步骤1中创建的AnimatorController设置为"Controller"字段
    Open Test Runner

  10. 打开选项卡"Animator"选择状态«code class="icode">"Paused"并添加脚本"PauseState"
    Open Test Runner

所有这些操作的结果是,我们得到了一个场景,在该场景中,鼠标左键可以切换状态,直接从目标代码中检查“活动”,然后“已暂停”状态从状态机执行代码。

结论

这种方法类似于提议用左脚划伤右耳,但是,另一方面,它是创建状态机的真实且行之有效的机制,即使最初打算用于动画也是如此。还不清楚为什么开发人员不会将状态机的功能与动画分离,而是将其转变为通用工具。可以肯定的是-这是在Unity上开发游戏时的主要工具之一,因此我们用经过Mecanim训练的一块石头杀死了两只鸟,并记得Status模式是什么。虽然,当您在实现中遇到另一个错误时,此方法似乎不是一个糟糕的选择。下次见!^_^


如果您喜欢这篇文章,可以为它提供支持



Privacy policyCookie policyTerms of service
Tulenber 2020