Unity游戏开发(一) 状态模式的学习笔记
有关设计模式(Design Patterns)
设计模式是一套经过长时间,大数量的考验的代码设计经验分类总结。使用设计模式的目的是为了提高代码的复用性、让其他人更加方便理解以及保证程序的健壮性。(PS:其实学习设计模式的主要原因还是因为这个学期我们专业开设了设计模式这门课程,但是这门课程开设的方向是企业软件设计…嗯~ o( ̄▽ ̄)o 和我向往的岗位还是有点差距所以就打算自己往这个方向先学习一下hhh)
状态模式(State)的介绍(状态模式是什么、该怎么使用)
状态模式产生的背景
通常一款游戏的设计都会涉及到多个场景的混合使用,让玩家在这些场景之间相互转换,而不同的场景之间环境可能各异,甚至是截然不同。例如:一款游戏中,某一个场景可能是玩家在火山附近进行任务,而另一个场景则是在海洋中进行捕鱼。这样的设计方式类似于舞台剧的呈现方式,编剧们设计好了一幕幕的场景让演员们在其间穿梭演出,而每一幕之间的差异,可能是在布景摆设或者参与演出的角色不同,但是对于观众来说,都只是在同一个屏幕下观看到不同场景的演出。
例如我们设计一款游戏,它的大致内容可以划分为:点击图标后进入游戏的logo、游戏的片头介绍、加载游戏数据、出现游戏的主菜单界面、登录注册画面、进入游戏画面、游戏画面等等…
在此基础之上我们就可以将功能进行分类为几个场景来实现:
- logo、游戏片头和数据加载界面可以划分为 初始化场景 意为初始化游戏数据
- 游戏主菜单界面和登录注册画面可以划分为 菜单场景
- 游戏界面则可以单独划分为 游戏场景(注:游戏场景可能为多个,并不一定唯一,本次划分是为了方便举例)
这样我们就把场景切分出来了,切分场景的目的主要是为了保证游戏功能执行时需要的环境明确分类,还有一个好处是可复用场景(因为同类型的游戏界面也大多相似)。
在此基础上状态模式(State)就应运而生了,它是游戏程序设计中应用最频繁的一种模式。因为"状态"经常被应用在游戏设计的多个环节中,例如游戏场景的状态、AI的智能状态、账号的登录状态、角色状态等等。
状态模式的具体分析
状态模式在GoF中的解释是:
“让一个对象的行为随着内部状态的改变而变化,而该对象也像是换了类一样”。
而这种功能的实现方式大多是用子类的实例来传递父类参数,从而进行多样的变化。
状态模式的主要构成有三大块:状态拥有者、状态接口以及继承状态接口的具体状态类。
- 状态拥有者类的设计:当前状态属性,构造函数,更改状态函数,加载新场景函数,状态更新函数。
- 状态接口设计:状态拥有者属性,构造函数,状态开始函数,状态结束函数,状态持续更新函数。
- 具体状态类设计:继承自状态接口,重写开始、结束和更新函数,并实现具体的场景需求。
其实在Unity引擎中实现该模式还需要一个成员那就是游戏主循环(GameLoop),GameLoop持有状态拥有者,因为在设计中为了减少运行负担状态拥有者是不继承Unity的MonoBehaviour类,所以需要一个持有状态拥有者的类来进行状态模式与Unity实现运行关联的。
状态模式的优缺点
接下来我们来分析一下状态模式的优缺点
优点
- 能减少错误的发生并且降低维护的难度
- 状态执行环境单一化
- 不同项目之间可以共享相同或者类似场景
缺点
- 如果状态模式所应用的场景将面对大量状态的情况下,就会遇到“产生过多的状态类”的情况,此时会伴随着类爆炸的问题。但是与普通的switch管理状态来说,在后期的管理中状态模式仍然占据着优势。
下面附上我自己实现状态模式的代码以避免电脑丢档
游戏场景状态拥有者
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
namespace Assets.Scripts._01State
{
class GameStateController : MonoBehaviour
{
private ISceneState m_state = null;
private