天天看點

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

任務:子彈射擊執行個體 

1. 定義實體射線; 

2. 實作從錄影機到滑鼠目标位置射線發射子彈并碰撞目标對象的碰撞效果; 

3. 功能: 

  • 利用子彈預制體生成子彈; 
  • 利用 cube 生成一牆面;牆面 cube 對象帶有剛體和碰撞體元件; 
  • 利用 Random.range(float,float) 在随機的位置生成一個 cube 對象; 
  • 對随機生成的 cube 對象添加 box collider 碰撞體元件; 
  • 滑鼠點選發射一帶有剛體和碰撞體的子彈; 
  • 子彈撞擊 cube 牆面後帶有實體碰撞效果; 
  • 子彈跟随機生成的 cube 對象觸發檢測,觸碰後銷毀; 
使用技巧
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
vs不錯!

添加剛體元件

才會具有動力學特征,才會動

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
重力
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

兩個元件:剛體,碰撞體

添加了碰撞體,才會發生碰撞

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
四種情況
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

Is Kinematic / 作為觸發器:

可以穿透,不會碰撞

添加實體材質
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

建立一個主要的cube

建立一個RigidbodyMovement.cs腳本,并将其綁定到此cube上

主要功能:鍵盤操控,滑鼠拖動,碰撞檢測

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RigidbodyMovement : MonoBehaviour
{
    Rigidbody rbody;//公開到顯示面闆 public
    public float speed = 30f;//速度預先定義在外部

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody>();//擷取一個對象上面的剛體元件

    }

    // Update is called once per frame
    void Update()
    {
       //擷取虛拟軸,h、v定義在函數體内部
        float h = Input.GetAxis("Horizontal");//擷取水準軸,即左右鍵傳回的資料
        float v = Input.GetAxis("Vertical");//擷取垂直軸,即上下鍵傳回的資料
        rbody.MovePosition(rbody.position + transform.right * h * Time.deltaTime * speed);//剛體左右移動
        rbody.MovePosition(rbody.position + transform.forward * v * Time.deltaTime * speed);//剛體上下移動
    }

    private void OnMouseDrag()
    {
        //通過滑鼠扯拽控制剛體移動
        transform.position += Vector3.right * speed * Time.deltaTime * Input.GetAxis("Mouse X");
        transform.position += Vector3.up * speed * Time.deltaTime * Input.GetAxis("Mouse Y");
        transform.position += Vector3.forward * speed * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel");
    }

    private void OnCollisionEnter(Collision collision)
    {
        //碰撞進入瞬間顯示除地闆外碰撞體名稱
        if (collision.gameObject.name != "Plane")
        {
            print("the name of collision enrty:" + collision.gameObject.name);
        }
    }

    private void OnCollisionStay(Collision collision)
    {
        //碰撞中顯示除地闆外碰撞體名稱
        if (collision.gameObject.name != "Plane")
        {
            print("the name of collision stay:" + collision.gameObject.name);
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        //碰撞退出瞬間顯示除地闆外碰撞體名稱
        if (collision.gameObject.name != "Plane")
        {
            print("the name of collision exit:" + collision.gameObject.name);
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        //如果另外一個碰撞體進入了觸發器,則顯示其名稱
        print("triggerEnter:" + other.gameObject.name);
    }
    private void OnTriggerStay(Collider other)
    {
        print("triggerStay:" + other.gameObject.name);
    }
    private void OnTriggerExit(Collider other)
    {
        print("triggerExit:" + other.gameObject.name);
    }
}
           
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

MovePosition(三維向量) 改變位置

MoveRotation 讓其旋轉

效果如下

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

固定關節的用法

先建立一個空對象,再添加關節元件

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

關節要具有運動學特征才能被固定

是以要勾選 Is Kinematic

kinematic
adj. 運動的;運動學的;
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

這樣紅色方塊無論是否受重力作用,都被固定在關節上了。

效果

HingeJoint 鉸鍊關節

先建立一個空對象,再添加鉸鍊關節元件

添加鉸鍊關節元件會自動添加剛體元件

設定鉸鍊關節的綁定對象:綠色方塊  //這裡不要綁錯,不然沒有反應

鉸鍊關節屬性設定

關閉重力作用(不影響cube的擺動),打開動力學屬性(固定鉸鍊,保持靜止)

綠色方塊屬性設定

打開重力作用(擺動的動力來源),關閉動力學屬性(這樣不會靜止) //為什麼?不能了解。

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

綁定在空對象上的cube,這個transform屬性的位置是相對位置。

先把相對位置設為(0,0,0),此時cube不會擺動。

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

改變z值,随便改一個,比如1,cube開始擺動。

效果

彈簧關節

先建立一個空對象,再添加彈簧關節元件

綁定球體至彈簧上

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
效果

點選以發射子彈

建立一個子彈(剛體)

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

把它做成預制體:

先建立一個Prefab檔案夾,再把子彈拖進去,就變藍了

建立BulletFire.cs腳本

using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;

public class BulletFire : MonoBehaviour
{
    Ray ray;//定義射線
    public Rigidbody bullet_rigidbody;//定義子彈剛體
    RaycastHit raycastHit;//射線碰撞檢測

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);//生成一條射線

            if (Physics.Raycast(ray, out raycastHit))//射線檢測:如果和其他物體碰撞,就發射子彈
            {
                Rigidbody bullet = Instantiate<Rigidbody>(bullet_rigidbody);//定義子彈剛體,然後克隆一個子彈
                //此處不用bullet.position,而是bullet.transform.position,兩者有差別
                bullet.transform.position = Camera.main.transform.position;//子彈初始位置設為錄影機的位置
                bullet.AddForce((raycastHit.point - bullet.transform.position)*3f,ForceMode.Impulse);//AddForce函數:給剛體施加一個力,然後發射出去。注意括号。
                //Destroy(raycastHit.collider.gameObject);//銷毀點選對象
            }
        }
    }
}
           

