2017-11-07 20:38:47 dongkaixuan 阅读数 365
  • Unity3D物理系统实战入门

    本课程深入浅出的介绍Unity3D物理引擎系统的概念,向初学者展示Unity3D物理引擎常见的编程思路和使用方式,与此同时,引领学习者逐步完成一款经典的关卡类物理引擎小游戏《Marble Drop》,详细展示如何根据项目的实际需求搭建简单而准确的物理组件和模块,对之前的理论知识进一步巩固和熟习。

    601 人正在学习 去看看 伍晓波

第五章 物理引擎

刚体

简述:

带有刚体组件的游戏物体

Add Component physics Rigidbody

刚体(rigid body)组件可使游戏对象受物理引擎控制,在外力产生真实的物理特性。

想让物体仿真,就加刚体

Ø  属性

质量 Mass :物体的质量。

阻力 Drag :当受力移动时物体受到的空气阻力。0表示没 有空气阻力,极大时可使物体停止运动,通常砖头0.001羽毛设置为10

角阻力 Angular Drag:当受扭力旋转时物体受到的空气阻 力。0表示没有空气阻力,极大时使物体停止旋转。

使用重力 Use Gravity激活,则物体受重力影响

是否是运动学 Is Kinematic :若激活,该物体不再受物理 引擎控制,而只能通过变换组件来操作。

插值 Interpolate:用于缓解刚体运动时抖动

      无 None --不应用插值。

      内插值 Interpolate --基于上一帧的变换来平滑本帧变换。

      外插值 Extrapolate --基于下一帧的预估变换来平滑本帧 变换。

    •碰撞检测 Collision Detection :碰撞检测模式。快速移动的刚体在碰撞时有可能互相穿透,可以设置碰撞检测频率, 但频率越高对物理引擎性能影响越大。    

    不连续 Discrete :不连续碰撞检测。适用于普通碰撞(默 认模式)。

    连续 Continuous :连续碰撞检测

动态连续 Continuous Dynamic  :连续动态碰撞检测,适用 于高速物体。

 

约束Constraints :对刚体运动的约束。

    冻结位置Freeze Position :刚体在世界中沿所选X,Y,Z 轴的移动,将无效。

    冻结旋转 Freeze Rotation :刚体在世界中沿所选的X,Y,Z轴 的旋转,将无效。

碰撞器

Ø  简介

•使刚体具有碰撞效果

•可以单独作用于物体,但是要使移动的物体具有碰撞效果 必须附加刚体组件。

Ø  分类

• 静态碰撞器 Static Collider :只有碰撞器没有刚体的物体

现象保持静止或者轻微移动,如:平面/树木

• 刚体碰撞器 Rigidbody Collider:具有刚体和碰撞器的物体

现象:完全受物理引擎影响

• 运动学刚体碰撞器: 带刚体,且勾选Is Kinematic,此碰撞器

不能添加力,只能通过transform移动。

Ø  属性

• 是否触发器 Is Trigger :如激活,此碰撞器用于触发事件

且被物理引擎忽略

• 材质Material :引用何种物理材质决定了他和其他对象如

何作用。

• 凸起的Convex :不激活则网格碰撞器间没有碰撞效果;

• Mesh 网格:用于碰撞所引用的网格

Ø  物理材质

• 用于调整碰撞对象摩擦力反弹效果

• 属性

动态摩擦力 DynamicFriction移动时摩擦力

静态摩擦力 StaticFriction静止时摩擦力

弹力 (Bounciness):反弹程度

备注:摩擦力、弹力建议0---1之间

摩擦力合并模式 Friction Combine Mode

合并反弹 Bounce Combine

两个碰撞对象摩擦力/弹力的合并方式

平均值Average 最小 Min 最大 Max 相乘Multiply

 

 

 

Ø  碰撞条件!!!

两者具有碰撞组件

运动的物体具有刚体组件

Ø  碰撞三阶段

Collision事件参数类 包含了引发事件时的相关信息,包含了对方的碰撞器

只要碰撞就会执行下面的方法    字母必须一致

1  当进入碰撞时执行    

voidOnCollisionEnter(Collision collOther)//注意不能和下边触发器的Collider弄错

2  当碰撞体与刚体接触时每帧执行

voidOnCollisionStay(Collision collOther)

3  当停止碰撞时执行

voidOnCollisionExit(Collision collOther)

 

other.contacts[0].point   碰撞点的世界坐标

other.contacts[0].normal  碰撞面的法线

Ø  代码引入

//满足碰撞条件的第一帧执行

    private void OnCollisionEnter(Collisionother)

    { //other 事件参数类:包含了引发事件时的相关信息。

        //对方的碰撞器组件

        Debug.Log("Collision:"+other.collider);

        //碰撞点的世界坐标

        //other.contacts[0].point

        //碰撞面的法线

        //other.contacts[0].normal

    }

    //满足触发条件的第一帧执行

    private void OnTriggerEnter(Collider other)

    { //other 事件参数类:包含了引发事件时的相关信息。

        //就是对方的碰撞器组件

        Debug.Log("Trigger:" + other);

    }

触发器

Ø  简介

• 带有碰撞器组件,且Is Trigger属性被勾选的物体 。

• 现象:无碰撞效果。

Ø  触发条件!!!

两者具有碰撞组件

• 其中之一带有刚体组件

• 其中之一勾选 isTrigger

Ø  触发三阶段

当Collider(碰撞体)进入触发器时执行

void OnTriggerEnter(Collider cldOther)

• 当碰撞体与触发器接触时每帧执行

