0%

unity学习总结

最近学了下Unity,先跟官方教程走了个3D碰撞球的小游戏的教程。然后实现了“合成同学小游戏“,借鉴合成大西瓜的游戏机制。

Unity介绍

unity是一个游戏引擎,帮助快速开发游戏。个人觉得unity的一大优势是跨平台编译(虽然其它平台也可能有跨平台编译),比如”合成同学小游戏“是2D休闲类游戏,第一需求是就是便捷性,因此web是最合适的平台。

Unity WebGL编译

unity WebGl编译可以直接产出js、data、css、html、wasm和图片使游戏可以直接运行在web端。

在编译对象的时候有三种压缩方式br、gzip和不压缩。br是google提出的web内容压缩格式压缩率最高也是unity默认的格式。我摸索的上线模式就是把这些生成的内容以http文件传输的方式提供给客户端访问。既然br(Brotli)的压缩率最高自然而然就作为了第一选择,但我在使用过程中遇到了一些问题,最终选择了更稳定的gzip,下面讲一下具体原因。

safari使用不灵?使用br压缩方式遇到的问题

因为上线服务的方式就是把编译出的js、data、css、html放到服务器服务,这些编译内容以index.html为核心组织,客户端GET domain:port/index.html后index.html中的js代码会在客户端浏览器执行对其它js、data、css资源进行GET请求。当所有内容正确在客户端载入时游戏就可以玩了。

但对于内容的压缩格式,在http协议中要客户端和服务端要对压缩格式进行约定。

1
2
3
客户端先发起请求在Header中添加:
Accept-encoding:br, gz
代表接受的压缩编码格式
1
2
3
服务端在返回的Header中添加:
content-type:application/js 或其他的text/css
Content-encoding: br

但我在使用python写了一版br http服务端代码后发现window上能正常运行,但在Safari上客户端的http请求Accept-encoding没有br),怀疑是兼容性问题,遂搁置问题转向gzip。

https://github.com/Bigpop/Unity-webGL-Server.git

Unity editor

“下面来聊聊unity本身”

unity editor本身由六大部分组成

1591643009468_.pic_hd

1.hierarchy

2.project

3.console

4.game

5.scene

6.inspector

从游戏角度看组织结构如下:

scene

​ gameObject1

​ component1(transform)

​ component2(rigidbody)

​ component3(collier)

​ component4(C# script)

​ gameObject2

​ gameObject2

unity中的类和实例

类和实例是在编程中一个常见的概念关于类和实例:

1.在代码中通过Instantiate()函数实例化(Instantiate中传入的也是实例,Instantiate返回对该实例的拷贝)

2.在unity中hierarchy中的内容都是实例,

3.C#脚本中声明并在inspector中拖拽赋值的实例变量

此外GameObject是类,gameObject是实例

刚体和碰撞

刚体(rigidbody)该component给游戏对象增加物理属性,如重力重量

碰撞(collider)只有两个游戏对象都启动这个component时才会检测到碰撞,碰撞分为两类

1.Collision,造成物理碰撞,可以在碰撞时执行OnCollision函数。

​ OnTriggerEnter

2.Trigger,取消所有物理碰撞,可以在碰撞时执行OnTrigger函数。

​ OnTriggerEnter、OnTriggerStay、OnTriggerExit

这两种方式通过在inspector中点击is trigger切换

实例间的通信

实例间的通信方法

1.A调用B的情况:

​ 1.1 GameObject.Find(“B”)得到所有名为B的实例的脚本对象通过其访问函数进行访问

​ 1.2 或者在Fruit脚本中增加 public Game;并将Game实例拖拽过去dd

​ 1.3 将B中要调用的内容使用static预实例化

2.A实例内产生B的情况:

​ 因为实例在脚本中instancelize 因此可以直接对该实例操作

遇到的其他问题

1.对象碰撞逻辑重复执行导致陷入死循环

问题描述:因为游戏逻辑是两个相同对象碰撞后合成一个更大的对象,但碰撞发生时两个对象都调用OnTriggerEnter2D分别产生的一个更大的对象,两个更大的对象又彼此碰撞无限循环

解决办法:在碰撞发生时通过object.GetInstanceID(),比较两个对象的id只有id更小的才能执行合并操作。

2.A和B、C同时碰撞

1581643009463_.pic_hd 预期1571643009462_.pic_hd 实际1561643009462_.pic_hd

问题描述:A和B、C同时碰撞生成了两个更大的对象,但预期是只能和其中一个发生碰撞合成一个更大的对象

解决办法:使用static建立了一个hash,key为实例id,在合并前先查看实例是否存在。合并在该hash中移除相应实例id