前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity基础(12)-物理系统

Unity基础(12)-物理系统

作者头像
孙寅
发布2020-06-02 15:06:37
1.6K0
发布2020-06-02 15:06:37
举报
文章被收录于专栏:宜达数字宜达数字
1.什么是Unity物理系统

Unity是一款3D引擎软件,内置NVIDIA PhysX物理引擎,使3D物体具备物理属性,产生物理效果。

2.什么是刚体

刚体使物体接受物理的控制,可以使物理实现移动 刚体就是模拟现实物体的运动状态,物体添加刚体后将受重力影响,并可以与其他物体发生碰撞。 Unity中两种刚体: 1.普通刚体(影响自己也影响其他物体),如:3D角色,运动的车子等 2.运动学刚体(Is Kinematic为 true, 自己不受物理引擎的驱动,但是会影响其他刚体)如:山体,房子等

3.Unity中的刚体组件

刚体组件

代码语言:javascript
复制
参数说明
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-方法

方法

代码语言:javascript
复制
添加一个力到刚体,参考世界坐标(瞬时)
�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.小练习

让一个方块产生,左键下落,右键暂停效果

代码语言:javascript
复制
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.封装

使用刚体移动封装的脚本

代码语言:javascript
复制
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);
    }
}

物体身上的脚本可以像下面一样调用

代码语言:javascript
复制
 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.力场组件

力场是一种为刚体快速添加恒定作用力的方法,使用与类似火箭发射的对象,起初没有很大的速度但是不断地加速

力场组件

代码语言:javascript
复制
代码添加
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);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.什么是Unity物理系统
  • 2.什么是刚体
  • 3.Unity中的刚体组件
  • 4-方法
  • 5.小练习
  • 6.封装
  • 7.力场组件
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档