void OnTriggerStay(Collider cldOther)

• 当停止触发时执行

void OnTriggerExit (Collider cldOther)

 

相关应用

案例一:  适合速度慢不知道打谁的物体   用触发器

缺点:用触发检测速度过快的物体不合理

每帧才做一次碰撞(触发)检测,如果物体速度太快,很容易直接越过要碰撞的物体,而检测失败。前一帧不在,后一帧就过了。

解决方案:运动前,就确定好与谁发生碰撞,然后朝向目标点移动。

 

public float moveSpeed = 80;

    privatevoid Movement()

    {

       transform.Translate(0, 0, Time.deltaTime * moveSpeed);

    }

    privatevoid Update()

    {

       Movement();

    }

    privatevoid FixedUpdate()

    {

       Debug.Log(transform.position);

    }

    //当前子弹与其他碰撞器接触时执行

    privatevoid OnTriggerEnter(Collider other)

    {

       Destroy(this.gameObject);

}

案例二:适合高速且躲也躲不掉的物体(子弹)

一、一种对方物体不动,则只需发射一根射线

二、如果对方物体移动,可能打不到,就每帧发射线,射线长度跟速度成正比

像射击类游戏,可以不加子弹,只需做一个弹道就可,省性能。

高速运动的物体,很可能碰撞(触发)检测失败

解决方案:运动前(Start)就确定到与谁发生碰撞,然后朝向目标点移动。

代码:

    public LayerMask layer;

    privateVector3 targetPos;

    privatevoid Start()

    {

       RaycastHit hit;

        //投射射线(起点,方向,结果,距离,参与检测的层)

       if(Physics.Raycast(transform.position, transform.forward, out hit, 500,layer))

        {

            //有目标 

           targetPos = hit.point;//得到检测到的目标点

        }

       else

        {

           //没有目标

           targetPos = transform.TransformPoint(0, 0, 500);//返回前方500m处的点

        }

    }

    privatevoid Update()

    {

       Movement();

        //如果接近目标点,则销毁物体

       if((transform.position - targetPos).sqrMagnitude<0.1f)

        {

           Destroy(this.gameObject);

        }

    }

    privatevoid Movement()

    {

       transform.position = Vector3.MoveTowards(transform.position, targetPos,Time.deltaTime * moveSpeed);//已知目标点的移动,用MoveTowards

    }

关节

关节分类:

铰链关节(最常用)

弹性关节(常用)

固定关节(常用)

角色关节

可配置关节

铰链关节Hinge Joint

铰链关节:将两个刚体(Rigidbody) 组合在一起,从而将其约束为如同通过铰链连接一样进行移动。它十分适合门,也可用于对链条、钟摆等进行模拟效果。

铰链关节组件属性:

属性:                     功能:

•连接体(Connected Body):对关节(Joint) 所依赖的刚体(Rigidbody) 的可选引用。如果未设置,则关节(Joint) 连接到世界坐标。

•锚点(Anchor):主体围绕其摇摆的轴的位置。

•轴(Axis):主体围绕其摇摆的轴的方向。

•使用弹簧(Use Spring):启用使用弹簧属性。

•弹簧(Spring) :对象为移动到位所施加的力。   弹簧力度

•目标位置(Target Position):使刚体(Rigidbody)相对于其连接体达到特定角度。

•阻尼(Damper):此值越高,对象减慢的幅度越大。

•使用电机(Use Motor):启用使用电机(Use Motor) 时使用的电机(Motor) 的属性。

•目标速率(Target Velocity):对象尝试达到的速度。      两个一起用,力度

•力(Force):为达到该速度而应用的力。               达不到速度也达不到

•自由旋转(Free Spin):如果启用,则电机从不用于对旋转制动,仅进行加速。

•使用限制(Use Limits):如果启用,则铰链角度会限制在最小(Min) 和最大(Max)值内。

•限制(Limits):启用使用限制(Use Limits)s 时使用的限制(Limits) 的属性。

•最小(Min):旋转可以达到的最小角度。

•最大(Max):旋转可以达到的最大角度。

•最小反弹(Min Bounce):对象在命中最小停止时反弹的量。

•最大反弹(Max Bounce):对象在命中最大停止时反弹的量。

•折断力(Break Force):为使此关节(Joint) 折断而需要应用的力。 超过该力会断掉与父物体的关系

•折断扭矩(Break Torque):为使此关节(Joint) 折断而需要应用的扭矩

•启动碰撞Enable Collision :如果启用,将启用与绑定物体之间的碰撞效果

撞门效果:谁撞门给谁

public class DoorForce : MonoBehaviour

{

    privatevoid OnCollisionStay(Collision other)

    {

       if(other.collider.tag == "Door")

       {   //在身体斜上方为门添加一个500的力  other.transform.GetComponent<Rigidbody>().AddForce((transform.forward+ transform.up)* 500);

        }

    }

}

固定关节Fixed Joint

固定关节将对象移动限制为依赖于其他对象。这在某种程度上类似于父子化,不过是通过物理而不是变换层级结构来实现。使用它们的最佳情况是在具有要方便地相互分离的对象,或是连接两个对象的移动而不进行父子化时。

固定关节组件属性:

属性:              功能:

连接体(ConnectedBody):对关节(Joint)所依赖的刚体(Rigidbody)的可选引用。如果未设置,则关节(Joint)连接到世界坐标。

折断力(BreakForce):为使此关节(Joint) 折断而需要应用的力。

折断扭矩(BreakTorque):为使此关节(Joint) 折断而需要应用的扭矩。

