Unity基础(12)-物理系统
2018-02-03 本文已影响192人
元宇宙协会
1.什么是Unity物理系统
Unity是一款3D引擎软件,内置NVIDIA PhysX物理引擎,使3D物体具备物理属性,产生物理效果。
2.什么是刚体
刚体使物体接受物理的控制,可以使物理实现移动
刚体就是模拟现实物体的运动状态,物体添加刚体后将受重力影响,并可以与其他物体发生碰撞。
Unity中两种刚体:
1.普通刚体(影响自己也影响其他物体),如:3D角色,运动的车子等
2.运动学刚体(Is Kinematic为 true, 自己不受物理引擎的驱动,但是会影响其他刚体)如:山体,房子等
3.Unity中的刚体组件
刚体组件参数说明
Mass 质量
Drag 位移阻力
Angular Drag 角阻力
Use Gravity 是否受重力影响
Is Kinematic 是否为运动学刚体
Interpolate 平滑物理运行的插值类型,该项用于控制刚体运动抖动情况
None:没有差值
Interpolater:内插值,基于前一帧的transform来平滑此次的transform
Extrapolate:外插值,基于下一帧的trransform来平滑此次的transform
Collision Detection 碰撞检测方式(枚举)控制避免高速运动的游戏对象穿过其他游戏对象昂而未发生碰撞
Discrete:离散碰撞检测
Continuous:连续碰撞检测:用于检测与动态碰撞体(带有rigidbody)碰撞,使用连续碰撞检测模式来检测与网格碰撞体的(不带rigidbody)碰撞。此模式用于连续动态碰撞检测的对象相碰撞的对象。如果不需要对快速运动的物体进行碰撞检测,请使用离散
Continuous Dynamic : 连续动态碰撞检测。检测与采用来连续碰撞模式或连续动态碰撞模式对象的碰撞,一般用于检测快速运动的游戏对象
Constraits 冻结位置和旋转
4-方法
方法添加一个力到刚体,参考世界坐标(瞬时)
�AddForce (force : Vector3, mode : ForceMode = ForceMode.Force) : void�
添加一个力到刚体,参考本地坐标(瞬时)
� AddRelativeForce (force : Vector3, mode : ForceMode = ForceMode.Force) : void
添加一个力矩到刚体,参考世界坐标(瞬时)
�AddTorque (torque : Vector3, mode : ForceMode = ForceMode.Force) : void�
添加一个力矩到刚体,参考本地坐标(瞬时)
� AddRelativeTorque (torque : Vector3, mode : ForceMode = ForceMode.Force) : void
说明在有阻力的作用下,物体会慢慢停下
在position位置应用force力。作为结果这个将在这个物体上应用一个力矩和力(瞬时)。
�AddForceAtPosition (force : Vector3, position : Vector3, mode : ForceMode = ForceMode.Force) : void
ForceModel
5.小练习
让一个方块产生,左键下落,右键暂停效果
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RigidbodyTest : MonoBehaviour {
private Rigidbody r;
void Start () {
r = this.gameObject.AddComponent<Rigidbody>(); // 通过代码的方式添加刚体
r.mass = 1;
r.angularDrag = 0.0f;
}
public void RigidbodyGreat(bool IsTrue)
{
if (IsTrue) // 表示IsTrue = yes;
{
r.isKinematic = true; // 设置当前游戏对象为运动学刚体
// r.constraints = RigidbodyConstraints.FreezePositionY; //锁定当前刚体即刚体所在的游戏物体的Y轴
}
else {
r.isKinematic = false;
// r.constraints = RigidbodyConstraints.None; // 不锁定任何轴
}
}
void Update () {
if (Input.GetMouseButtonDown(1))
{
RigidbodyGreat(true);
}
if (Input.GetMouseButtonDown(0))
{
RigidbodyGreat(false);
}
}
6.封装
使用刚体移动封装的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveControllerWithRighd {
/// <summary>
/// 判断游戏对象是否有刚体,如果没有自动添加,同时可以冻结的传入的物体旋转位置
/// </summary>
/// <param name="obj">判断的物体</param>
/// <param name="rc">冻结的参数</param>
/// <returns></returns>
public static Rigidbody ObjIsHaveRid(GameObject obj, RigidbodyConstraints rc)
{
Rigidbody r = ObjIsHaveRid(obj);
r.constraints = rc;
return r;
}
/// <summary>
/// 判断游戏对象是否有刚体,如果没有自动添加
/// </summary>
/// <param name="obj">判断的对象</param>
private static Rigidbody ObjIsHaveRid(GameObject obj)
{
Rigidbody r = obj.GetComponent<Rigidbody>();
if (r == null)
{
r = obj.AddComponent<Rigidbody>();
}
return r;
}
/// <summary>
/// 物体移动方法
/// </summary>
/// <param name="obj">移动的物体</param>
public static void ObjMoveWithKey(GameObject obj,float speed)
{
KeyContro(KeyCode.W, obj, new Vector3(0, 0, speed));
KeyContro(KeyCode.S, obj, new Vector3(0, 0, -speed));
KeyContro(KeyCode.A, obj, new Vector3(-speed, 0, 0));
KeyContro(KeyCode.D, obj, new Vector3(speed, 0, 0));
}
/// <summary>
/// 按键控制方法
/// </summary>
/// <param name="key">控制的键</param>
/// <param name="player">需要控制的对象</param>
/// <param name="move">按键控制移动的方向</param>
private static void KeyContro(KeyCode key, GameObject player, Vector3 move)
{
if (Input.GetKey(key))
{
RidMove(player, move, ForceMode.Force);
}
}
/// <summary>
/// 刚体的移动
/// </summary>
/// <param name="obj">要移动的对象</param>
/// <param name="Move">移动的方向</param>
/// <param name="m">力的模式</param>
private static void RidMove(GameObject obj, Vector3 Move, ForceMode m)
{
// 耦合性
obj.GetComponent<Rigidbody>().AddForce(Move, m);
}
}
物体身上的脚本可以像下面一样调用
public GameObject Player;
void Start () {
Player = CreatObj(PrimitiveType.Cube,"PlayerA", new Vector3(0, 0.5f, 0));
MoveControllerWithRighd.ObjIsHaveRid(Player, RigidbodyConstraints.FreezeRotation);
}
public GameObject CreatObj(PrimitiveType p, string ObjName, Vector3 Pos)
{
GameObject obj = GameObject.CreatePrimitive(p);
obj.name = ObjName;
obj.transform.position = Pos;
return obj;
}
void Update () {
MoveControllerWithRighd.ObjMoveWithKey(Player,15f);
}
7.力场组件
力场是一种为刚体快速添加恒定作用力的方法,使用与类似火箭发射的对象,起初没有很大的速度但是不断地加速
力场组件代码添加
ConstantForce cf = this.gameObject.AddComponent<ConstantForce>();
cf.force = new Vector3(5, 0, 0);
cf.relativeForce = new Vector3(5, 0, 0);
cf.torque = new Vector3(5, 0, 0);
cf.relativeTorque = new Vector3(5f, 0, 0);