起因:每个游戏场景中都会有许多的游戏对象,而各个游戏场景之间也是同等的关系。如何去管理它们,是我们要解决的问题。

场景中各脚本间的直接访问,会在各脚本间形成一个巨大而又混乱的网络,这给以后代码的维护带来了极大的困难。为了避免这种因交互访问而带来的过度耦合情况,我们取消掉场景中各脚本间的直接交互,取而代之的是,让所有脚本都只与场景中的一个特定脚本交互。

在刚开始使用这种方法时,自己声明了一个场景中的全局脚本,然后把场景中所有其他需要交互的脚本声明为其成员,一旦脚本间要发生交互,就在脚本中声明一个全局脚本的对象,然后通过这个对象去访问其他的脚本,从而把直接交互变成了间接交互。这样做确实解决了脚本之间直接访问带来的高耦合度问题,但是在每个脚本中都要保存一个全局脚本的对象,这显然有些不太合适,浪费了资源。为了进一步解决这个问题,引入了单例模式的应用。

单例模式的定义是:保证一个类只有一个实例,并且提供一个访问它的全局访问点。单例对象的类必须保证只有一个实例存在。在我们的场景中,全局脚本的对象只会创建一次,保证单例,然后它(全局单例类)提供给各个脚本访问单例对象的方法,并且所有其他脚本的公共数据都会存储在全局单例脚本中。

private static GloSingleton _globalSingleton;

声明全局单例类自身类型的静态私有成员变量,作为单例对象使用。

public static GloSingletonGetSingleton() { …}

提供获取单例对象的类的静态方法。任何对单例对象的访问都要通过该方法来获取。

if (null ==_globalSingleton) {

lock(_globalSingleton) {

if(null == _globalSingleton) {

_globalSingleton=

(GloSingleton)GameObject.FindObjectOfType(typeof(GloSingleton));

}

}

}

单例模式的使用在多线程并发的情况下必须小心谨慎。因为当唯一实例尚未创建时,如果有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自会创建一个实例,这违背了单例模式中实例唯一的原则。解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁。

如我们的代码所示,在方法内部,首先判断单例对象是否为空,为空的话说明单例对象还没有创建,需要实例化一个。反之直接返回单例对象。在准备首次创建单例对象时,设置了一个互斥锁。目的是为了在多线程并发的情况下也能保证单例。相关内容请参看我转载的另一篇博文《C#中的lock关键字》。互斥锁中的判空检测同样是为了保证单例而设的。如果没有二次的检测,当线程A进入lock代码块中,线程B等待时,刚开始单例对象还没有创建,线程A执行完毕离开lock代码块后,单例对象已被创建完毕,而此时原本等待的线程B会进到lock代码块中,再次创建单例对象,因此单例被破坏。二次检测则避免了这种情况的发生。当线程A从lock中离开时,单例对象已经存在,线程B进入lock,便不会再执行创建单例对象的代码了。

这种实现方式即遵守了单例模式,又不必在每次获取单例对象时进行互斥锁的判断,提高了效率。因为自己对单例模式的理解比较简单,若大家有更好的实现方法,欢迎交流讨论。

单例模式在Unity中的应用的更多相关文章

  1. Unity中C#单例模式使用总结

    一.单例模式优点 单例模式核心在于对于某个单例类,在系统中同时只存在唯一一个实例,并且该实例容易被外界所访问: 意味着在内存中,只存在一个实例,减少了内存开销: 二.单例模式特点 只存在唯一一个实例: ...

  2. 【Unity3D基础教程】给初学者看的Unity教程(七):在Unity中构建健壮的单例模式(Singleton)

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 该博客中的代码均出自我的开源项目 : 迷你微信 ...

  3. MonoSingleton——Unity中的单例模式

    Unity中有很多特别的类需要以单例模式呈现,比如全局的UI管理类,各种缓存池,以及新手导航类等等.而Unity中,因为所有继承自Monobehaviour的脚本在实现的时候都是单线程的,所以像网上流 ...

  4. Unity中的万能对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的万能对象池 本节通过一个简单的射击子弹的示例来介 ...

  5. 【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则

    作者:Williammao, 腾讯移动客户端开发工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/290.h ...

  6. 【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则

    引言 原则1尽可能地使用属性而不是可直接访问的数据成员 原则2偏向于使用运行时常量而不是编译时常量 原则3 推荐使用is 或as操作符而不是强制类型转换 原则4 推荐使用条件属性而不是if条件编译 原 ...

  7. 【转】Effective C#观后感之提高Unity中C#代码质量的21条准则

    转自:http://blog.csdn.net/swj524152416/article/details/75418162 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effectiv ...

  8. Unity编程标准导引-3.4 Unity中的对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的对象池 本节通过一个简单的射击子弹的示例来介绍T ...

  9. Unity中使用Attribute

    Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...

随机推荐

  1. C#截取指定字符串函数

    本文转载:http://www.cnblogs.com/liufei88866/archive/2012/05/12/2497395.html 一.通过函数方式进行获取. public string ...

  2. android ui定义自己的dialog(项目框架搭建时就写好,之后事半功倍)

    自定义一个dialog: 之前有很多博客都有过这方面的介绍,可是个人觉得通常不是很全面,通用性不是很强,一般会定义一个自己的dialog类,然后去使用,难道每一个dialog都要定义一个class吗? ...

  3. UVA 10627 - Infinite Race(数论)

    UVA 10627 - Infinite Race option=com_onlinejudge&Itemid=8&page=show_problem&category=516 ...

  4. PHP读取文件头(2字节)判断文件类型(转)

    看到此标题或许你会说是否是多此一举,直接判断扩展名不就知道文件类型了吗,但是扩展名很容易伪造,这样就绕过了判断.大部分的文件都会将一个特殊的数字或字符存放在文件的特定位置里(开始处的2个字节) /** ...

  5. maven提示错误的解决办法

    import或者new一个的maven project的时候,提示如下错误 Description    Resource    Path    Location    TypeCannot read ...

  6. TOKEN的保存与验证

    Token主要为了防止非本页数据的提交,防止重复提交. /** * * 保存TOKEN信息 * */ public void saveToken() { //此处生成md5串 string md5 = ...

  7. CI 笔记(easyui js命令)

    1. 两种方式加载easyui,一是用class自动渲染,一种是js.建议js. 2. 参考李炎恢的easyui的视频教程.最好的一个视频,对于easyui.

  8. CI 笔记4 (easyui 手风琴)

    添加父div标签,和子div标签 <div class="easyui-accordion" data-options="fit:true,border:false ...

  9. xcode7 icon图标设置

  10. JavaScript HTML DOM EventListener

    JavaScript HTML DOM EventListener addEventListener() 方法 实例 点用户点击按钮时触发监听事件: document.getElementById(& ...