启动碰撞EnableCollision :如果启用,将启用与绑定物体之间的碰撞效果。

弹性关节 Spring Joint

弹簧关节将两个刚体(Rigidbody) 组合在一起,从而将其约束为如同通过弹簧连接一样进行移动效果。

弹性关节组件属性:

属性:                    功能:

连接体(ConnectedBody):对关节所依赖的刚体(Rigidbody) 的可选引用。

锚点(Anchor):对象局部坐标空间中定义关节中心的位置(静止时)。这不是将对象拉向的位置。

弹簧(Spring):弹簧的强度。

阻尼(Damper):弹簧在处于活动状态时缩减的量。

最小距离(MinDistance):大于此值的距离不会使弹簧激活。

最大距离(MaxDistance):小于此值的距离不会使弹簧激活。

折断力(BreakForce):为使此关节折断而需要应用的力。

折断扭矩(BreakTorque):为使此关节折断而需要应用的扭矩。

启动碰撞EnableCollision :如果启用,将启用与绑定物体之间的碰撞效果

给刚体添加力

•rigidbody.AddForce(Vector3.forward*500);

•//世界坐标前方(Z轴)方向添加一个500的力。

•rigidbody.AddForce(transform.forward*500);

•//自己的坐标前方(Z轴)方向添加一个500的力。

 

练习;子弹检测

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

 

public class Bullet : MonoBehaviour {

 

    // Use thisfor initialization

     RaycastHit hit;

    public LayerMask layer;

    private Vector3 targat;

 

    public float MoveSpeed =5;

 

    void Start ()

    {

        if (Physics.Raycast(transform.position,transform.forward, out hit, 500, layer))

        {

           targat =hit.point;

        }

        else

        {//如果没有检测到目标

            targat =transform.TransformPoint(0, 0, 500);

        }

    }

      

       // Update iscalled once per frame

       void Update ()

    {

       transform.position = Vector3.MoveTowards(transform.position, targat, Time.deltaTime *MoveSpeed);

        if((transform.position - targat).sqrMagnitude <= 0.1f)

        {

           Destroy(hit.transform.gameObject);

            Destroy(this.gameObject);

        }

       }

}

2015-06-27 17:12:59 qq_27880427 阅读数 3000
  • Unity3D物理系统实战入门

    本课程深入浅出的介绍Unity3D物理引擎系统的概念,向初学者展示Unity3D物理引擎常见的编程思路和使用方式,与此同时,引领学习者逐步完成一款经典的关卡类物理引擎小游戏《Marble Drop》,详细展示如何根据项目的实际需求搭建简单而准确的物理组件和模块,对之前的理论知识进一步巩固和熟习。

    601 人正在学习 去看看 伍晓波

添加关节Joints让刚体的行为更加复杂。比如,你可以制作一扇逼真的门或者是一台有摆动链条的吊机。

1.关节介绍

(1)铰链关节 Hinge Joint 铰链关节由两个刚体组成,约束它们像连在一个铰链上一样运动,适用于门,不过对于典型的链子、钟摆等同样适用。


属性

Connected Body 连接体 为刚体指定的关节连接物,如不设定,则与世界相连。

Anchor 锚点 主体摇摆围绕的锚点坐标,基于本地坐标系

Axis 坐标轴 摇摆方向的坐标,基于本地坐标系

Use Spring 是否使用弹簧 弹簧使刚体相对它连接的主体达到一个特定的角度

Spring 弹力 维持对象移动到一定位置的力

Damper 阻尼 值越大,对象移动越慢

Target Position 目标角度 弹簧的目标角度。弹簧拉向这个角度.(单位:角度)

Use Motor 是否使用马达。 Motor使对象旋转

Target Velocity 目标速率。对象设法达到的速度

Force

Free Spin 自由转动 如果启用,Motor永远不会破坏旋转,只会加速

Use Limits 是否有限制 如果启用,铰链的角度将被限制在最大和最小之间

Limits 限制 用于如启用Use Limits 的边界属性

Min 最小 最小角速度

Max 最大 最大角速度

Min Bounce 最小弹跳  物体碰触最小限制时的弹跳系数

Max Bounce 最大弹跳 物体碰触最大限制时的弹跳系数

Break Force 破坏力 可以使这个关节断开的力

//当一个力大于10时,是这个关节断开
    hingeJoint.breakForce = 10;
    // Makes the joint unbreakable
    //使该关节牢不可破
    hingeJoint.breakForce = Mathf.Infinity;

Break Torque 破坏扭矩 可以使这个关节断开的扭矩

Spring Joint 弹簧关节 弹簧关节是两个刚体组。制约它们就像弹簧一样。

      (2)Spring Joint 弹簧关节 弹簧关节是两个刚体组。制约它们就像弹簧一样。


属性

Min Distance 最小距离

Max Distance 最大距离

如果物体的位置在最小和最大距离之间,那么关节不会被应用到物体,位置必须在这些值之外,关节才会激活。

(3)固定关节 Fixed Joint

固定关节基于另一个物体来限制一个物体的运动。效果类似于父子关系,但是不是通过层级变换,而是通过物理实现的。使用它的最佳情境是当你有一些想要轻易分开的物体,或想让两个没有父子关系的物体一起运动。

(4)Character Joint

它可以模拟角色的骨骼关节,就好比人的手腕一样可以大氛围任意角度旋转。


(5)可配置关节 Configurable Joint

可配置关节是极其可定制的。可配置关节将PhysX引擎中所有与关节相关的属性都设置为可配置的,因此可以用此组件创造出与其他关节类型行为相似的关节.

