Unity3D_VR或AR 凝視效果


效果展示

在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 下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM