1. 程式人生 > >Unity靠近後開關門的效果實現

Unity靠近後開關門的效果實現

實現一個大多數的遊戲場景中,靠近門之後,按下“F”鍵開門,再按下“F”鍵關門的效果。

這裡要利用到觸碰體(Trigger)和查詢場景中物體的知識。

首先搞一個門出來,弄一個Cube隨便捏扁就有了,不多說。

先大概的想想門是怎麼開的。是繞它的一條左邊(也可以是右邊),做旋轉。

可如果我們直接對門的transform元件中的rotate設定旋轉,會變成什麼樣。

很明顯,大家可以想到,會繞著門的中心點做旋轉,這無疑不是我們想要的效果。

那麼,怎麼改變它的中心旋轉呢。unity是不能直接改變物體的中心點的。

其實也很簡單,我們只需要多加一個門軸(door shaft)就好了啊,我們可以新建一個空物體,名為doorshaft。然後把門(door)變成門軸的子物體,這樣門軸旋轉會帶動門旋轉,就能體現出門繞一邊旋轉的效果了。

ps:按住ctrl左鍵點選兩個物體,,Pivot會使中心點在前一個物體上面,Center則是會在兩個物體中間。

這裡基本上實現了門的開啟,接下來要做的是“靠近門才能開關門”。

沒錯,觸碰體(Trigger)正適合做這樣的事情。這裡可以參考一下 uinty之碰撞體,觸碰體,剛體 裡的觸碰體的解說。

觸碰體在由物體進入它的collide範圍之後,呼叫void OnTriggerEnter(Collider collider)方法,離開的時候呼叫 void OnTriggerExit(Collider collider)。

我們用一個空物體來做這個事情。新建一個空物體(命名為DoorTrigger),然後賦給他一個Box Collide,然後勾選

Is Trigger,再Edit Collide捏成差不多的大小,再把DoorTrigger擺放到合適位置就Ok了。

像下面這個就差不多了。

搞兩個指令碼,分別賦給DoorShaft一個名為叫Door的C#指令碼,給DoorTrigger一個叫Trigger的C#指令碼。

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

public class Trigger : MonoBehaviour
{
    private Door m_Door;
    private bool enterCollide = false;
    // Start is called before the first frame update
    void Start()
    {
        m_Door = GameObject.Find("Doorshaft").GetComponent<Door>();
    }


    void OnTriggerEnter(Collider collider)
    {
        Debug.Log("enter");
        enterCollide = true;
    }

    void OnTriggerExit(Collider collider)
    {
        Debug.Log("exit");
        enterCollide = false;
    }
    // Update is called once per frame
    void Update()
    {
        if (enterCollide)
        {
            if (Input.GetKeyDown(KeyCode.F))
            {
                if (m_Door.GetIsOpen())
                {
                    m_Door.CloseDoorMethod();

                }
                else
                {
                    m_Door.OpenDoorMethod();
                }
            }
        }
      
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Door : MonoBehaviour
{
    Transform tf;
    private bool isOpen = false;

    // Start is called before the first frame update
    void Start()
    {
        tf = gameObject.GetComponent<Transform>();
    }

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

    public void OpenDoorMethod()
    {
            tf.Rotate(Vector3.up, 100);
            Debug.Log("close");
            isOpen = !isOpen;

    }
    public void CloseDoorMethod()
    {
            tf.Rotate(Vector3.up, -100);
            Debug.Log("open");
            isOpen = !isOpen;
    }

    public bool GetIsOpen()
    {
        return isOpen;
    }
    public void SetIsOpen(bool b)
    {
        isOpen = b;
    }
}

m_Door = GameObject.Find("Doorshaft").GetComponent<Door>();

這句是什麼意思呢。通過GameObject的靜態方法Find(String),可以在場景中找到名為“Doorshaft”的GameObject,直接呼叫這個GameObject中的元件Door(即Door.cs,C#指令碼)。賦給m_Door;

這樣就可以在觸發體中獲得門軸(Doorshaft)的物件了,然後在有物體進入觸發體中,On TriggerEnter(Collide)被呼叫了的情況下,使用Door中的屬性方法實現開門了。