可配置关节有两类主要的功能:移动/旋转限制和移动/旋转加速。这些功能取决于一系列相互依赖的属性。你可能需要进行一些试验来创建出你想要的行为。

功能概述:

Movement/Rotation Restriction 移动/旋转限制

你可以为每个的旋转轴和每个运动类型都指定约束。X轴平移(XMotion),Y轴平移(YMotion)和 Z轴平移(ZMotion)允许你定义沿不同轴的平移。X轴角运动(Angular XMotion)、Y轴角运动(Angular YMotion)和Z轴角运动(Angular ZMotion)允许你定义沿不同轴的旋转。这些属性可以被设置为Free (无限制),Limited (受限于用户定义的约束),Locked (没有运动)。

Limiting Motion 平移限制

如有某轴的平移属性被设置为受限制的,则可以设置物体在对应轴上平移的限制。可以通过改变边界属性的值来达到此目的。

对于平移运动(非角运动),线性限制属性(Linear Limit)定义了物体可以远离原点移动的最大距离。任何沿受限制的轴的运动都会受限于线性限制的属性(Linear Limit->Limit)。可以将此限制属性视为设定物体沿特定轴运动时所需遵从的边界。

反弹力(Bouncyness),弹簧力(Spring)和阻尼(Damper)定义了物体运动到其边界时的行为,这些参数在所有受限的平移轴上都是一样的。如果这三个参数的值都被设置为0,物体在到达边界后会立即停止运动。反弹力使得物体到达边界后反弹远离边界。弹簧力和阻尼利用弹簧的力量将物体拉回边界。这些参数能够软化边界,使得物体能够穿过边界后再被拉回来,而不是到达边界就立即停止。

Limiting Rotation 旋转限制

旋转限制与平移限制几乎完全一样,除了角运动参数与不同的角度限制参数相关而不是与线性限制相关。在3个不同坐标轴上的平移限制由线性限制属性定义,而绕三个轴的旋转限制由不同的角度限制属性定义,每个轴有其不同的角度限制属性。

X轴上下限可以不同,Y和Z轴只能分别设置同样的数。

Movement/Rotation Acceleration 移动/旋转限制

可以用使物体到达特定的位置/朝向,或是到达特定的速度/角速度来指定物体的运动。此系统的工作方式如下:首先定义你期望达到的“目标”(Target),然后通过“驱动”(“Drive)产生加速度来使物体到达此目标。每个”驱动“都有定义物体的当前”目标“的模式(Mode)。

X轴驱动、Y轴驱动和Z轴驱动属性可以使物体沿特定的轴运动。每个驱动的模式指定了物体是朝目标位置运动还是朝目标速度运动或者两者都是。例如,如果设置X轴驱动的模式为位置,物体会朝目标位置->x进行运动。

当驱动的模式为位置时,其位置弹簧数值定义了物体如何向目标位置运动。同样的,当驱动的模式为速度时,其最大强度数值定义了物体如何向目标速度运动。

旋转加速度属性:X轴角驱动、YZ轴角驱动和插值驱动,这些驱动的功能与平移驱动功能基本相同。不同之处在于插值驱动与角驱动的表现出的功能不同。在旋转驱动模式中可以选择使用角驱动或是使用插值驱动,两者无法同时被使用。

部分属性

Axis 主轴 局部旋转轴,定义了物理模拟下物体的自然旋转。

Secondary Axis 副轴 主轴和副轴定义了关节的局部坐标系。第三个轴垂直于主轴和副轴。

Slerp Drive 插值驱动  定义关节如何绕所有局部旋转轴旋转。只有当旋转驱动模式为插值时才有效

Projection Mode 投影模式 当物体离开它受限的位置太远时让它迅速回到它受限的位置

Projection Distance 投影距离  当物体与其相链的肢体的距离差异超过投影距离后,物体才会迅速回到一个可接受的位置

Projection Angle 投影角度 当物体与其相链的肢体的角度差异超过投影角度后,物体才会迅速回到一个可接受的位置。

Congfigure in World Space在世界空间中配置

如果启用了此选项,所有与目标相关的计算都会在世界空间中进行而不是在物体的局部空间中进行

(6)Constant Force 恒力


恒力(Constant Force)是添加恒力到刚体的一个快速工具,对于一个子弹样物体(如火箭),它可以很好的工作,启动时没有很大的速度,而是慢慢加速。

Force 力 被施加的力在世界坐标中的矢量

Relative Force 相对力 被施加在对象上的力在本地坐标中的矢量

Torque 扭矩 施加在世界坐标中的扭矩矢量。对象将绕着该矢量转动。矢量越长,转速越快。

Relative Torque 相对扭矩 施加在本地坐标中的扭矩矢量。对象将绕着该矢量转动。矢量越长,转速越快

示例:

using UnityEngine;
using System.Collections;

public class JointTemp : MonoBehaviour
{
    //链接关节游戏对象  
    GameObject connectedObj = null;
    //当前链接的关节组件  
    Component jointComponent = null;

    void Start()
    {
        //获得链接关节的游戏对象  
        connectedObj = GameObject.Find("Sphere");
    }

