终于笔者的国庆余额不足,所以乖乖地回来给大家做教程了。
上回说到,预制件平地显身手,旋转脚本大放异彩。
这回讲,门头沟险遇碰撞体,C#祝你一臂之力。
那么,为了实现物体碰撞,我们势必需要建立不同的触发器Trigger来触发碰撞事件。如果不设立触发器,那么场上存在的cube和sphere由于各自都拥有自身的collider,我们的Ball可能会因为接触到地面而把地面拾取。那没了地面我们还玩个毛啊。
好的,那我们来给我们的Ball添加这个触发器。我们打开
MoveController,我们要写点什么呢。我们可以键入Trigger,然后使用Ctrl+‘查询帮助。但是我们也可以使用另一种方法。
选中Ball组件,我们可以看见Inspector序列之下,的Sphere Collider选项边上有一本带着问号的小书
点中它。是的,你能够查询到Sphere这个基本体的使用说明,和许多属性
看见右上角的convert to script了没,戳她,嘿嘿嘿,我们又到了喜闻乐见的查阅函数环节。
既然知道我们需要的是Trigger事件,那请同学们自行查找函数(messages下的OnTriggerEnter)
好的,我们现在得到了一个道具
仔细地阅读一下,上面的这个函数OnTriggerEnter的作用似乎是——将触碰到的Collider存入Other变量中,然后通过Destroy函数摧毁它。
所谓的Destroy摧毁 ,是将该物体及其子对象和所有组件从场景中移除。
这段代码能够检测到碰撞,但是本身并不会产生物理碰撞。
来,把代码拷贝下来,扔到我们的脚本中,当然我们并不是很需要这些功能(=-=都说了叫做sample,当然是要修改的咯)
碰到一个东西直接移除太过暴力了一点,我们应该使用的是禁用当前物体,关于如何禁用当前物体,我们需要检索一下关键字GameObject。
需要如下两个道具
通过标签判别当前物体
设定是否被禁用
有了这么些个东西,那我们就很好做事了
void OnTriggerEnter(Collider other) {
//Destroy(other.gameObject);
if (other.gameObject.tag == "Coins")
other.gameObject.SetActive (false);
}
很简单的一个条件判断语句,通过tag来禁用物体,当然我们当前还没有设置tag,将脚本保存,打开预制件的标签选项卡
目前是未标签状态,点选Add tag标签,自定义一个叫做Coins的标签。
然后我们再次打开预制件,就能发现标签选项中已经存在Coins了,选择它。
这时候,预制件的好处就体现出来了,我们只需要给预制件绑定一个tag,他的所有实例对象都跟着一起变化了,查看一下,是不是?
好的= =我们来播放一下,成功了!!!这怎么可能=A=,哈哈哈哈哈哈哈哈哈!!!!
会发现还是碰撞而并没有产生拾取=-=这是为什么?难道我写错了嘛、、、
怎么会,这里涉及到了一个巨大的问题,不想了解内幕的童鞋自行跳过以下蓝色字体(真跳过你就亏大了)
Unity的物理引擎系统
在视窗中按下ctrl见同时选中Ball和一个Coin,然后在Inspecter中将Mash Render(网格渲染器)关闭 。能够看见留在画面中的是两个绿色的小格子
那么我们该知道,物理引擎中是不允许两个碰撞器(体)发生重叠的,正是因为这样所以才能够产生虚拟碰撞。当两个或者多个以上的物体发生碰撞的时候,Unity会按照他们的速度来计算出碰撞的结果。
然而计算的一项重要依据就是物体的碰撞器到底是static(静态)还是Dynamic(动力学的)。
Static的物体在计算碰撞的时候并不会受到影响,反之Dynamic的物体就会。就好像小球撞到了墙上,墙不动,小球会被弹开。在我们的画面中,动态的小球碰到旋转的方块(虽然在旋转但他是静态的,你就当是一个电视在放动画= =,反正就是
不具备动力学原理!!!!这个涉及到Unity的三种碰撞模式,静态碰撞,刚体碰撞和动态物理学碰撞,我会在文章的最后给出链接。)小球被弹开二coins依旧旋转。(旋转旋转,在这光滑的地板上旋转!!!)
;i另一个要注意的地方是,当碰撞体发生重叠的时候物理引擎通常会计算碰撞体的体积并且追踪碰撞器的重叠,但是不会在重叠的物体上以物理的形式表现出来,因为这并不算是一个碰撞。
为了事项碰撞,我们将碰撞体放置在触发器中,就叫做触发式碰撞器。这样我们就可以通过OnTriggerEvent返回的信息来检测是否发生了碰撞事件。
触发式碰撞器能够完成许多智能效果,比如我们在游戏中将触发式碰撞器放置在NPC旁边,玩家靠近后,NPC可以自动向玩家交代故事剧情。
此处我们使用的是onTriggerEnter而非onCollisionEnter,所以我们需要将碰撞器的体积设置为触发器的体积,这样才能实现拾取的效果。而这个也很简单,在预制件的Box Collider选项中,将isTrigger勾选上
然后就能看见我们期待的结果噜!!
是不是很简单呢。
好的今天的课程就到这里还没有结束= =3333333333333333333(其实已经可以下课了,学有余力的同学请继续往下看)
光是这个样子是不能满足我强迫症患者的,在上面的情况下,其实还存在一些小小的问题,这里就不得不提一下Unity优化物理。
为了优化性能,Unity会将场景上的所有物体信息,包括静态物体都保存到Cash当中,对于静止的物体而言有了这些信息,就不再需要在每一帧重新绘制。而我们的错误就在于让这些
static物体进行了旋转,当静止的碰撞器发生了变化的时候,Unity会再次计算他们,并重新上传到Cash中去。这样的重复计算会占用cash资源,而动态的物体则不会发生上述的情况。
Unity已经预料到我们会移动这些碰撞器了,所以只需要在移动碰撞器之前告诉Unity哪些是动态的。我们通过添加刚体Rigibody来完成这个行为。所有包含有Rigidbody的组件会被当做动态物体
,反之则为静态物体。我们的Coins含有碰撞器,但是没有刚体,所以会被重复计算并占用Cash。
解决方案也很简单,给俺们添加刚体,这样他们就会从静态变为动态。保存然后播放,可以看到coins全部掉下去了。
这是因为勾选了重力,而他们本身是触发器所以没有碰撞。所以把重力去掉。
那么,今天啰啰嗦嗦一大堆好像应该赢来了完结。可惜啊可惜,我们发现去掉了重力之后,竟然回到解放前,又不能拾取了,因为现在的coins是动态的,当然之前那套静态的方法需要有所改变。
看到Gravity选项之下有一个is Kinematic(动态的) 了没,还记得第一节课阮同学问为什么移动可以用力而不是transform,选上他之后,你就不能通过施加力的方式来使物体移动了。因为
运动刚体碰撞器是不能加力的,只能修改他的transform才能移动。所以之前我在讲台上小球不能动是因为雷哥把这个东西给我选上了。
由于运动碰撞刚体不会对物理作用有反应,只会依据transform移动对于有碰撞器的许多物体很有用,比如移动的平台(电梯?船?)
好了保存一下,我们今天的任务就真的完完全全告一段落了!今天的内容有点多,请务必仔细消化(尤其是两段拓展内容)
当然上面搞来搞去你依旧不是很懂还是很糊涂的三种碰撞方式,不懂就戳我!!!!
下回请听,计数加分不算难,骨骼动画一起玩!
最后,依旧是课下提问时间
敢问北京卤煮哪家强?东四小街爽又爽!(蒸吃友一道去)
我是小苹果,大家明天见