Unity基礎 之 生命週期函數(二)

這是我參與8月更文挑戰的第4天,活動詳情查看:8月更文挑戰markdown

一,鼠標交互

1.1 函數描述

幾個函數ide

  1. OnMouseEnter: 鼠標進入時調用一次
  2. OnMouseOver: 鼠標停留(通過)時一直調用
  3. OnMouseExit: 鼠標退出時調用一次
  4. OnMouseDown: 鼠標按下時調用一次
  5. OnMouseDrag: 鼠標拖拽(按住)時一直調用
  6. OnMouseUp: 鼠標擡起時調用一次

實際使用:使用時通常都是成對使用函數

  1. OnMouseEnter,OnMouseOver,OnMouseExit 一組。好比模擬選中狀態:鼠標進入時物體變色,鼠標退出時再變回來。
  2. OnMouseDown,OnMouseDrag,OnMouseUp 一組。好比射擊遊戲:鼠標按下拖拽時調整方向,擡起時發射子彈。
  3. 當鼠標按下並停留在當前遊戲對象上時,OnMouseOver,OnMouseDrag會同時觸發。

檢測原理post

  1. 只能檢測當前腳本掛載的遊戲對象。
  2. 當前遊戲對象須要有碰撞體。
  3. 不能有其餘物體(UI)遮擋到此遊戲對象。
  • 總結爲一局話就是:OnMouseXXX的原理是經過鼠標的射線檢測來判斷鼠標當前位置是否碰到了掛載腳本遊戲對象的碰撞體。

勾選IsTrigger:測試

  若須要不檢測勾選IsTrigger的碰撞體,Edit => Project Settings => Physics中的Queries Hit Triggers,將這個✅ 取消,便可不觸發勾選IsTrigger的。【注意:默認是✅ 勾選狀態,不須要觸發則取消勾選】 ui


1.2 示例解析

  場景中建立一個Cube,將其位置調整在攝像機先顯示便可【示例中調整位置(0,0,-1),縮放爲(3,3,3)】。spa

測試功能:code

  • 鼠標進入\退出,觸發Cube顏色變化
  • 鼠標移動到Cube上,觸發旋轉
  • 鼠標在Cube按下並拖拽,觸發Cube跟隨移動
  • 鼠標擡起Cube迴歸到原來位置

建立並掛載到Cube代碼以下:orm

using UnityEngine;

public class OnMouseXXXTest : MonoBehaviour
{
    #region 鼠標相關

    // 鼠標和Collider(碰撞體)之間的觸發
    
    // 鼠標進入
    private void OnMouseEnter()
    {
        Debug.Log("OnMouseEnter 鼠標進入...");
        GetComponent<MeshRenderer>().material.color = Color.blue;
    }
    
    // 鼠標停留
    private void OnMouseOver()
    {
        transform.Rotate(Vector3.up * 50 * Time.deltaTime);
    }

    // 鼠標退出
    private void OnMouseExit()
    {
        Debug.Log("OnMouseExit 鼠標退出...");
        GetComponent<MeshRenderer>().material.color = Color.green;
    }

    // 鼠標按下
    private void OnMouseDown()
    {
        Debug.Log("OnMouseDown 鼠標按下...");
    }

    // 鼠標拖動
    private void OnMouseDrag()
    {
        Vector3 target = Input.mousePosition;
        target.z = Mathf.Abs(Camera.main.transform.position.z);
        transform.localPosition = Camera.main.ScreenToWorldPoint(target);
    }

    // 鼠標擡起
    private void OnMouseUp()
    {
        Debug.Log("OnMouseUp 鼠標擡起...");
        transform.localPosition = new Vector3(0, 0, -1);
    }

    #endregion
}
複製代碼

測試效果: 對象


二,碰撞檢測

2.1 函數描述

碰撞函數

  1. OnCollisionEnter: 進入碰撞時觸發一次。
  2. OnCollisionStay: 在碰撞體中停留時每幀觸發一次。
  3. OnCollisionExit: 離開碰撞體時觸發一次。

觸發函數

  1. OnTriggerEnter: 進入碰撞體時觸發一次。
  2. OnTriggerStay: 在碰撞體中停留時每幀觸發一次。
  3. OnTriggerExit: 離開碰撞體是觸發一次。

