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 下载

posted on 2021-04-01 19:22  考拉宝贝  阅读(749)  评论(0编辑  收藏  举报

导航