作者feather623 (小羽毛)
看板GameDesign
标题[程式] Singleton Pattern实作-Instance
时间Sun Sep 10 11:55:25 2017
开发过稍微复杂一点的游戏的人大概都遇过这个状况:
●●●
写了一个负责掌控全局的脚本(许多人习惯命名为GameManager),它知道玩家现在几等、
目前是处於第几关、游戏是进行中or暂停中,所有需要使用它资讯的物件都必须在程式码
中宣告并引用之,并且还要开发者自己去拉reference(如图),如果线没牵好,游戏甚至
还有可能强制终止。
●●●
https://i.imgur.com/gqwJv0u.jpg
当你在其他脚本里撰写了public GameManager GM;,就会看到上图的画面。这个步骤本身
是正确且可行的,然而,在降低耦合性的程式设计原则下,这并不是工程师所崇尚的作法
。
既然自始至终,所有物件提到的GameManager都是指涉同一个对象,无一例外,那有没有
什麽方法可以避免这一再拉reference的步骤呢?
这时,我们可以藉助C#的一个特性,单例(Singleton)。
单例,顾名思义,就是在整个系统架构里面,这个脚本只会有唯一一个代表人,可以免去
手动指定的流程。
https://i.imgur.com/vPmOtZK.jpg
如图中第7行,我们创造了一个公开(public)但静态(static)的GameManager,并且命名为
Instance(这也是习惯上的命名,要取名做TheChosenOne也可以XD)。
再来看到第12行的Awake()函式,我们必须把Instance指向this,也就是GameManager它自
己。
经过这两个步骤,就完成单例的宣告了。
注:之所以将单例的指定放在Awake()里面,是为了让这一层关系早在其他脚本呼叫Insta
nce前就搭建起来,避免其他脚本在Start()呼叫了Instance,却获得Instance是null的状
况。
https://i.imgur.com/Nnzp0NR.jpg
我们再开另外一个脚本来检查结果,当我按下键盘的S键时,就会在Console中显示当前的
关卡,而关卡资讯是来自GameManager.Instance.curStage。
https://i.imgur.com/e0ad8eL.jpg
如此一来就不再需要第7行的宣告,也不用亲手帮每一个物件挂上GM的reference,可说是
一个便捷又具有设计美感(?)的做法,在越大型的专案里功效就越显着!
--
我是羽毛,目标是成为游戏工程师,请多多指教!
羽毛的电玩新手村
https://tinyfeather1997.wordpress.com
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.249.56.86
※ 编辑: feather623 (111.249.56.86), 09/10/2017 11:58:30
1F:推 coolrobin: 帮推,不过是不是在标题或内文前面加上unity会比较好?09/10 12:41
2F:→ coolrobin: 会比较便於搜寻 09/10 12:43
好的,谢谢你的建议~
3F:推 b87088: 羽毛推 09/10 13:06
HiHi 请问你是XD
※ 编辑: feather623 (111.249.56.86), 09/10/2017 13:17:03
4F:→ MBRSL: Singleton很容易被滥用造成bug,只建议在小规模的专案使用 09/10 13:43
5F:推 cjcat2266: 我觉得如果谨慎、分工正确、又有规矩地使用,应该还好 09/10 16:48
6F:→ cjcat2266: 碰过几个大专案有多个singleton合作,但是大家很谨慎 09/10 16:48
7F:→ cjcat2266: 没看到什麽严重的滥用情况,所以我觉得还是看使用者 09/10 16:49
9F:→ joseph33: 个singleton的base class出来用 09/10 17:20
10F:→ b87088: 之前gamejam队友~,看code才知道每个人都自己写自己的sin 09/10 18:46
11F:→ b87088: gleton~~ 09/10 18:46
12F:→ y3k: Singleton我只推荐用在API入口 不然很容易有bug 09/10 20:40
13F:→ bantime: 我挺好奇会造成什麽bug?有案例吗? 09/10 23:03
14F:→ dreamnook: 好奇是甚麽bug+1(没遇过 09/10 23:46
15F:推 MBRSL: 最常见是全域变数类的bug,详细理念请见下一篇文章 09/11 01:14
16F:→ y3k: 等一下 上面的真的都没遇过喔XD static变数造成的bug就不用提 09/11 01:23
17F:→ y3k: 了 我也遇过继承的问题、Singleton自己去跟其他物件黏答答在 09/11 01:23
18F:→ y3k: 一起发生的问题... 虽然没到罄竹难书的地步但是这个写法一看 09/11 01:24
19F:→ y3k: 到我都得先花个一两天把它的code翻一遍才安心 09/11 01:24
20F:→ y3k: 虽然这不是一个不能用的写法 但是遇到比较没经验或便宜行事的 09/11 01:26
21F:→ y3k: 捧油用 就容易把人的脑洞放大... 我只能这样讲 09/11 01:27
22F:→ dreamnook: 大概是我们平时在写的时候都有特别注意过吧@@ 09/11 08:11
23F:→ y3k: 我觉得是专案规模不大 或有一个SA之类的专职在处理规划架构 09/11 10:18
24F:→ dreamnook: 也是 近年来都很少碰过20人以上的专案了 09/11 10:55
25F:→ y3k: 20人如果全RD 那不少耶= = 09/11 11:01
26F:→ dreamnook: 整个专案20人 不是纯RD 20人xD 09/11 11:07
27F:→ bantime: 还真的没遇过..可能我在实作singleton的时候 09/11 13:26
28F:→ bantime: 都是保证唯一的状况下 例如你不会同时出现两个选角介面吧 09/11 13:27
29F:推 dreamnook: 09/11 18:15