Unity物理引擎

3 篇文章 0 订阅
1 篇文章 0 订阅

一、刚体

带有刚体组件的游戏物体
刚体(rigid body)组件可使游戏对象受物理引擎控制,在受到外力时产生真实的物理特性。想让物体仿真,就加刚体。

二、碰撞器

物理引擎:模拟真实世界中物体物理特性的引擎
物理碰撞器(collider)组件:实现物体间的碰撞。尽量使用Box Collider ,性能最好。Mesh Collider 可以模仿任何形状的物体,但因面数往往过高,性能最低。
碰撞器的选择:面数越少越好。
在游戏场景中玩家有可能接触到的物体要加碰撞器。
需要在现实生活中有高仿真度的要加刚体。要把属性配的合理,仿真度才高。
若想模拟物体破碎,可以把它拆成很多小物体一起运动,然后施加一个力。

Mass:物体的质量
Drag:受力移动时物体收到的空气阻力。0表示没有阻力,极大时可使物体停止运动,砖头0.001,羽毛10
AngleDrag:角阻力
Use Gravity 是否使用重力
Is Kinematic 运动学刚体,受到外力自身无任何影响,但会影响别的物体。例如(打台球的球杆,就可以勾上)只能通过组件移动。原则是要不要对别人有影响,别人要不要对自己有影响。若对 别人有影响,别人对自己无影响就勾上。
Constraints约束:对刚体运动的约束。
冻结位置Freeze Position:刚体在世界中沿所选X,Y,Z 轴的移动,将无效。
冻结旋转Freeze Rotation:刚体在世界中沿所选的X,Y,Z轴 的旋转,将无效。
Interpolate插值:用于缓解刚体运动时的抖动。
None 无–不应用插值。
Interpolate内插值–基于上一帧的变换来平滑本帧变换。
Extrapolate外插值–基于下一帧的预估变换来平滑本帧 变换。

碰撞检测 Collision Detection:

碰撞检测模式。快速移动的刚体在碰撞时有可能互相穿透,可以设置碰撞检测频率, 但频率越高对物理引擎性能影响越大。
不连续Discrete:不连续碰撞检测。适用于普通碰撞(默认模式)。
连续Continuous:连续碰撞检测。
动态连续Continuous Dynamic:连续动态碰撞检测,适用于高速物体。

物理材质 physic material

用于调整碰撞对象的摩擦力和反弹效果。
属性
动态摩擦力Dynamic Friction:移动时摩擦力
静态摩擦力Static Friction:静止时摩擦力
动静态摩擦力一般设为一样
弹力(Bounciness):反弹程度
备注:摩擦力、弹力建议0—1之间
摩擦力合并模式Friction Combine Mode、
合并反弹Bounce Combine:
两个碰撞对象摩擦力/弹力的合并方式
平均值Average 最小Min 最大Max 相乘Multiply

碰撞条件:

两者具有碰撞组件。
运动的物体具有刚体组件。

碰撞三阶段:

Collision事件参数类 包含了引发事件时的相关信息,包含了对方的碰撞器
只要碰撞就会执行下面的方法 字母必须一致
当进入碰撞时执行

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

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

void OnCollisionStay(Collision collOther)

当停止碰撞时执行

void OnCollisionExit(Collision collOther)

	other.contacts[0].point   碰撞点的世界坐标
	other.contacts[0].normal  碰撞面的法线
	//满足碰撞条件的第一帧执行
    private void OnCollisionEnter(Collision other)
    { 
    	//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 选项。就是触发器。
当只想知道有没有接触,而不想有碰撞效果时,用触发器。
若触发范围不规则,载入让美工做形状,再添加到Mesh Collider

触发条件

两者具有碰撞组件
动的物体有刚体组件
其中之一勾选isTrigger

触发三阶段

Collider 就是对方的碰撞器组件 作用:检测碰撞还是没碰撞
只要满足触发条件,就会执行下边方法
当Collider(碰撞体)进入触发器时执行

void OnTriggerEnter(Collider cldOther)

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

void OnTriggerStay(Collider cldOther) 

当停止触发时执行

void OnTriggerExit(Collider cldOther) 

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

public float moveSpeed = 80;
    private void Movement()
    {
        transform.Translate(0, 0, Time.deltaTime * moveSpeed);
    }
    private void Update()
    {
        Movement();
    }
    private void FixedUpdate()
    {
        Debug.Log(transform.position);
    }
    //当前子弹与其他碰撞器接触时执行
    private void OnTriggerEnter(Collider other)
    {
        Destroy(this.gameObject);
    }

用触发检测速度过快的物体不合理
每帧才做一次碰撞(触发)检测,如果物体速度太快,很容易直接越过要碰撞的物体,而检测失败。前一帧不在,后一帧就过了。
解决方案:运动前,就确定好与谁发生碰撞,然后朝向目标点移动。
解决方案二:适合高速且躲也躲不掉的物体(子弹)
一、一种对方物体不动,则只需发射一根射线
二、如果对方物体移动,可能打不到,就每帧发射线,射线长度跟速度成正比
像射击类游戏,可以不加子弹,只需做一个弹道就可,省性能。

//高速运动的物体,很可能碰撞(触发)检测失败
    //解决方案:运动前,就确定到与谁发生碰撞,然后朝向目标点移动。
    public LayerMask layer;
    private Vector3 targetPos;
    private void 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处的点
        }
    }
    private void Update()
    {
        Movement();
        //如果接近目标点,则销毁物体
        if((transform.position - targetPos).sqrMagnitude<0.1f)
        {
            Destroy(this.gameObject);
        }
    }
    private void 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 
{
    private void OnCollisionStay(Collision other)
    {
        if(other.collider.tag == "Door")
        {   //在身体斜上方为门添加一个500的力   other.transform.GetComponent<Rigidbody>().AddForce((transform.forward + transform.up)* 500);
        }
    }
}

固定关节Fixed Joint

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

连接体(Connected Body):

对关节(Joint) 所依赖的刚体(Rigidbody) 的可选引用。如果未设置,则关节(Joint) 连接到世界坐标。
折断力(Break Force):为使此关节(Joint) 折断而需要应用的力。
折断扭矩(Break Torque):为使此关节(Joint) 折断而需要应用的扭矩。
启动碰撞Enable Collision :如果启用,将启用与绑定物体之间的碰撞效果。

弹性关节 Spring Joint

弹簧关节将两个刚体(Rigidbody) 组合在一起,从而将其约束为如同通过弹簧连接一样进行移动效果。
弹性关节组件属性:
连接体(Connected Body):对关节所依赖的刚体(Rigidbody) 的可选引用。
锚点(Anchor):对象局部坐标空间中定义关节中心的位置(静止时)。这不是将对象拉向的位置。
弹簧(Spring):弹簧的强度。
阻尼(Damper):弹簧在处于活动状态时缩减的量。
最小距离(Min Distance):大于此值的距离不会使弹簧激活。
最大距离(Max Distance):小于此值的距离不会使弹簧激活。
折断力(Break Force):为使此关节折断而需要应用的力。
折断扭矩(Break Torque):为使此关节折断而需要应用的扭矩。
启动碰撞Enable Collision :如果启用,将启用与绑定物体之间的碰撞效果

五、给刚体添加力

•rigidbody.AddForce(Vector3.forward500);
•//世界坐标前方(Z轴)方向添加一个500的力。
•rigidbody.AddForce(transform.forward
500);
•//自己的坐标前方(Z轴)方向添加一个500的力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值