效果展示
在Unity中的層級關系及命名
改變每個物體的屬性
創建腳本 GazePartical,將該腳本掛載到CanvasGaze上
腳本代碼如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // 實心圓代表沒有看到物體或看到的物體上沒有碰撞器,空心圓帶表看到了待遇碰撞器的物體 // 射線檢測到的物體為 selectTrans public class GazePartical : MonoBehaviour { [Header("發出射線的物體")] // 一般為攝像機 public Transform rayGameObject; // 點擊效果(粒子特效) public ParticleSystem clickPartical; // 返回選中的物體 [HideInInspector] public Transform selectTrans; // 開始轉圈的等待時間(秒) private float startAnimatorTime = 1; // 轉滿一圈的時間(秒) private float finishCircleTime = 1; // 在看不到物體時顯示 private GameObject imageSolid; // 看到可交互的物體時顯示 private GameObject imageHollow150; // 看到可交互的物體一秒不變時顯示 private Image imageHollow200; // 用於設置凝視點在看不到物體時的位置 private Transform imageSolidTrans; // 計時器 private float timer; // 當前看到的物體 private string targetName; // 是否開始計時 private bool isTime; // 是否達到激活條件 private bool isActivate; public bool IsActivate { get { if (imageHollow200.fillAmount >= 1) return true; else return false; } } void Start() { imageSolid = transform.Find("Image_Solid").gameObject; imageHollow150 = transform.Find("Image_Hollow150").gameObject; imageHollow200 = transform.Find("Image_Hollow150/Image_Hollow200").GetComponent<Image>(); // 用於設置凝視點在看不到物體時的位置 imageSolidTrans = new GameObject().transform; imageSolidTrans.parent = rayGameObject; imageSolidTrans.localPosition = new Vector3(0f, 0f, 4.5f); imageSolidTrans.localRotation = Quaternion.identity; // fillAmount 取值范圍:0 ~ 1 imageHollow200.fillAmount = 0f; // 生成特效,並賦值 clickPartical = Instantiate(clickPartical.gameObject).GetComponent<ParticleSystem>(); } void Update() { Ray ray = new Ray(rayGameObject.position, rayGameObject.forward); RaycastHit raycastHit = new RaycastHit(); if (Physics.Raycast(ray, out raycastHit)) { // 顯示空心,隱藏實心 imageHollow150.SetActive(true); imageSolid.SetActive(false); // 設置位置 transform.position = raycastHit.point; // 讓圓環貼到物體表面 transform.forward = raycastHit.normal; // 當體驗者盯住一個物體超過一秒,開始填充 if (raycastHit.transform.name == targetName) { isTime = true; } else { isTime = false; targetName = raycastHit.transform.name; } } else { // 顯示實心,隱藏空心 imageSolid.SetActive(true); imageHollow150.SetActive(false); imageHollow200.fillAmount = 0f; // 歸零計時器 isTime = false; timer = 0f; // 設置位置和旋轉 transform.position = imageSolidTrans.position; transform.rotation = imageSolidTrans.rotation; } // 盯住同一個物體,開始計時 if (isTime) { timer += Time.deltaTime; } // 不盯住他物體時計時器初始化,重新計時 else { timer = 0f; imageHollow200.fillAmount = 0f; isPlayParticle = true; } if (timer >= startAnimatorTime) { timer = startAnimatorTime; imageHollow200.fillAmount += ((1 / finishCircleTime) / (1 / Time.deltaTime)); } if (imageHollow200.fillAmount >= 1f) { // 播放點擊粒子 ClickParticle(raycastHit.transform.position); selectTrans = raycastHit.transform; } else { selectTrans = null; } // 測試:打印檢測到的物體 // if (selectTrans) print("射線檢測到的物體:" + selectTrans.name); } // 是否播放粒子 private bool isPlayParticle; // 點擊粒子 private void ClickParticle(Vector3 point) { if (isPlayParticle) { // 特效位置 clickPartical.transform.position = transform.position + (transform.forward * 0.001f); clickPartical.transform.rotation = transform.rotation; if (clickPartical.isPlaying) { clickPartical.Stop(); } // 播放粒子 clickPartical.Play(); isPlayParticle = false; } } }
本示例 UnityPackage 下載