简述:
带有刚体组件的游戏物体
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
}
关节分类:
铰链关节(最常用)
弹性关节(常用)
固定关节(常用)
角色关节
可配置关节
铰链关节:将两个刚体(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
}
}
}
固定关节将对象移动限制为依赖于其他对象。这在某种程度上类似于父子化,不过是通过物理而不是变换层级结构来实现。使用它们的最佳情况是在具有要方便地相互分离的对象,或是连接两个对象的移动而不进行父子化时。
固定关节组件属性:
属性: 功能:
连接体(ConnectedBody):对关节(Joint)所依赖的刚体(Rigidbody)的可选引用。如果未设置,则关节(Joint)连接到世界坐标。
折断力(BreakForce):为使此关节(Joint) 折断而需要应用的力。
折断扭矩(BreakTorque):为使此关节(Joint) 折断而需要应用的扭矩。
启动碰撞EnableCollision :如果启用,将启用与绑定物体之间的碰撞效果。
弹簧关节将两个刚体(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);
}
}
}