正确处理对象状态

时间:2019-12-04 12:35:38

标签: unity3d design-patterns state

我在正确管理对象状态时遇到麻烦。

查看以下内容:

class PlayerController 
{
    bool canMove = true;
    bool canRotate = true;
    bool canShoot = true;
    bool canCastAbility = true;
}

class PlayerCamera 
{
    bool canLookAround = true;
    bool followPlayer = true;
}

class PlayerAbility 
{
    when used over time - PlayerCamera.canLookAround = false;
}

class PauseScreen 
{
    when game is paused - PlayerCamera.canLookAround != PlayerCamera.canLookAround;
}

您可能已经在这里看到了什么问题-当我们不使用自己的能力并且想要暂停游戏时,“ canLookAround”将正确设置为false。尽管当我们使用我们的能力并同时希望暂停游戏时,“ canLookAround”将设置为true-这是不正确的。

我相信我不必补充说,这种管理状态的方式看起来很糟糕,而且很容易迷失所有这些“ canDoSomething”布尔值。不仅Player具有这种布尔值,项目内部的许多脚本都受到这种不良状态管理的影响,这导致很多沮丧和迷失的感觉。

毕竟,您最终会遇到类似这样的可憎之处:

void PauseGame()
{
    enemy.canMove = false;
    enemy.canShoot = false;
    player.canMove = false;
    player.canShoot = false;
    player.canCastAbility = false;
    NPCs.canMove = false;
    etc...
}

除了让枚举器保存对象的当前状态外,处理此类状态的正确方法是什么?

有没有可以很好地解决此问题的设计模式?为了轻松处理状态,在项目的体系结构级别上是否必须遵循任何原则?

请与我分享您的经验,谢谢。

1 个答案:

答案 0 :(得分:1)

由于暂停游戏不是与对象相关的状态,而是一种全局状态,因此您应该这样做。

您不应仅因为暂停游戏而更改任何对象状态。暂停游戏的人甚至不需要(不需要)知道对象的概念存在。它仅负责进入和退出暂停状态!

我宁愿为暂停状态本身使用全局bool标志,并让您的所有组件都进行检查,例如

public class PauseScreen
{
    private static bool gameIsPaused;

    // ReadOnly public property so others can access the value
    // but only this class may change it
    public static bool GameIsPaused => gameIsPaused;

    void PauseGame()
    {
       gameIsPaused = true;
    }
}

现在让所有组件都依赖它。由于值为static,因此您甚至不需要引用(尽管您当然也可以使用通常的实例化字段和属性)。

private void Update()
{
    if(PauseScreen.GameIsPaused) return;

    ....
}