    void OnGUI()
    {
        if (GUILayout.Button("添加链条关节"))
        {

            ResetJoint();
            jointComponent = gameObject.AddComponent("HingeJoint");
            HingeJoint hjoint = (HingeJoint)jointComponent;
            connectedObj.rigidbody.useGravity = true;
            hjoint.connectedBody = connectedObj.rigidbody;
        }

        if (GUILayout.Button("添加固定关节"))
        {
            ResetJoint();
            jointComponent = gameObject.AddComponent("FixedJoint");
            FixedJoint fjoint = (FixedJoint)jointComponent;
            connectedObj.rigidbody.useGravity = true;
            fjoint.connectedBody = connectedObj.rigidbody;
        }

        if (GUILayout.Button("添加弹簧关节"))
        {
            ResetJoint();
            jointComponent = gameObject.AddComponent("SpringJoint");
            SpringJoint sjoint = (SpringJoint)jointComponent;
            connectedObj.rigidbody.useGravity = true;
            sjoint.connectedBody = connectedObj.rigidbody;
        }

        if (GUILayout.Button("添加角色关节"))
        {
            ResetJoint();
            jointComponent = gameObject.AddComponent("CharacterJoint");
            CharacterJoint cjoint = (CharacterJoint)jointComponent;
            connectedObj.rigidbody.useGravity = true;
            cjoint.connectedBody = connectedObj.rigidbody;
        }

        if (GUILayout.Button("添加可配置关节"))
        {
            ResetJoint();
            jointComponent = gameObject.AddComponent("ConfigurableJoint");
            ConfigurableJoint cojoint = (ConfigurableJoint)jointComponent;
            connectedObj.rigidbody.useGravity = true;
            cojoint.connectedBody = connectedObj.rigidbody;
        }
    }

    //重置关节  
    void ResetJoint()
    {
        //销毁之前添加的关节组件  
        Destroy(jointComponent);
        //重置对象位置  
        this.transform.position = new Vector3(821.0f, 72.0f, 660.0f);
        connectedObj.gameObject.transform.position = new Vector3(805.0f, 48.0f, 660.0f);
        //不敢应重力  
        connectedObj.rigidbody.useGravity = false;
    }
}


2014-04-11 17:30:16 kuloveyouwei 阅读数 27733
  • Unity3D物理系统实战入门

    本课程深入浅出的介绍Unity3D物理引擎系统的概念,向初学者展示Unity3D物理引擎常见的编程思路和使用方式,与此同时,引领学习者逐步完成一款经典的关卡类物理引擎小游戏《Marble Drop》,详细展示如何根据项目的实际需求搭建简单而准确的物理组件和模块,对之前的理论知识进一步巩固和熟习。

    601 人正在学习 去看看 伍晓波

Unity内置了NVIDIA的Physx物理引擎,Physx是目前使用最为广泛的物理引擎,被很多游戏大作所采用,开发者可以通过物理引擎高效、逼真地模拟刚体碰撞、车辆驾驶、布料、重力等物理效果,使游戏画面更加真实而生动。

Rigidbody(刚体)组件可使游戏对象在物理系统的控制下来运动,刚体可接受外力与扭矩力用来保证游戏对象像在真实世界中那样进行运动。任何游戏对象只有添加了刚体组件才能受到重力的影响,通过脚本为游戏对象添加的作用力以及通过NVIDIA物理引擎与其他的游戏对象发生互动的运算都需要游戏对象添加了刚体组件。

依次打开GameObject->Create Empty,创建一个空游戏对象,然后选择该对象,打开菜单栏中的Component->Physics->Rigidbody,如下图:


Rigidbody组件的属性面板,如下图:


Mass:质量,该项用于设置游戏对象的质量

Drag:阻力,当对象受力运动时受到的空气阻力,0表示没有空气阻力,阻力极大时游戏对象会立即停止运动

Angular Drag:当对象受扭矩力旋转时受到的空气阻力,0表示没有空气阻力,阻力极大时游戏对象会立即停止运动

Use Gravity:使用重力,若开启此项,游戏对象会受到重力的影响

Is Kinematic:是否开启动力学,若开启此项,游戏对象将不再受物理引擎的影响从而只能通过Transform属性来对其操作

Interpolate:插值,该项用于控制运动的抖动情况,有3项可以选择,None:没有插值;Interpolate:内插值,基于前一帧的Transform来平滑此次的Transform;Extrapolate:外插值,基于下一帧的Transform来平滑此次的Transform

Collision Detection:碰撞检测,该属性用于控制避免高速运动的游戏对象穿过其他的对象而未发生碰撞,有3项可以选择,Discrete:离散碰撞检测,该模式与场景中其他的所有碰撞体进行碰撞检测;Continuous:连续碰撞检测;Continuous Dynamic:连续动态碰撞检测模式

Constraints:约束,该项用于控制对于刚体运动的约束

Collides碰撞体,碰撞体是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞。如果两个刚体相互撞在一起,除非两个对象有碰撞体时物理引擎才会计算碰撞,在物理模拟中,没有碰撞体的刚体会彼此相互穿过

选中游戏对象,打开菜单栏中的Component->Physics->。。。,如下图:


Box Collider:盒碰撞体,盒碰撞体是一个立方体外形的基本碰撞体,该碰撞体可以调整为不同大小的长方体,可用作门、墙、以及平台等,也可以用于布娃娃的角色躯干或者汽车等交通工具的外壳,当然最适合用在盒子或是箱子上,属性如下图:


Is Trigger:触发器,勾选该项,则该碰撞体可用于触发事件,并将被物理引擎所忽略

Material:材质

Center:中心,碰撞体在对象局部坐标中的位置

Size:大小,碰撞体再X、Y、Z方向上的大小

Sphere Collider:球形碰撞体,球形碰撞体是一个基于球体的基本碰撞体,球体碰撞体的三维大小可以均匀等地调节,但不能单独调节某个坐标轴方向的大小,该碰撞体适用于落石、乒乓球等游戏对象


