用自訂方式觸發 uGUI - Trigger uGUI object without click

這幾天我需要實作一個功能:在遊戲中用準星瞄準、射擊來觸發 uGUI 元件。

很直覺的我在 uGUI 元件上加上 Collider,並用 Raycast 來觸發;不過反覆調整之後還是無法順利觸發 uGUI 元件,直到朋友給了我不同的思考方向,才成功完成實作。這個新的實作方向,同樣是利用 Raycast,不過我們不用來觸發 Collider,而是仿照點擊觸發的流程,觸發 uGUI 的 EventHandler。

完成了這個實作之後,同理類推,便能用各式各樣自訂的方式來觸發 uGUI,讓 uGUI 不一定只適用在點擊觸發的操作介面上,可以發展各式各樣的創意。

利用程式自行觸發 uGUI 的 EventHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using UnityEngine;
using System.Collections;
using System.Collections.Genertic;
using UnityEngine.EventSystems;

public class FakeClick {
private PointerEventData m_Pointer = new PointerEventData(EventSystem.current);
private List<RaycastResult> m_RaycastResults = new List<RaycastResult>();

public void OnClick (Vector2 pos) {
// This pos should be a screen position.
// Use Camera.main.WorldToScreenPoint() if you need.
m_Pointer.position = pos; m_RaycastResults.Clear();
EventSystem.current.RaycastAll(m_Pointer, m_RaycastResults);
if(m_RaycastResults.Count > 0) {
foreach(RaycastResult result_ in m_RaycastResults) {
Debug.Log(result_.gameObject.name + " is OnClick");
}
}
}
}
  • Line 7:模擬點擊的位置。
  • Line 8:用來發布 Raycast 觸發結果的 List,要注意這邊官方文件用 “發布” 這個字,而不是用回傳值的方式來接收,所以這個 List 的 new() 以及 Clear() 必須自行處理。
  • Line 13:此處要記得轉換成 Screen 坐標系的位置,不是 World 也不是 Local。
  • Line 15:運作點擊事件。
  • Line 17~21:處理點擊的結果。

參考