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");
}
}
参考资料
- 协程(协同程序)的概括(StartCoroutine 和yield return和StopCoroutine )
- IEnumerator和IEnumerable详解
- 《Unity 5实战——使用C#和Unity开发多平台游戏》,作者Joseph Hocking ,译者蔡俊鸿。
Unity3D游戏开发——编程实现游戏管理器的更多相关文章
- 【读书笔记《Android游戏编程之从零开始》】19.游戏开发基础(游戏音乐与音效)
在一款游戏中,除了华丽的界面 UI 直接吸引玩家外,另外重要的就是游戏的背景音乐与音效:合适的背景音乐以及精彩的音效搭配会令整个游戏上升一个档次. 在 Android 中.常用于播放游戏背景音乐的类是 ...
- Unity 4.2.0 官方最新破解版(Unity3D 最新破解版,3D游戏开发工具和游戏引擎套件)
Unity是一款跨平台的游戏开发工具,从一开始就被设计成易于使用的产品.作为一个完全集成的专业级应用,Unity还包含了价值数百万美元的功能强大的游戏引擎.Unity作为一个游戏开发工具,它的设计主旨 ...
- 【笔记】《DirectX 9.0 3D游戏开发编程基础》:Direct3D初始化
Direct3D初始化大概分为4个步骤: 1.获取接口IDirect3D9的指针.(Direct3DCreate9函数调用). 该接口用户获取系统中物理硬件设备的信息并创建接口IDirect3DDev ...
- H2Engine游戏服务器设计之属性管理器
游戏服务器设计之属性管理器 游戏中角色拥有的属性值很多,运营多年的游戏,往往会有很多个成长线,每个属性都有可能被N个成长线模块增减数值.举例当角色戴上武器时候hp+100点,卸下武器时HP-100点, ...
- Unity 2D游戏开发教程之游戏精灵的开火状态
Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- [Unity3D]Unity3D游戏开发Lua随着游戏的债券(在)
---------------------------------------------------------------------------------------------------- ...
- 【读书笔记《Android游戏编程之从零开始》】20.游戏开发基础(游戏数据存储)
对于数据的存储,Android 提供了4种保存方式. (1)SharedPreference 此方法适用于简单数据的保持,文如其名,属于配置性质的保存,不适合比较大的情况,默认存放在手机内存里 (2) ...
- 8、Cocos2dx 3.0三,找一个小游戏开发3.0存储器管理的版本号
重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27693365 复杂的内存管理 移动设备上的硬件资源十 ...
随机推荐
- Scrapy-从数据库取出IP并判断是否可用
import pymysql import requests conn = pymysql.connect(host="localhost",user="root&quo ...
- Onvif获取rstp地址GetCapabilities能力时,出现error 4或者52的的解决方法
在获取Onvi能力soap_call___tds__GetCapabilities的接口中有时候会出现error:4或者52的情况,是因为在soapC.c中用不到extension,所以我们必须得把它 ...
- angular自定义过滤器在页面和控制器中的使用
首先设置自定义过滤器. 定义模块名:angular .module('myApp') .filter('filterName',function(){ return function(要过滤的对象,参 ...
- 十张图了解Docker【转】
这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(container)和镜像(image)之间的区别,并深入探讨容器和运行中的容器之间的区别. 当我对Docker技术还是一知半解的时候,我 ...
- 2017-2018-1 20155315 《信息安全系统设计基础》嵌入式C语言测试
Hours 要求 伪代码 提取Hours 提取时间地址 时间存放在(基址+2)的16位寄存器中,定义一个时间宏存放地址. #define Time_Addr 0xFFFFC0000 #define T ...
- 对Dataguard的三种模式的理解
模式1:最大可保护模式: 必须同步. 模式2:最大可用性模式: 能同步就同步,不能同步就不同步. 模式3:最大性能模式: 异步模式.
- Linux下开发python django程序(模板设置和载入数据)
1.添加templates文件夹 2.修改settings.py文件 import os #引用 os模块 BASE_DIR = os.path.dirname(os.path.dirname(os. ...
- extern "C" 的用意
extern "C" 修饰符只有在C++代码的时候才用到. C++编译器通常会对变量名和函数名进行改编,这样在链接的时候会出现问题. 假如: 1.用C++编写的Dll,在编译成Dl ...
- PKUWC2019题解
这里其实只放一下题面和一些提示,大家评一评有几道题可做 题面全部蒯自xzz的博客 Day 1 T1 题面 一个有向图,每一条边可能存在也可能不存在,求拓扑序列数量的期望乘\(2^m\) 没有重边自环, ...
- JAVA中使用RSA通过秘钥文件对字符串进行加密解密
技术交流群: 233513714 //字符串进行加密算法的名称 public static final String ALGORITHM = "RSA"; //字符串进行加密填充的 ...