Radius:半径,球形碰撞体的大小

Capsule Collider:胶囊碰撞体,胶囊碰撞体由一个圆柱体和与其相连的两个半球体组成,是一个胶囊形状的基本碰撞体,胶囊碰撞体的半径和高度都可以单独调节,可用在角色控制器或与其他不规则形状的碰撞结合来使用


Height:高度,该项用于控制碰撞体中圆柱的高度

Direction:方向,在对象的局部坐标中胶囊的纵向方向所对应的坐标轴,默认是Y轴

Mesh Collider:网格碰撞体,网格碰撞体通过获取网格对象并在其基础上构建碰撞,在与复杂网格模型上使用基本碰撞相比,网格碰撞体要更加精细,但会占用更多地系统资源


Smooth Sphere Collisions:平滑碰撞,在勾选该项后碰撞会变得平滑

Mesh:网格,获取游戏对象的网格并将其作为碰撞体

Convex:凸起,勾选该项,则网格碰撞体将会与其他的网格碰撞体发生碰撞

Wheel Collider:车轮碰撞体,车轮碰撞体是一种针对地面车辆的特殊碰撞体,它有内置的碰撞检测、车轮物理系统以及滑胎摩擦的参考体


Suspension Distance:悬挂距离,该项用于设置车轮碰撞体悬挂的最大伸长距离,按照局部坐标来计算,悬挂总是通过其局部坐标的Y轴延伸向下

Center:中心,该项用于设置车轮碰撞体在对象局部坐标的中心

Suspension Spring:悬挂弹簧,该项用于设置车轮碰撞体通过添加弹簧和阻尼外力使得悬挂达到目标位置

Forward Friction:向前摩擦力,当轮胎向前滚动时的摩擦力属性

Sideways Friction:侧向摩擦力,当轮胎侧向滚动时的摩擦力属性

Character Controller,角色控制器,角色控制器主要用于对第三人称或第一人称游戏主角的控制,并不使用刚体物理效果

character controller组件属性如下图:


Slope Limit:坡度限制,该项用于设置所控制的角色对象只能爬上小于或等于该参数值的斜坡

Step Offset:台阶高度,该项用于设置所控制的角色对象可以迈上的最高台阶的高度

Skin Width:皮肤厚度,该参数决定了两个碰撞体可以相互渗入的深度,较大的参数值会产生抖动的现象,较少的参数值会导致所控制的游戏对象被卡住,较为合理地设定上是:该参数值为Radius值的10%

Min Move Distance:最小移动距离,如果所控制的角色对象的移动距离小于该值,则游戏对象将不会移动

Center:中心,该参数决定了胶囊碰撞体再世界坐标中得位置,

Radius:半径,胶囊碰撞体的长度半径,

Height:高度,该项用于设置所控制的角色对象的胶囊碰撞体的高度

Interactive Cloth:交互布料,交互布料组件可在一个网格上模拟类似布料的行为状态

Skinned Cloth:蒙皮布料,蒙皮布料组件与蒙皮网格渲染器一起用来模拟角色身上的衣服,如果角色动画使用了蒙皮网格渲染器,那么可以为其添加一个蒙皮布料,使其看起来更加真实、生动

Cloth Renderer:布料渲染器


Hinge Joint:铰链关节,铰链关节由两个刚体组成,该关节会对刚体进行约束,使得它们就好像被连接再一个铰链上那样运动,它非常适用于对门的模拟,也适用于对模型及钟摆等物体的模拟

Fixed Joint:固定关节,固定关节组件用于约束一个游戏对象对另一个游戏对象的运动

Spring Jonit:弹簧关节,弹簧关节组件可将两个刚体连接在一起,使其像连接着弹簧那样运动

Character Joint:角色关节主要用于表现布娃娃效果,它使扩展的球关节,可用于限制每一个轴向上的关节

Configurable Joint:可配置关节,可配置关节组件支持用户自定义关节,它开放了physx引擎中所有与关节相关的属性,因此可像其他类型的关节那样来创造各种行为


力场是一种为刚体快速添加恒定作用力的方法,适用于类似火箭等发射出来的对象,这些对象在起初并没有很大的速度但却是再不断加速的



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



2015-02-02 10:26:22 book_longssl 阅读数 3756
  • Unity3D物理系统实战入门

    本课程深入浅出的介绍Unity3D物理引擎系统的概念,向初学者展示Unity3D物理引擎常见的编程思路和使用方式,与此同时,引领学习者逐步完成一款经典的关卡类物理引擎小游戏《Marble Drop》,详细展示如何根据项目的实际需求搭建简单而准确的物理组件和模块,对之前的理论知识进一步巩固和熟习。

    601 人正在学习 去看看 伍晓波


简介
       物理引擎就是在游戏中模拟真实的物理效果,比如,场景中有两个立方体对象,一个在空中,一个在地面上,在空中的立方体开始自由下落,然后与地面上的立方体对象发生碰撞,而物理引擎就是用来模拟真实碰撞的效果。

       如果需要让模型感应物理引擎的效果,需要将刚体组件或角色控制器组件添加至该对象中。

刚体(Rigidbody)
       刚体是一个非常重要的组件,新创建的物体默认情况下是不具有物理效果的,而刚体组件可以给物体添加一些常见的物理属性,比如物体质量、摩擦力和碰撞参数等,这些属性可用来真实的模拟该物体在3D游戏世界中的一切行为。

     下面我们在unity中创建一个plane(平面),两个cube(立方体),蓝色cube默认状态是没有rigidbody,给红色cube添加刚体组件,选择要添加刚体的对象,通过 “Component—>Physics—>Rigidbody”或者在Inspector窗口,选择“AddComponent—>Physics—>Rigidbody ”




