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中的屬性方法實現開門了。