1.现在自学unity3d(含C#语言),有前途吗?一般人要学多久?
2.Unity 编辑器扩展和序列化踩坑记(一)
3.unity3d和虚幻4哪个好有什么区别
现在自学unity3d(含C#语言),有前途吗?一般人要学多久?
1. 对于C#语言,它是微软.NET平台的一部分,尽管微软大力推广,但由于这门语言不跨平台且入门门槛较低,eos签名源码社会上的态度有些复杂。常常出现的情形是高级语言如C++看不起JAVA,JAVA又看不起C#,这种态度反映了编程界的某种鄙视链。
2. Unity3D的未来发展预计将保持稳定,不会有太大的波动。虽然大家都说VR是未来的趋势,确实有很多VR行业的公司开始使用UE4引擎进行开发。UE4是开源的,而Unity3D不是,这从软件开发成本上就形成了优势。此外,UE4允许修改源码以达到特定效果,而Unity如果出现BUG,可能会带来问题。
3. Unity3D的一个显著优势是它的跨平台性。许多3D手游都是使用Unity开发的。虽然UE4也可以用于开发手游,ebpm源码但目前手机的普遍配置难以流畅运行UE4开发的游戏。随着未来手机硬件性能和散热能力的提升,UE4在移动端与Unity平分天下的可能性完全存在。
4. 对于楼主来说,是一名高中生。我建议楼主先打好理论基础,因为Unity这类技能属于应用型学科。还有6年才进入就业市场,未来6年的变化无法预测。因此,现在专注于打好基础更为重要。
Unity 编辑器扩展和序列化踩坑记(一)
本篇文章未经作者本人授权,禁止任何形式的转载,谢谢!如果在第三方阅读发现公式等格式有问题,请到个人博客地址或知乎地址阅读。
最近两三周在写 Unity 的编辑器扩展,主要是为项目开发地图编辑器,过程中遇到了一些问题,因此决定记录下来,形成系列文章。这是第一篇,但真心希望不要有第二篇。文石源码
目前我使用的 Unity 版本是 .1.3.f1。
在编写编辑器扩展时,如果需要将数据保存到文件,序列化数据是必须的。我尝试过两种方案:Unity 自身的序列化系统配合 ScriptableObject,以及 C# 的序列化 API。两者各有优缺点。
C# 序列化虽然方便快捷,但在 Unity 中使用可能并不理想。如果使用 C# 序列化,class 或 struct 必须加上 Serializable 属性。然而,大多数你想序列化的 C# 内置 class 或 struct 都没有这个属性,例如 VectorX 系列,还有 ScriptableObject。在需要使用 C# 序列化时,我不得不自己实现一个可序列化版本,例如 Vector2 和 Vector3。
C# 序列化在 Unity 中的另一个问题是,它不如内置序列化系统方便。虽然 Unity 的序列化几乎每时每刻都在进行,但有相应接口,你必须确保在必须序列化的pdfviewer源码时机进行序列化,以免数据被清空。
Unity 内置序列化系统以及一些配套组件(例如 ScriptableObject 等)在 Unity 中能保证序列化和反序列化数据的正确性,并且几乎不需要关心序列化的时机,只需要指明哪些数据需要序列化即可。一般来说,在会被 Unity 进行序列化的内置类中,public 字段和被 SerializeField 属性修饰的字段会被序列化,例如 MonoBehaviour 中的字段,ScriptableObject 也是,其他自定义类我没验证过,但是 private 的我都加了 SerializeField 属性没有问题,public 的也可以正确序列化。
但是并非所有类型都可以序列化!在常用的需要序列化的类中,Dictionary、二维数组以及其他有嵌套关系的容器(目前看来是这样,不能保证所有这种容器一定不能被序列化)不能被序列化。幸运的是,都有相应的解决办法。
虽然 Dictionary 不能被 Unity 序列化,但 List 是可以的。我们可以把 Dictionary 的 keys 和 values 保存在两个 List 里,这样就可以序列化和反序列化字典了。源码人员请注意,我并不是说要用两个 List 完全代替 Dictionary 这个数据结构,这样就失去了 Dictionary 的数据结构特性了。我们只需要在 Unity 进行序列化和反序列化的时候把 Dictionary 搬到两个 List 里,再从两个 List 中复原 Dictionary 就行了。Unity 进行序列化和反序列化的时机是可以知道的,关键在于一个 interface。
这个 interface 有两个方法:OnBeforeSerialize 在将要序列化的时候执行,OnAfterDeserialize 在反序列化完成后执行。因此,我们只需要在 OnBeforeSerialize 中把 keys 和 values 保存到两个 List 里,在 OnAfterDeserialize 中根据两个 List 中的数据重建一个 Dictionary 就行了。需要注意的是,这个 interface 目前不支持 struct。
如果是类似这样的数据,里面的 X[] 是不能被序列化的。但是如果你将 X[] 写在一个类里,外部容器保存这个 XWrapper,就可以正确序列化数组中的数据了。因此,如果你在使用嵌套容器时出现问题,可以考虑这种方法。
在编写编辑器代码时,会有一些情况导致内存中的数据被清空。我判断内存数据被清空重置的方式是观察静态构造函数在控制台的输出。目前我遇到的情况有:退出运行不会进行内存重置,但很重要,因为退出也相当于加载了场景,会执行 Awake 等相关函数,如果你有一些初始化函数在这时候执行,你需要注意它是否会影响到你。
ScriptableObject 类看似很简单,但第一次使用却花费了我很长时间来与其搏斗。这个类主要用来进行数据交互,它不需要挂在 GameObject 上,可以作为单独的数据存储来使用。在编写编辑器扩展时使用它,有不少地方需要注意。
ScriptableObject 可以保存为 Asset,而且实际使用时发现,如果你不保存成 Asset,相关的引用就会在某些时候变为空。例如使用 ScriptableObject.CreateInstance 创建一个 ScriptableObject 后,把它保存在容器里,然后函数结束。当你下次再用,就会发现这个引用变为 null 了。如果 ScriptableObject.CreateInstance 之后把这个 ScriptableObject 保存为 Asset,则没有问题。
如果使用诸如 AssetDatabase.LoadAsset<> 之类的函数把 ScriptableObject Asset 加载进来,然后保存在一个 MonoBehaviour 的变量里,当你删除这个 Asset 时,这个变量也为空了。也就是说,如果是直接加载这个 ScriptableObject Asset,当 Asset 被删除,加载进来的对象也没了(我原本以为挂在物体上的数据还会保留)。这个不注意可能会有一些致命的问题,例如你有个 ScriptableObject Asset,里面可能还有很多子 ScriptableObject Asset,策划想要用你的编辑器继续做上次没完成的工作,于是把上次保存好的 ScriptableObject Asset 加载进来进行操作,操作完毕后进行保存,可能会直接选择上次的路径,代码里可能会使用 AssetDatabase.CreateAsset 等方法,这实际上会覆盖原先的资源,也就是说之前的资源被删掉了。这时问题就来了,资源被删除后,Scene 中的数据也没了,这时保存代码执行,自然什么也保存不到。
解决方案是加载后使用 Instantiate<> 去复制出一个 ScriptableObject,之后都操作这个复制出来的,或者干脆用 ScriptableObject.CreateInstance 创建一个新的(要注意上面提到的问题,最好创建完后立即使用或者挂在物体上)。
保存数据时,尽可能不要用枚举作为 key,因为一旦枚举因为某些原因数值发生变化,数据可能取不出来。可以考虑将其转换为字符串。参考了 C# 的源码,枚举在进行 GetHashCode 时,好像是用它的数值进行操作的。
这次暂时写这么多,再次希望不要有第二篇。以上如果有朋友知道更准确的原因,可以留言。感谢大家阅读。
unity3d和虚幻4哪个好有什么区别
unity3d和虚幻4比较:
首先,UE4在各方面都优于Unity,毕竟它是顶级引擎。但开发游戏的成本太高了。小团队负担不起。你有吗?虚幻4难以优化,界面深度,开发速度慢,一批多少公司开发半死不活,更不用说需求变化如此之快,唯一的好处是下一代工作流现在比Unity更好
Unity开发速度快,通用,未来有HDRP管道,ECS支持,我看好Unity,并且优化灵活。Unity的优势是做手机游戏,但在目前的国内形势下,版本号的审批速度慢得像蜗牛。许多小型游戏公司倒闭了。
在这两者之间,可能是虚幻引擎,以下是原因。
1. 引擎开发团队制作了游戏,并在主流游戏中同时设置了所有可能的凹坑,以确保所有人都能使用这些内容,并且不会出现巨大的凹坑。
2. 将源代码开放给全世界,让每个人都来挑洞和提供更新的想法,收集所有人的想法,积极吸收社区的意见,每次更新平均间隔2个月左右,更新~个功能,不断得到反馈和修复。
3.持续追求未来的探索,集团率先支持VR、AR、引擎参与**(如星球大战)、大型活动预演,未来参与度高。游戏公司拥有自己的首席数学家,这算哪门子团队?
4.虚幻引擎不收费,直到你赚钱