运行后可以发现,添加了刚体的红色cube感应到了物理效应,会从空中落下。而蓝色cube依然是静止不动的




  可以看到Inspector可以看到Rigidbody包含的属性,简单的看下几个属性的含义,详细的可以看手册





   力是物理学中一个非常重要的元素,其种类有很多,刚体组件可以受力的作用,比如给刚体施加一个X轴方向的力,那么该刚体绑定的物体将沿X轴方向向前移动,这就好比用力将物体仍出去一样,该物体会以抛物线的形式移动,而不是呆板的做匀速平移 。

力的方式有两种

     1:普通力,通过设定里的方向和大小,相当于把力施加在物体的重心上。
     2:位置力,需要设定目标点的位置,该物体就朝向这个目标位置施加力。

AddForce和AddForceAtPosition
还是拿之前的那个列子做演示。在Hierarchy视图中创建两个Sphere,红色的添加普通力,白色的添加位置力
红色Cube当作位置力的目标对象。即向该位置发射一个位置力

1:创建脚本。定义三个变量:
    public GameObject whiteSph; 
 //白色球体 施加普通力的对象
    public GameObject redSph; 
 //红色球体 施加目标位置力的对象
    public GameObject targetPos;
 //目标对象


2:GUI绘制两个Button,分别控制“普通力”和“位置力”逻辑代码

void OnGUI()    { 

         if (GUILayout.Button("普通力"))   {
              redSph.rigidbody.AddForce(0,1000,0); 
     //Y轴上力的大小为1000。即向上         
   }
   if (GUILayout.Button("位置力")) {           
     //算出whiteSph到targetPos的目标向量            
     Vector3 c = targetPos.transform.position - whiteSph.transform.position;             
     //在c位置施加一个位置力,targetPos将会向这个位置移动
     whiteSph.rigidbody.AddForceAtPosition(c, targetPos.transform.position, ForceMode.Impulse);         
   }    
}


3:脚本挂载到Camera上。给变量拖拽赋值。运行看效果.


  运行游戏,刚体会受物理效应会往下落

  1:当单击普通力。红色球体会往天空弹起,因为它有刚体。最终还是外往下落。
  2:当单击位置力。白色球体会朝着红色方块位置添加力。最终移动到这个位置。
  3:当改变红色cube坐标后。目标位置也跟着移动。

  说了这么多。那AddForce和AddForceAtPosition到底有什么区别呢?我也是跟着学。跟着看手册,也许只有等以后知道了它运用在什么逻辑代码中。就自然而然了解了。

手册上的解释:

1: 添加一个力到刚体。作为结果刚体将开始移动。
2:在position位置应用force力。作为结果这个将在这个物体上应用一个力矩和力。

力矩?是什么。这个我也犯迷糊。不过在手册手看到这样一个函数。AddTorque:添加一个力矩到刚体。作为结果刚体将绕着torque轴旋转。
手册上函数有很多。有兴趣的可以自己去测试,等下把手册给大家。我也是网上下载的。


碰撞与休眠
   刚体与物体之间是存在碰撞的,一旦刚体开始移动,就可以在系统方法中监听刚体的碰撞状态,碰撞分为三种:

   1:进入碰撞
   2:碰撞中
   3:碰撞结束

我们通过一张图片来了解



碰撞器
  游戏对象如果需要感应碰撞,那么必须给其添加碰撞器,默认情况下,创建游戏对象时,会自动将碰撞器添加到其中。
  unity一共为对象提供了6种碰撞器
  1:Box Collider         盒子碰撞器
  2:Sphere Collider     球体碰撞器
  3:Capsule Collider    胶囊碰撞器
  4:Mesh Collider        网格碰撞器
  5:Wheel Collider      车轮碰撞器
  6:Terrain Collider     地形碰撞器



在碰撞器之间可以添加物理材质,用于设定物理碰撞后的效果,它将将开始
相互反弹,反弹的力度是有物理材质决定的。




unity标准资源包中提供了一些物理材质的资源,我们可以导入到当前工程中





导入成功后:


好。我们可以看出之前的游戏中,球体下落是立即禁止的。
现在给之前的Plane添加弹性材质,运行游戏



可以看到刚体在弹性材质的作用下。会反弹

碰撞检测
1:两个游戏对象必须有Collider
2:对于双方都要检测的物体,至少其中一个必须是刚体。
3:如果刚体是运动的,那么在双方都没有设置碰撞体的 Is Trigger属性的时候,
     双方都可以通过OnCollisionEnter函数检测碰撞
4:如果至少一个碰撞体Is Trigger被设置,那么双方可以通过OnTriggerEnter检测碰撞





2016-09-21 16:16:33 LONERrain 阅读数 7035
  • Unity3D物理系统实战入门

    本课程深入浅出的介绍Unity3D物理引擎系统的概念,向初学者展示Unity3D物理引擎常见的编程思路和使用方式,与此同时,引领学习者逐步完成一款经典的关卡类物理引擎小游戏《Marble Drop》,详细展示如何根据项目的实际需求搭建简单而准确的物理组件和模块,对之前的理论知识进一步巩固和熟习。

    601 人正在学习 去看看 伍晓波
 物理引擎对于当前大多数游戏都是必不可少的一部分。在虚拟现实逐渐兴起的今天,玩家对游戏的真实感,以及操作感要求越来越高。Unity3D内置PhysX物理仿真引擎,具有高效低耗,仿真度膏的特点。

