物理引擎
- 一、刚体
- 二、碰撞器
- 碰撞检测 Collision Detection:
- 物理材质 physic material
- 碰撞条件:
- 碰撞三阶段:
- 三、触发器
- 触发条件
- 触发三阶段
- 四、关节
- 关节分类:
- 铰链关节Hinge Joint
- 固定关节Fixed Joint
- 连接体(Connected Body):
- 弹性关节 Spring Joint
- 五、给刚体添加力
一、刚体
带有刚体组件的游戏物体
刚体(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.forward500);
•//自己的坐标前方(Z轴)方向添加一个500的力。