【问题标题】:Best way to notify game objects of change? (Unity Script Organization / Delegation)通知游戏对象更改的最佳方式? (统一脚本组织/委托)
【发布时间】:2020-07-04 23:29:09
【问题描述】:

目前我的游戏有两种模式,构建模式和游戏模式。

对象在构建模式中的行为与在播放模式中的行为不同。

处理这些对象的最简单方法是什么?我应该使用切换吗?考虑到我在 OnUpdate 中的内容,我当前的性能和代码可读性设置如何?

这是一个示例,用于检查我制作的 GameController 是处于构建模式还是播放模式。当这些模式启动时,它也会获取,并通过操作布尔值运行一次函数。我正在寻找可以帮助我在优化游戏、代码可读性和代码的整体格式时做出更好决策的答案。我知道必须有一种更简单的方法,无论是使用侦听器还是使用事件/触发器。

游戏中一次可以有大约一百个这样的物品,所以我想确保我不会因为太多的更新调用而毁掉游戏。现在,虽然我有很多这些项目,但性能并没有真正下降,但这不是不优化我的游戏的理由。

   public class GameItem: MonoBehaviour 
{
    //....

         private void Update()
        {
         CheckMode();
        }
    
        // Checks Current Mode, And If StartingMode
        private void CheckMode()
        {
            // check to see if starting build mode, 
            if (!gameController.inPlayMode) 
            { 
               if (!startingBuildMode) 
              { 
                WhenStartingBuildMode(); 
                startingPlayMode = false; 
                startingBuildMode = true; 
               } 
        WhileInBuildMode();
        return; 
      }
    
            // check to see if starting play mode, 
            if (!startingPlayMode) 
           { 
             startingPlayMode = true;
             WhenStartingPlayMode(); 
             startingBuildMode = false; 
           }
    
    
            // what to do while in play mode
            WhileInPlayMode();
    
    
        }
    }

【问题讨论】:

  • 能否提供一些 OnUpdate() 方法的代码?
  • 更新中?在更新时运行 CheckMode() 类,该类不断运行 WhileInPlayMode() 或 WhileInBuildMode()。这是一个基类,因此这些函数根据项目执行不同的操作。例如,一个敌方物体会不断检查玩家的位置。或者一个箱子会不断更新,无论它是否打开。

标签: c# performance unity3d readability


【解决方案1】:

这将代表我使用的模式(具有能够在编辑器中切换模式的额外功能,不确定是否需要它)

public class GameItem: MonoBehaviour 
{
     [SerializeField] //see it in edior
     private bool _isBuildMode;
     public bool isBuildMode
           { get { return _isBuildMode;}
             set {
                 // if you want to make sure code only runs when value changes:
                 //   if (_isBuildMode==value)   return;
                  _isBuildMode=value; 
                  // do stuff related to mode change, like
                   if (isBuildMode) WhenStartingPlayMode(); 
                 }
           }
      void OnValidate()
      {
       if (Application.isPlaying) isBuildMode=isInBuildMode; // enable editor change
      }
     private void Update()
       {
        if (isBuildMode)
       {
          WhileInBuildMode();
       }
       else 
       {
          WhileInPlayMode();
        }
     }
   }

如果您想在游戏控制器中放置布尔机制,您可能需要考虑执行类似的操作

      public System.Action<bool> OnModeChanged;
      private bool _isBuildMode;
      public bool isBuildMode
           { get { return _isBuildMode;}
             set {
                  _isBuildMode=value; 
                  if (OnModeChanged!=null) OnModeChanged(value); 

                 }
           }

然后您可以订阅您的子组件

void Start()
{
  var gameController=GetComponentInParent<GameController>();
  if (gameController!=null) gameController.OnModeChanged+=(x)=>
    {
      isBuildMode=x;
    };
}

【讨论】:

  • 这个比我的读起来流畅多了,我喜欢!如果我想添加 WhenStartingBuildMode 我会使用: if (!isBuildMode) WhenStartingBuildMode(); ?另外,既然 Item 从游戏控制器获取模式,那么将 bools 放在我的 GameController 上会更好吗?
  • 很难知道你的游戏控制器是什么,但最好把布尔值放在那里。我展示的代码还有一个很好的属性,可以绑定到 Toggles
  • 我已经编辑了我的答案以添加关于在哪里引发事件的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多