把該腳本綁定到錄影機上,并在屬性中指定子彈的預制體

效果(指哪打哪)

子彈的銷毀(防止浪費記憶體資源)

建立一個DestroyBullet.cs腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestoryBullet : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag!="bullet")
        {
            return;
        }Destroy(collision.gameObject);
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.gameObject.tag != "bullet")
            return;
        if (other.attachedRigidbody)
            other.attachedRigidbody.AddForce(Vector3.up * 20f);
    }
}           

通過碰撞檢測+标簽的方式實作

給子彈添加标簽

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

如果與牆碰撞的東西是子彈,就銷毀子彈。

把腳本綁定到牆上,記得把牆固定住

注意:牆不能設定為觸發器,否則無法碰撞,也就無法銷毀子彈

效果

子彈碰牆後被銷毀

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

子彈穿過cube加速

(代碼包含在上面)

cube設定為

透明材質(暫時不會)

效果

子彈明顯加速

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

随機生成Cube(按A鍵控制生成),子彈若與其碰撞,将被銷毀

建立cube預制體,設定為可被撞開(運動學on)

Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
若用代碼建立cube,則難以調整其運動學屬性
GameObject cloneCube = Instantiate(cubeObj, new Vector3(0, 3, 0), Quaternion.identity);
GameObject cubeObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
cubeObj.GetComponent<Renderer>().material.color = Color.cyan;           
建立RandomCube.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomCube : MonoBehaviour
{
    public Rigidbody cubeObj;
    //public GameObject cubeObject;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            Rigidbody cloneCube=Instantiate<Rigidbody>(cubeObj);
            float x = Random.Range(-5.0f, 5.0f);
            float y = Random.Range(1f, 5.0f);
            float z = Random.Range(-5.0f, 5.0f);
            cubeObj.transform.position = new Vector3(x, y, z);
            cubeObj.tag = "RandomCube";
            cubeObj.name = "RandomCube";
        }
    }
}
           
把RandomCube.cs挂到平面上
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
實作銷毀子彈的效果,就把DestroyBullet.cs挂到RandomCube預制體上
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀

效果

按A随機生成RandomCube,子彈撞擊後,子彈銷毀,RandomCube在撞擊下運動

一張合照
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀
Unity 3d 剛體與碰撞體屬性 固定、鉸鍊、彈簧關節的使用 子彈的發射和銷毀