zoukankan      html  css  js  c++  java
  • Unity3D游戏开发——编程实现游戏管理器

    本篇简介

    • 本篇介绍了如何将上一篇的设计模式思想运用到实际的开发过程中。

    脚本文件

    • (1)IGameManager:这个接口存在声明了一个属性(一个拥有getter函数的变量,属性的类型是ManagerStatus,一个枚举)和一个方法,它们都要被任何实现这个接口的类实现。定义了status属性,可以从任何地方获取状态(getter方法是公有方法),但是只能在脚本中设置状态(setter方法是私有方法).(ps:一个接口本身不会做任何事情,它存在的意义仅仅是将代码结构约束到其他类身上)
    • (2)ManagerStatus:这是一个几乎没有代码的文件,列出了管理器所有可能的状态(限定了status属性只能是里面列出的状态之一)。
    • (3)PlayerManager与InventoryManager:前者为人物管理器,后者为库存管理器。它们都继承自类MonoBehaviour且实现了IGameManager定义的结构。
    • (4)Managers:管理器的管理器。

    状态转化

    • 在所有的管理器中,初始化(InventoryManager没有做任何事情,而PlayerManager设置了一些值)一旦完成,status将被设置为Started。
    • 但是数据模块的初始化中可能有一些长线任务(例如加载所保存的数据),在初始化时,Startup()将运行这些任务,设置管理器的状态为Initializing(初始化中)。当完成后,再将status转化为Started。

    IGameManger的脚本代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public interface IGameManager 
    {
        ManagerStatus status { get; } //这是一个我们需要定义的枚举
    
        void Startup();  //这个方法的目的是处理管理器的初始化
    
    }
    

    ManagerStatus的脚本代码

    public enum ManagerStatus
    {
        Shutdown,  //关机
        Initializing,  //正在初始化
        Started  //开始启动
    }
    

    PlayerManager的脚本代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    ///<summary>
    ///人物管理脚本
    ///</summary>
    
    public class PlayerManager : MonoBehaviour, IGameManager    //继承一个类并实现一个接口
    {
        public ManagerStatus status
        {
            get;
            private set;  //status只读,不能在外部设置,内部可读写
        }
    
        public int health  //人物健康值
        {
            get;
            private set;
        }
    
        public int maxHealth  //人物最高健康值
        {
            get;
            private set;
        }
    
        public void Startup()
        {
            Debug.Log("PlayerManager starting ...");
            health = 50;   //初始化值
            maxHealth = 100;
    
            status = ManagerStatus.Started;
        }
    
        public void ChangeHealth(int value)
        {
            health += value;
            if (health > maxHealth)
            {
                health = maxHealth;
            }
            else if (health < 0)  //健康值最小为0
            {
                health = 0;
            }
    
            Debug.Log("Health:" + health + "/" + maxHealth);
        }
    }
    

    InventoryManager的脚本代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    ///<summary>
    ///库存管理脚本
    ///</summary>
    
    public class InventoryManager : MonoBehaviour, IGameManager
    {
        public ManagerStatus status  //这个属性可以从任何地方获取,但只能在这个脚本中设置
        {
            get;
            private set;
        }
    
        public void Startup()  
        {
            Debug.Log("InventoryManager starting ...");//任何长任务在这里启动
            status = ManagerStatus.Started;   //如果是长任务,状态改变为"Initializing"
        }
    
    }
    

    Managers的脚本代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    ///<summary>
    ///管理器的管理器
    ///</summary>
    
    [RequireComponent(typeof(PlayerManager))]  //自动添加管理器,确保存在不同的管理器
    [RequireComponent(typeof(InventoryManager))]
    
    public class Managers : MonoBehaviour
    {
        public static PlayerManager Player //其他代码用来访问管理器的静态属性
        {
            get;
            private set;
        }
        public static InventoryManager Inventory
        {
            get;
            private set;
        }
    
        private List<IGameManager> _startSequence;  //启动时要遍历的管理器列表
    
        void Awake()  //列出了启动序列,然后启动协同程序来运行所有的管理器
        {
            Player = GetComponent<PlayerManager>();
            Inventory = GetComponent<InventoryManager>();
    
            _startSequence = new List<IGameManager>();  //创建了List对象,用List.Add的方法来添加管理器。列表对象与数组相似,以一种具体的类型声明,把一系列元素依次存入,但可在创建后改变大小。
            _startSequence.Add(Player);
            _startSequence.Add(Inventory);
    
            StartCoroutine(StartupManagers());  //异步启动序列
        }
    
        private IEnumerator StartupManagers()
        {
            foreach (IGameManager manager in _startSequence)
            {
                manager.Startup();
            }
            yield return null;
    
            int numModules = _startSequence.Count;
            int numReady = 0;
    
            while (numReady < numModules)  //循环至所有管理器都启动为止
            {
                int lastReady = numReady;
                numReady = 0;
    
                foreach (IGameManager manager in _startSequence)
                {
                    if (manager.status == ManagerStatus.Started)
                    {
                        numReady++;
                    }
                }
                if (numReady > lastReady)
                    Debug.Log("progress:" + numReady + "/" + numModules);
                yield return null;
            }
    
            Debug.Log("All managers started up");
        }
    
    }
    

    参考资料

  • 相关阅读:
    FXBlurView用法
    NSAttributedString用法
    SDWebImage的使用
    UITextField 对输入金额的约束
    Delphi获取计算机名
    delphi下实现控制其它窗体中的控件[转]
    根据版本的不同整理所有的绿色SQL Server[转]
    点击TWebBrowser中的超级链接不在新的IE窗口打开
    Delphi 快速获取本机的IP地址[转]
    Delphi下如何使程序在Win7/Vista上用管理员权限运行[转]
  • 原文地址:https://www.cnblogs.com/Akyy/p/10652565.html
Copyright © 2011-2022 走看看