1、什么是刚体?
刚体使物体能在物理控制下运动。刚体可通过接受力使物体允许效果更加真实。总而言之,Unity3D中任何物体想要受到重力、外力的影响都必须包含一个刚体组件。

2、怎样给物体添加刚体?
选中物体,然后在点击菜单 Components>Physics>Rigidbody,来给物体增加一个刚体。

3、刚体组件中有什么属性?(介绍常用属性)
1)质量(Mass) 发生碰撞时,质量大的物体能够推开质量小的物体。
2)阻力(Drag)默认为0,没什么好解释的吧……
3)旋转阻力(Augular Drag)默认值为0.05
4)使用重力(Use Gravity)用来设定是否在刚体上施加重力用来模拟现实世界中的自由落体状态等。勾选即选中。
5)是否遵循运动学(Is Kinematic)用来设置刚体是否遵循牛顿物理学定律 勾选表示不会调用物理计算,只受脚本和动画的影响而运动!!!

4、常用方法
1)AddForce函数:对刚体施加一个指定方向的力,使其发生移动。
函数表示如下:
function AddForce(force: Vector3,mode: ForceMode=ForceMode.Force) : void
函数ForceMode有四种模式:Force、Impulse、Acceleration、VelocityChange
Force表示施加一个恒力, Impulse表示施加一个瞬间冲击力
Acceleration表示对物体施加加速度 VelocityChange 表示改变物体速度
2)MovePosition函数:将刚体移动到position位置。
函数表示如下:
function MovePosition(position : Vector3) : void
3)MoveRoration函数:将刚体旋转相对应的角度。

5、简单案例
1)案例说明:使用上面介绍的三种函数,对场景中的正方体施加恒力、爆炸力、移动和旋转。重置按钮使正方体复位。
案例运行效果如下图1.1所示:
这里写图片描述
图1.1

2)制作流程:
1.使用在场景中创建4个Cube搭建成围墙,修改尺寸调整位置,创建一个Cube作为本案例的主角,创建一个Plane对象充当地板,为Cube和Plane分别添加纹理图片。
2.使用UGUI在场景里创建5个button按钮,如上图1.1所示。界面布局就完成了,接下来就需要编写脚本对主角Cube进行操作。
3、在Assets内点击鼠标右键,Create>C#Script,重命名为Script2,双击打开脚本编写代码。

using UnityEngine;
using System.Collections;
public class Script2 : MonoBehaviour {
    protected Transform m_transform;
    public float force;    //施加在物体上的力
    public float speed;    //物体移动速度
    private bool ForceMode_Impulse;    //布尔类型变量,用来判断当前是否对物体施加爆炸力
    private bool ForceMode_Force;      //布尔类型变量,用来判断当前是否对物体施加恒力
    private bool CubeMovePosition;     //判断物体是否移动
    private bool CubeMoveRotation;     //判断物体是否旋转
    private Vector3 eulerAngle = new Vector3(0, 100, 0);    //三维向量,用来设置物体绕那个轴旋转
    private Vector3 cubePosition;      //存储物体的位置
    private Quaternion cubeRotation;   // 存储物体旋转状态
    void Awake()
    {
        cubePosition = this.transform.position;   //记录物体初始位置
        cubeRotation = this.transform.rotation;   //记录物体初始状态
    }

       // Use this for initialization
       void Start () {
        m_transform = this.transform;

       }

       // Update is called once per frame
       void Update () {
        if (ForceMode_Impulse)//爆炸力 使物体向右移动
        {
            this.GetComponent<Rigidbody>().AddForce(Vector3.right * force, ForceMode.Impulse);
        }
        if (ForceMode_Force)//恒力 使物体向右移动
        {
            this.GetComponent<Rigidbody>().AddForce(Vector3.right * force, ForceMode.Force);
        }
        if (CubeMovePosition)//移动方块
        {
            this.GetComponent<Rigidbody>().MovePosition(m_transform.position + Vector3.right * Time.deltaTime);
        }
        if (CubeMoveRotation)//旋转方块
        {
            Quaternion deltaRotation = Quaternion.Euler(eulerAngle * Time.deltaTime);
            this.GetComponent<Rigidbody>().MoveRotation(m_transform.rotation * deltaRotation);
      }

       }
    public void OnClick1()//施加爆炸力
    {
        ForceMode_Impulse = !ForceMode_Impulse;
    }
    public void OnClick2()//施加横力
    {
        ForceMode_Force = !ForceMode_Force;
    }
    public void OnClick3()//移动方块
    {
        CubeMovePosition = !CubeMovePosition;
    }
    public void OnClick4()//旋转方块
    {
        CubeMoveRotation = !CubeMoveRotation;
    }
    public void OnClick5()//重置方块
    {    
        this.GetComponent<Rigidbody>().isKinematic = true;//先不遵循物理学定律,消除物体的移动、旋转
        this.GetComponent<Rigidbody>().isKinematic = false;//然后遵循物理学定律
        m_transform.position = cubePosition;   //将物体的位置修改为初始状态
        m_transform.rotation = cubeRotation;   // 将物体的旋转状态修改为初始状态
    }
}

OnClick1()————OnClick4()功能类似,是当点击button按钮后,更改物体的状态

4、保存脚本,在Unity中把Script2脚本拖拽到游戏体Cube上。在Inspector面板上就会看到该脚本的设置面板。如下图1.2所示。
Force和Speed可以任意修改。
这里写图片描述
图1.2

没有更多推荐了,返回首页