unity3D技术之使用单例模式Singleton.docx
- 文档编号:3232622
- 上传时间:2022-11-20
- 格式:DOCX
- 页数:9
- 大小:18.53KB
unity3D技术之使用单例模式Singleton.docx
《unity3D技术之使用单例模式Singleton.docx》由会员分享,可在线阅读,更多相关《unity3D技术之使用单例模式Singleton.docx(9页珍藏版)》请在冰豆网上搜索。
unity3D技术之使用单例模式Singleton
这几天想把在实习里碰到的一些好的技巧写在这里,也算是对实习的一个总结。
好啦,今天要讲的是在Unity里应用一种非常有名的设计模式——单例模式。
单例模式的简单介绍请看前面的链接,当然网上还有很多更详细的介绍,有兴趣的童靴可以了解一下。
其实设计模式对于一个程序员来说还是非常有用的,这点随着学习的深入感受越来越深。
好啦,现在说一下Unity里的单例模式。
什么时候需要使用单例模式呢?
正如它的名字一样,你认为一些东西在整个游戏中只有一个而你又想可以方便地随时访问它,这时你就可以考虑单例模式了。
例如,你的游戏可能需要一个管理音乐播放的脚本,或者一个管理场景切换的脚本,或者一个管理玩家信息的通用脚本,又或者是管理游戏中各种常用UI的脚本。
事实上,这些都是非常常用而且必要的。
实现
庆幸的是,单例模式的代码非常简单。
下面是Singleton.cs的内容:
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
publicclassSingleton:
MonoBehaviour
{
privatestaticGameObjectm_Container=null;
privatestaticstringm_Name=“Singleton”;
privatestaticDictionary
privatestaticboolm_IsDestroying=false;
publicstaticboolIsDestroying
{
get{returnm_IsDestroying;}
}
publicstaticboolIsCreatedInstance(stringName)
{
if(m_Container==null)
{
returnfalse;
}
if(m_SingletonMap!
=null&&m_SingletonMap.ContainsKey(Name))
{
returntrue;
}
returnfalse;
}
publicstaticobjectgetInstance(stringName)
{
if(m_Container==null)
{
Debug.Log(“CreateSingleton.”);
m_Container=newGameObject();
m_Container.name=m_Name;
m_Container.AddComponent(typeof(Singleton));
}
if(!
m_SingletonMap.ContainsKey(Name))
{
if(System.Type.GetType(Name)!
=null)
{
m_SingletonMap.Add(Name,m_Container.AddComponent(System.Type.GetType(Name)));
}
else
{
Debug.LogWarning(“SingletonTypeERROR!
(”+Name+“)”);
}
}
returnm_SingletonMap[Name];
}
publicvoidRemoveInstance(stringName)
{
if(m_Container!
=null&&m_SingletonMap.ContainsKey(Name))
{
UnityEngine.Object.Destroy((UnityEngine.Object)(m_SingletonMap[Name]));
m_SingletonMap.Remove(Name);
Debug.LogWarning(“SingletonREMOVE!
(”+Name+“)”);
}
}
voidAwake()
{
Debug.Log(“AwakeSingleton.”);
DontDestroyOnLoad(gameObject);
}
voidStart()
{
Debug.Log(“StartSingleton.”);
}
voidUpdate()
{
}
voidOnApplicationQuit()
{
Debug.Log(“DestroySingleton”);
if(m_Container!
=null)
{
GameObject.Destroy(m_Container);
m_Container=null;
m_IsDestroying=true;
}
}
}
代码大部分都比较容易看懂,下面介绍几点注意的地方:
当我们在其他代码里需要访问某个单例时,只需调用getInstance函数即可,参数是需要访问的脚本的名字。
我们来看一下这个函数。
它首先判断所有单例所在的容器m_Container是否为空(实际上就是场景中是否存在一个Gameobject,上面捆绑了一个Singleton脚本),如果为空,它将自动创建一个对象,然后以“Singleton”命名,再捆绑Singleton脚本。
m_SingletonMap是负责维护所有单例的映射。
当第一次访问某个单例时,它会自动向m_Container上添加一个该单例类型的Component,并保存在单例映射中,再返回这个单例。
因此,我们可以看出,单例的创建完全都是自动的,你完全不需要考虑在哪里、在什么时候捆绑脚本,这是多么令人高兴得事情!
在Awake函数中,有一句代码DontDestroyOnLoad(gameObject);,这是非常重要的,这句话意味着,当我们的场景发生变化时,单例模式将不受任何影响。
除此之外,我们还要注意到,这句话也必须放到Awake函数,而不能放到Start函数中,这是由两个函数的执行顺序决定的,如果反过来,便可能会造成访问单例不成功,下面的例子里会更详细的介绍;
在OnApplicationQuit函数中,我们将销毁单例模式。
最后一点很重要:
一定不要在OnDestroy函数中直接访问单例模式!
这样很有可能会造成单例无法销毁。
这是因为,当程序退出准备销毁单例模式时,我们在其他脚本的OnDestroy函数中再次请求访问它,这样将重新构造一个新的单例而不会被销毁(因为之前已经销毁过一次了)。
如果一定要访问的话,一定要先调用IsCreatedInstance,判断该单例是否存在。
--来自狗刨学习网
例子
下面,我们通过一个小例子来演示单例模式的使用。
首先,我们需要创建如上的Singleton脚本。
然后,再创建一个新的脚本SingletonSample.cs用于测试,其内容如下:
usingUnityEngine;
usingSystem.Collections;
publicclassSingletonSample:
MonoBehaviour
{
//Usethisforinitialization
voidStart(){
TestSingleton();
}
//Updateiscalledonceperframe
voidUpdate()
{
}
privatevoidTestSingleton()
{
LitJsonSamplelitjson=Singleton.getInstance(“LitJsonSample”)asLitJsonSample;
litjson.DisplayFamilyList();
}
// voidOnDestroy(){
// LitJsonSamplelitjson=Singleton.getInstance(“LitJsonSample”)asLitJsonSample;
// litjson.DisplayFamilyList();
// }
}
注意,为了方便,我使用了上一篇博文里使用的Litjson的代码,并做了少许修改。
下面是修改后的LitJsonSample.cs:
usingUnityEngine;
usingUnityEditor;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingLitJson;
publicclassFamilyInfo{
publicstringname;
publicintage;
publicstringtellphone;
publicstringaddress;
}
publicclassFamilyList{
publicList
}
publicclassLitJsonSample:
MonoBehaviour{
publicFamilyListm_FamilyList=null;
//Usethisforinitialization
voidAwake(){
ReloadFamilyData();
}
privatevoidReloadFamilyData()
{
//AssetDatabase.ImportAsset(“Localize/family.txt”);
UnityEngine.TextAssets=Resources.Load(“Localize/family”)asTextAsset;
stringtmp=s.text;
m_FamilyList=JsonMapper.ToObject
if(JsonMapper.HasInte
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- unity3D 技术 使用 模式 Singleton