PS:上面這六個方法,還有對應2D碰撞體的六個方法(如:OnCollisionEnter2D) 函數後面添加2D接口,觸發條件和使用方式和3D一致。 使用時注意碰撞體和檢測函數同步接口,即用2D碰撞體必須用2D函數。

函數執行條件

  1. 兩個物體須要都有碰撞體(Collider)組件。
  2. 檢測方(掛載腳本物體)須要有剛體(Rigidbody)組件。
  3. Collider上都不勾選IsTrigger(有一方勾選則執行觸發函數)。

2.2 示例解析

在一例上繼續操做,在Cube上添加Rigidbody組件,並取消勾選Use Gravity 屬性(避免其受到重力影響)。

而後再建立兩個Cube,位置大小隨意能在Game視圖看到就行。將其中一個BoxCollider的IsTrigger 屬性勾選 ✅ 上。這樣就能夠一個用來測試碰撞,一個用來測試觸發了。

將代碼添加到OnMouseXXXTest類中,添加內容以下:

#region 碰撞,觸發檢測

// 在方法名後加上2D(如:OnCollisionEnter2D), 便可觸發2D碰撞體對應函數
// 進入碰撞時觸發
private void OnCollisionEnter(Collision other)
{
    Debug.Log("開始碰撞..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.black;
}

// 在碰撞體中停留時每幀觸發一次
private void OnCollisionStay(Collision other)
{
    Debug.Log("持續碰撞中..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.red;
}

// 離開碰撞體時觸發
private void OnCollisionExit(Collision other)
{
    Debug.Log("碰撞結束..." + other.collider.gameObject.name);
    other.collider.GetComponent<MeshRenderer>().material.color = Color.white;
}

// 碰撞體勾選is Trigger 選項: 取消碰撞器,開啓觸發器
// 進入碰撞體時觸發
private void OnTriggerEnter(Collider other)
{
    Debug.Log("觸發開始...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.black;
}

// 在碰撞體中觸發
private void OnTriggerStay(Collider other)
{
    Debug.Log("持續觸發中...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.yellow;
}

// 離開碰撞體是觸發
private void OnTriggerExit(Collider other)
{
    Debug.Log("觸發結束...");
    other.transform.GetComponent<MeshRenderer>().material.color = Color.white;
}
#endregion
複製代碼

運行後獲得以下效果:


三,應用程序

3.1 函數描述

三個函數

  1. OnApplicationPause: 檢測到暫停的幀結束 --> 切換到後臺和回來時調用。
  2. OnApplicationFocus: 當屏幕 得到/失去 焦點時調用
  3. OnApplicationQuit: 當程序退出時調用。

實際應用

  1. OnApplicationPause: 遊戲中止保存數據/遊戲繼續數據初始化。

  2. OnApplicationFocus: 失去焦點關閉背景音樂/得到焦點繼續播放音樂。

  3. OnApplicationQuit: 在移動端大退時也會對調用,但不會觸發上面兩個方法。


3.2 示例解析

使用時將下面代碼複製到須要處理檢測邏輯的部分便可:

#region Application 應用程序

// 檢測到暫停的幀結束時調用,有效地在正常幀更新之間
private void OnApplicationPause(bool pauseStatus)
{
    Debug.Log("OnApplicationPause ... " + pauseStatus);
    if (pauseStatus) // 切換到後臺時執行
    {
    }
    else // 切換到前臺執行一次
    {
    }
}

// 當屏幕 得到/失去 焦點時調用
private void OnApplicationFocus(bool hasFocus)
{
    Debug.Log("OnApplicationFocus ... " + hasFocus);
    if (hasFocus) // 得到焦點 -- 切換到前臺
    {
    }
    else // 失去焦點
    {
    }
}

// 當程序退出時調用 -- Application.Quit();觸發,不會觸發上面兩個方法
private void OnApplicationQuit()
{
    Debug.Log("OnApplicationQuit ... ");
}
複製代碼

由下圖能夠看到執行邏輯:當我點擊Hierarchy面板時觸發失去焦點,再次點擊Game視圖則觸發了得到焦點

Unity 官方圖解: 圖解

相關文章
相關標籤/搜索