理清静态类和单例
作者:互联网
大家都知道什么是静态类,什么是单例,但是在使用unity做游戏的过程中其实我对这两个名词还是感觉没有清晰的区分,到底应该在什么时候该用静态类,什么时候该用单例呢?他们使用之后的差别又到底在哪里呢?今天我就通过一些实际在项目中的代码来理一理他们俩吧。
- 单例常用情景:大部分管理类的使用
大家在游戏中最常用的一种类就是管理类了,什么GameManager,SoundManager,这些一般都是单例类,我们的目的也就是想要在游戏中只存在一个这样的类,然后通过这个唯一实例化的管理类来进行一些管理行为。那么,静态类不是也是唯一的吗?为啥不用静态类来做呢?我这里就用一个最常用的子弹对象池的管理类来做一个对比分析吧。
我先来写一个非常简易的子弹对象池的单例类:
那么,如果用静态类能不能做到这个事情呢?能不能也用来管理一个对象池呢?答案是当然可以,接下来我就用静态类写一个,然后分析一下为什么用单例,而不用静态类。
可以看出静态类也是可以完全实现我们的需求功能的,但是,接下来我们一步一步的分析一下为什么静态类不适合作为对象池的管理类。
-
静态类不能继承。 图2和图1的第一个不同点,就是静态类并没有继承MonoBehaviour,这是因为静态类本身是不能继承其他类的,那么,他也就失去了很多单例类的优势,单利本身是可以实例化的,只是单例模式确保了实例化的这个类对象的唯一性,所以单例可以继承MonoBehaviour,所以也就自带了Unity的生命周期,比如Start,Awake,Update等等,而且也支持在编辑器面板的一些公共可视化参数编辑,而静态类由于其本身不能继承的特性,也就失去了这个优势,所有的这些都需要自己去实现,就好比图2中的transform,图1里是可以直接使用本身的transform,因为继承了MonoBehaviour自带了这个对象,但是自己写的静态类就需要自己写一个方法从外部传进来了。静态类本身的静态属性让其本身就是唯一的,所以也不需要像单例模式那样自己去保证唯一性。
-
静态类中的成员会一直存在直到应用退出。静态类中的成员引用指针或者值对象都会一直存在,直到你退出应用,而单例管理类是可以随着切换场景销毁的,就比如你单例类的脚本挂在一个Gameobject上,那么你Destroy了这个Gameobject之后,这个单例也就被销毁掉了,单例里的所有成员,引用指针,都会被销毁,等待GC回收掉,而在我们平时做游戏的时候,当然不希望在场景1使用的某些管理类,比如只有场景一才需要的子弹管理器,到了场景二还存在,因为可能我们场景二完全就不是一个战斗场景,不需要子弹,那如果这个管理器还保留着,缓存着那些子弹,不就是浪费了内存么,因为我们根本不需要,所以一般在场景切换的时候,我们就可以根据需求,去销毁释放一些下一个场景并不需要的单例类,而静态类本身无法被销毁,自然就达不到我们的目的了。
分析完以上两点,那么是不是游戏中静态类就没有用武之地了呢?其实也不是,我就发现了一个地方,如果用静态类来管理,就非常合适,那就是存档。
- 静态类适用场景:游戏存档 (单机类轻量级游戏适用,3A大作的那种存档数据量巨大的应该会有其他方案吧,有大佬知道的希望可以在评论区讨教一下)
因为游戏存档是所有地方都需要调用和使用的,那么其实可以用静态类来做管理,读取和保存,我感觉用着还是很方便的,你不需要去操心切换场景是不是要销毁释放,因为存档是一直存在在游戏中的,你随时都需要用来读或者存,尤其是做轻量级单机小游戏,下面我就简单的写一个存档的静态类管理,使用的是Unity自带的PlayerPref类。
顺手把实际用的地方也写一下
标签:类来,场景,游戏,静态,存档,理清,单例 来源: https://blog.csdn.net/XIAO_11_DONG/article/details/114528405