OnTrrigerEnter与OnCollisionEnter、OnControllerColliderHit、Rigidbody、CharacterController

1,测试OnTriggerEnter和OnCollisionEnter的区别

测试:如果两个物体A,B 

两者都有碰撞体collider(Box Collider,Sphere Collider,Capsule Collider等)

A,B都有刚体(Rigidbody)

A或者B中有一个勾选isTrigger或者两者都勾选isTrigger A和B都可以进入OnTriggerEnter方法,但是不可进入OnCollisionEnter方法。

A和B都不勾选isTrigger,A和B能进入OnCollisionEnter方法但是不能进入OnTriggerEnter方法。

结论:

OnCollisionEnter方法必须是在两个碰撞物体都不勾选isTrigger的前提下才能进入,反之只要勾选一个isTrigger那么就能进入OnTriggerEnter方法。

OnCollisionEnter和OnTriggerEnter是冲突的不能同时存在的。

2,OnTriggerEnter和OnCollisionEnter的选择。

如果想实现两个刚体物理的实际碰撞效果时候用OnCollisionEnter,Unity引擎会自动处理刚体碰撞的效果。

如果想在两个物体碰撞后自己处理碰撞事件用OnTriggerEnter。

3,一些技巧。

3.1:刚体(Rigidbody)的使用。

     两个碰撞的物体A 和 B

     现在我们就可以分两种模式来分析了,就是OnTrigger模式和OnCollision模式,因为上面已经详细介绍了两者是对立的模式, 

     在OnCollision模式下:

     测试1:如果只有A有刚体(Rigidbody),那么当A去碰撞B时,发现A弹开B没有动。A和B都进入OnCollisionEnter方法

     结论1:只有刚体能实现真实的物理碰撞。

     测试2:如果只有A有刚体(Rigidbody),那么当B去碰撞A时,发现没有碰撞效果,A和B都没有进入OnCollisionEnter方法。

     结论2:实现碰撞的条件是,发起碰撞方必须具有刚体。

     这里我猜测了刚体是用来实现物理真实碰撞的Component,但是这个想法是错误的,因为OnTriggerEnter也必须有一个物体具有刚体,所以猜测刚体应该是一个判断是否实现碰撞的是与否的标志。

     在OnTrigger模式下:

     A和B必须有一个有刚体(Rigidbody),A和B都可以进入OnTriggerEnter方法。

4,知识扩展。

上面的内容中有的实验是A,B有一个有刚体,有的实验是A,B都有刚体,那么为什么不干脆把两个物体都加刚体就没这么多麻烦了?

其实是这样的,真实游戏里面,有太多的物体,而这些物体如果都有刚体那么对系统的开销是很大的,如果可以减少一半的开销是很不错的选择。

比如地面就可以不设置刚体,因为地面是永远不动的,把人物设置刚体就可以实现真实的物理碰撞效果了。

CharacterController.OnControllerColliderHit 控制碰撞器碰撞 

function OnControllerColliderHit (hit : ControllerColliderHit) : void

Description描述

OnControllerColliderHit is called when the controller hits a collider while performing a Move.

当控制器碰撞一个正在运动的碰撞器时,OnControllerColliderHit 被调用。

This can be used to push objects when they collide with the character

这个可以被用于推动物体,当他们碰撞角色时。

  • C#//OnControllerColliderHit 此函数要挂载在角色控制器CharacterController上。
using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
	public float pushPower = 2.0F;
	void OnControllerColliderHit(ControllerColliderHit hit) {
		Rigidbody body = hit.collider.attachedRigidbody;
		if (body == null || body.isKinematic)
			return;

		if (hit.moveDirection.y < -0.3F)
			return;

		Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
		body.velocity = pushDir * pushPower;
	}
}
刚体Rigidbody
       是让GameObject能够按照真实的物理规律运动。不再使用Transform组件移动或旋转物体,而是用力(force)!如重力、摩擦力、恒定力等。


角色控制器Character Controller
       主要用于第一或第三人称控制中。它对外界施加的力不作反应,也不自动的把其他的刚体推开(刚体组件撞上另一个刚体会对其施加力)。如果你想推开其他刚体,或在碰到其他刚体时作出反应,需要重载 OnControllerColliderHit() 函数并实现你的逻辑。角色控制器和Collider不能同时存在,可以与Rigidbody同时存在,如果不要求对物理力做出真实的反应的话,它可以取代Rigidbody和Collider。


碰撞器和触发器

碰撞器和触发器的区别在于Collider的isTrigger 参数是true or false ,如果是true,那它就是一个触发器,可以被穿透,对应函数为OnTriggerEnter,OnTriggerExit,OnTriggerStay;如果值为false,那它就是一个碰撞器,不可被穿透,在碰撞时调用OnCollisionEnter,OnCollisionExit,OnCollisionStay 函数,其函数的参数为Collision类,类中包括接触点,接触速度等信息。

CharacterController.OnControllerColliderHit 控制碰撞器碰撞

function OnControllerColliderHit (hit : ControllerColliderHit) : void

Description描述

OnControllerColliderHit is called when the controller hits a collider while performing a Move.

当控制器碰撞一个正在运动的碰撞器时,OnControllerColliderHit 被调用。

This can be used to push objects when they collide with the character

这个可以被用于推动物体,当他们碰撞角色时。

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
	public float pushPower = 2.0F;
	void OnControllerColliderHit(ControllerColliderHit hit) {
		Rigidbody body = hit.collider.attachedRigidbody;
		if (body == null || body.isKinematic)
			return;

		if (hit.moveDirection.y < -0.3F)
			return;

		Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
		body.velocity = pushDir * pushPower;
	}
}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 脚本概览 这是一个关于Unity内部脚本如何工作的简单概览。 Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的。在脚本对象内部不同志的函数被特定的事件调用。最常用的列在下面: Update: 这个函数在渲染一帧之前被调用,这里是大部分游戏行为代码被执行的地方,除了物理代码。 FixedUpdate: 这个函数在每个物理时间步被调用一次,这是处理基于物理游戏的地方。 在任何函数之外的代码: 在任何函数之外的代码在物体被加载的时候运行,这个可以用来初始化脚本状态。 注意:文档的这个部份假设你是用Javascript,参考用C#编写获取如何使用C#和Boo编写脚本的信息。 你也能定义事件句柄,它们的名称都以On开始,(例如OnCollisionEnter),为了查看完整的预定义事件的列表,参考MonoBehaviour 文档。 概览:常用操作 大多数游戏物体的操作是通过游戏物体的Transform或Rigidbody来做的,在行为脚本内部它们可以分别通过transform和rigidbody访问,因此如果你想绕着Y轴每帧旋转5度,你可以如下写: function Update(){ transform.Rotate(0,5,0); } 如果你想向前移动一个物体,你应该如下写: function Update(){ transform.Translate(0,0,2); } 概览:跟踪时间 Time类包含了一个非常重要的类变量,称为deltaTime,这个变量包含从上一次调用Update或FixedUpdate(根据你是在Update函数还是在FixedUpdate函数中)到现在的时间量。 所以对于上面的例子,修改它使这个物体以一个恒定的速度旋转而不依赖于帧率: function Update(){ transform.Rotate(0,5*Time.deltaTime,0);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值