Unity3D之Character Controller(CC)与GameObject的碰撞方法

Unity3d中参与碰撞的物体分2种类型:

一、发起碰撞的物体。

二、接收碰撞的物体。

1. 参与发起碰撞物体:Rigodbody, CharacterController 角色碰撞器。

2. 参与接收碰撞的物体:所有Collider .

工作的原理为:发生碰撞的物体中必须要有“发起碰撞”的物体。否则,碰撞不响应。

比如:两面墙都只用BoxCollider ,所以墙与墙之间无反应。

比如:一个带有Rigidbody属性的箱子,能落到带有MeshCollider属性的地面上。

比如:一个带有Rigidbody属性的箱子,可以被一个带有CharacterController 属性的人推着跑。

在所有Collider上有一个Is Trigger 的boolean型参数。

(If enabled, this Collider is used for triggering events, and is ignored by the physics engine.)

当发生碰撞反应的时候,会先检查此属性是否为true。

当激活此选项时,会调用碰撞双方的脚本 OnTrigger, 反之,脚本方面没有任何反应。

当激活is trigger = true,不会发生后续物理的反应。反之,发生后续的物理反应。

总结:Is Trigger 好比是一个物理功能的开关, 是要“物理功能”还是要“OnTrigger脚本”。

在Rigodbody 上有一个Use Gravity 的boolean型参数.

(Controls whether gravity affects this rigidbody.)

 

Unity 物理引擎,处理的一个细节:

当一个CharacterController不发生位置变化,一个Collier发生位置变化后,产生碰撞。将不会调用任何碰撞函数,也就是没有碰撞反应的。

物理引擎视为CharacterController无碰撞.

--------------------分隔线----------------------

 

现在就来考虑如何让GameObject(魔法球)主动碰撞到CC(人物), 碰撞到人物后,显示受击效果.

解决方案, 由上面的可知, 做出如下设置:

1:魔法球: Collider(合适的类型), Rigidbody(Use Gravity可以去掉)

2:人物: CC.

脚本:

在魔法球上添加脚本

    void OnCollisionEnter (Collision collision)
    {
        Debug.Log ("**** collision.gameObject.name***:" + collision.gameObject.name);        if(collision.gameObject.name == "Player")
        {
       // 发送攻击消息            SendAttackMsg();
       // 销毁魔法球
            Destroy (gameObject);
        }
    }


具体的一些,可以看 unity3d manual refrernce的东西,有几个表格在后面可以参考:

几个类型碰撞器:

1. 静态碰撞器: 就是只有碰撞器,但没有刚体的

2.刚体碰撞器: 带Rigidbody的碰撞器,这个是最基本的碰撞器

3.运动学刚体碰撞器: 带Rigidbody, 而且RigidbodyIsKinematic打勾的,注意这个碰撞器是不能加力的,只能修改他的transform才能移动

Triggers 触发器

仅需要选中Inspector中的IsTrigger属性选择框。触发器不受物理引擎控制,当和一个触发器发生碰撞时会发出三个独特的触发信息,为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体.

 

今天遇到的一个情况是:如果刚体碰撞器不动,静态碰撞器去碰撞,则不会触发任何信息,而如果静态碰撞器不动,刚体碰撞器(包括运动学刚体碰撞器)去碰撞静态碰撞器,则会触发碰撞,如果是触发器,则会触发事件。所以下面的表格提供了触发的条件,但主动性大家也还需要注意,不然要纠结一段时间的。

 


Static Collider
静态碰撞器

Rigidbody Collider
刚体碰撞器

Kinematic 
Rigidbody Collider
运动学刚体碰撞器

Static 
Trigger Collider
静态触发碰撞器

Rigidbody 
Trigger Collider
刚体触发碰撞器

Kinematic Rigidbody 
Trigger Collider
运动学刚体触发碰撞器

Static Collider 静态碰撞器

Y

Rigidbody Collider 刚体碰撞器

Y

Y

Y

Kinematic Rigidbody Collider
运动学刚体碰撞器

Y

Static Trigger Collider
静态触发碰撞器

Rigidbody Trigger Collider
刚体触发碰撞器

Kinematic Rigidbody Trigger Collider
运动学刚体触发碰撞器



 

Static Collider
静态碰撞器

Rigidbody Collider
刚体碰撞器

Kinematic 
Rigidbody Collider
运动学刚体碰撞器

Static 
Trigger Collider
静态触发碰撞器

Rigidbody 
Trigger Collider
刚体触发碰撞器

Kinematic Rigidbody 
Trigger Collider
运动学刚体触发碰撞器

Static Collider 静态碰撞器

Y

Y

Rigidbody Collider 刚体碰撞器

Y

Y

Y

Kinematic Rigidbody Collider
运动学刚体碰撞器

Y

Y

Y

Static Trigger Collider 静态触发碰撞器

Y

Y

Y

Y

Rigidbody Trigger Collider
刚体触发碰撞器

Y

Y

Y

Y

Y

Y

Kinematic Rigidbody Trigger Collider
运动学刚体触发碰撞器

Y

Y

Y

Y

Y

Y

 

 

下面就是我做的测试情况,都是A物体去撞B物体。

一、A(碰撞体),B(没有碰撞体,无论有没有刚体),没有触发事件。

二、A(碰撞体),B(碰撞体),没有触发事件。

二、A(碰撞体和刚体,开启IsTrigger),B(碰撞体,关闭IsTrigger),双方都能收到触发事件。

三、A(碰撞体和刚体,关闭IsTrigger),B(碰撞体,开启IsTrigger),双方都能收到触发事件。

四、A (碰撞体,关闭IsTrigger),B(碰撞体和刚体,开启IsTrigger),没有触发事件。

五、A (碰撞体,开启IsTrigger),B(碰撞体和刚体,关闭IsTrigger),没有触发事件。


额外实验:

六、A(碰撞体和刚体,开启IsTrigger)自由下落,B(碰撞体)撞击A,双方都能收到触发事件。


根据上面的实验得出,如果要收到触发事件,必须满足如下三个条件:

1、必须都要有碰撞器组件(Collider),其实上面的碰撞事件同样也需要这个前提条件。

2、必须有一个物体带刚体组件,并且处于运动状体中(包括主动运动去撞击别人和在运动过程中被别人撞击)。

3、两个碰撞器中至少有一个开启了IsTrigger。


此外还有两点:

一、产生触发事件的两个物体会相互穿越,准确的说是因为开启IsTrigger那个物体会被物理引擎锁忽略掉,所以会产生两个物体穿越的情况。

二、两个对象要么都收到碰撞事件,要么都收到触发事件,不会出现一个收到触发事件,一个收到碰撞事件的情况。


还有一个经验点就是,在控制一个物体A去撞另一个物体B时,不要直接去修改物体A的Transform的position属性,因为你会发现如果即使两者发生了碰撞也还是会穿越的,原因就在于我们是直接设置的坐标,如果物体A有刚体组件的话,应该用AddForce,给物体添加一个力,然后让物理引擎去让物体动,此时如果发生了碰撞的话,就不会穿越了。


好吧,下午折腾了半天之后,我就一直在想那个IsTrigger有啥用,后来在网上搜了一下,说是可以做门的自动打开,就让我想起了Unity3d 4自带的哪个AngryBots例子,貌似当控制主角走到一个门前时,那个门会自动打开。

你可能感兴趣的:(Unity3D之Character Controller(CC)与GameObject的碰撞方法)