VR开发实战HTC Vive项目之僵尸大战(语音唤醒与手势识别)

一、框架视图

VR开发实战HTC Vive项目之僵尸大战(语音唤醒与手势识别)_第1张图片

二、主要代码

BaseControllerManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK;

public abstract class BaseControllerManager : MonoBehaviour
{
    private VRTK_ControllerEvents controllerEvents;

    public abstract void GripReleased();
    public abstract void GripPressed();
    public abstract void TouchpadReleased();
    public abstract void TouchpadPressed();
    public abstract void TriggerReleased();
    public abstract void TriggerPressed();

    private void Awake()
    {
        controllerEvents = GetComponent();
        controllerEvents.GripPressed += ControllerEvents_GripPressed;
        controllerEvents.GripReleased += ControllerEvents_GripReleased;

        controllerEvents.TriggerPressed += ControllerEvents_TriggerPressed;
        controllerEvents.TriggerReleased += ControllerEvents_TriggerReleased;

        controllerEvents.TouchpadPressed += ControllerEvents_TouchpadPressed;
        controllerEvents.TouchpadReleased += ControllerEvents_TouchpadReleased;
    }

    private void ControllerEvents_TouchpadReleased(object sender, ControllerInteractionEventArgs e)
    {
        TouchpadReleased();
    }

    private void ControllerEvents_TouchpadPressed(object sender, ControllerInteractionEventArgs e)
    {
        TouchpadPressed();
    }

    private void ControllerEvents_TriggerReleased(object sender, ControllerInteractionEventArgs e)
    {
        TriggerReleased();
    }

    private void ControllerEvents_TriggerPressed(object sender, ControllerInteractionEventArgs e)
    {
        TriggerPressed();
    }

    private void ControllerEvents_GripReleased(object sender, ControllerInteractionEventArgs e)
    {
        GripReleased();
    }

    private void ControllerEvents_GripPressed(object sender, ControllerInteractionEventArgs e)
    {
        GripPressed();
    }
}

Game:

BodyPartDrop

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// 
/// 受伤后掉落
/// 
public class BodyPartDrop : MonoBehaviour
{
    public GameObject go_Firend;

    public void SetFriend(GameObject go)
    {
        go_Firend = go;
    }
    /// 
    /// 受伤后掉落的处理
    /// 
    public void Hit()
    {
        BodyPartDrop[] arr = transform.parent.GetComponentsInChildren();

        foreach (var item in arr)  //中间掉落  下面也要跟着掉落
        {
            item.go_Firend.SetActive(false);
            item.transform.parent = null;
            item.transform.GetChild(0).gameObject.SetActive(true);
            item.gameObject.AddComponent();
            Destroy(item);
        }
    }
}

Bomb

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// 
/// 爆炸
/// 
public class Bomb : MonoBehaviour
{
    public bool IsThrow = false; //是都可以投掷
    public float BrustTime = 5f; //爆炸等待时间
    public GameObject effect_Brust; //爆炸特效

    private float m_Timer = 0.0f; //计时器

    private void FixedUpdate()
    {
        if (IsThrow) //判断是否可以爆炸  在手管理类的时候投掷炸弹设置为true  HandManger170 
        {
            m_Timer += Time.deltaTime;
            if (m_Timer >= BrustTime)
            {
                Instantiate(effect_Brust, transform.position, transform.rotation); //实例化特效
                Destroy(gameObject);
                EventCenter.Broadcast(EventDefine.BombBrust, transform.position);//广播发生爆炸特效的事件 当前爆炸位置的信息
            }
        }
    }
}

Book

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum BookType
{
    StartBook,
    AboutBook,
    GestureBook
}


/// 
/// 书籍管理类
/// 
public class Book : MonoBehaviour
{
    public BookType m_BookType;
    public Vector3 m_StratPos;
    public Quaternion m_StartRot;
    /// 
    /// 判断书本是否触发到书台
    /// 
    public bool m_IsTrigger = false;
    /// 
    /// 触发的书台物体
    /// 
    private GameObject go_StandBook;

    private void Awake()
    {
        m_StratPos = transform.position;
        m_StartRot = transform.rotation;
    }
    private void Update()
    {
        if (transform.parent != null && go_StandBook != null)
        {
            if (transform.parent != go_StandBook.transform)
            {
                IsActiveUI(false);
            }
        }
    }
    /// 
    /// 放置书本
    /// 
    public void Put()
    {
        if (go_StandBook.GetComponentInChildren() != null)
        {
            go_StandBook.GetComponentInChildren().Release();
        }
        transform.parent = go_StandBook.transform;
        transform.position = go_StandBook.transform.GetChild(0).position;
        transform.rotation = go_StandBook.transform.GetChild(0).rotation;
        IsActiveUI(true);
    }
    /// 
    /// 书本归为
    /// 
    public void Release()
    {
        transform.parent = null;
        transform.position = m_StratPos;
        transform.rotation = m_StartRot;
        IsActiveUI(false);
    }
    /// 
    /// 是否激活当前书本对应的UI界面
    /// 
    /// 
    private void IsActiveUI(bool value)
    {
        switch (m_BookType)
        {
            case BookType.StartBook:
                EventCenter.Broadcast(EventDefine.IsShowStartPanel, value);
                break;
            case BookType.AboutBook:
                EventCenter.Broadcast(EventDefine.IsShowAboutPanel, value);
                break;
            case BookType.GestureBook:
                EventCenter.Broadcast(EventDefine.IsShowGesturePanel, value);
                break;
        }
    }
    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "BookStand")
        {
            m_IsTrigger = true;
            go_StandBook = other.gameObject;
        }
    }
    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "BookStand")
        {
            m_IsTrigger = false;
            go_StandBook = null;
        }
    }
}

GestureRecognition

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Edwon.VR;
using Edwon.VR.Gesture;


/// 
/// 检测手势
/// 
public class GestureRecognition : BaseGestureRecognition
{
    public override void Awake()
    {
        base.Awake();
        EventCenter.AddListener(EventDefine.IsStartGestureRecognition, IsStartGestureRecognition); //后面可以是方法或者直接赋值  布尔变量
    }
    public override void OnDestroy()
    {
        base.OnDestroy();
        EventCenter.RemoveListener(EventDefine.IsStartGestureRecognition, IsStartGestureRecognition);
    }
    /// 
    /// 是否开始手势识别
    /// 
    /// 
    private void IsStartGestureRecognition(bool value)
    {
        if (value)
        {
            BeginRecognition();
        }
        else
        {
            gestureRig.uiState = VRGestureUIState.Idle;
        }
    }

    public override void OnGestureDetectedEvent(string gestureName, double confidence) //检测手势事件
    {
        string skillName = GestureSkillManager.GetSkillNameByGestureName(gestureName); //获取技能的名称
        GameObject skill = ResourcesManager.LoadObj(skillName); //加载技能预制体
        Instantiate(skill, new Vector3(Camera.main.transform.position.x, 0, Camera.main.transform.position.z), skill.transform.rotation);  //实例化技能 注意生成的位置
    }
}

GestureSkillManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Edwon.VR;
using Edwon.VR.Gesture;

/// 
/// 手势技能管理
/// 
public class GestureSkillManager
{
    /// 
    /// 手势名与技能名的字典
    /// 
    private static Dictionary m_GestureSkillDic = new Dictionary();
    private static VRGestureSettings gestureSettings;
    private static string SkillName = "Skill";

    static GestureSkillManager()
    {
        gestureSettings = Utils.GetGestureSettings();
        m_GestureSkillDic = GetGestureSkillDic();
    }
    /// 
    /// 获取手势名与技能名之间的关系
    /// 
    /// 
    private static Dictionary GetGestureSkillDic()
    {
        Dictionary gestureSkillDic = new Dictionary();
        //规则:手势名-技能名;手势名-技能名
        if (PlayerPrefs.HasKey("GestureSkill"))
        {
            string gestureSkill = PlayerPrefs.GetString("GestureSkill");
            string[] arr = gestureSkill.Split(';');
            foreach (var item in arr)
            {
                string[] tempArr = item.Split('-');
                gestureSkillDic.Add(tempArr[0], tempArr[1]);
            }
        }
        else
        {
            for (int i = 0; i < gestureSettings.gestureBank.Count; i++)
            {
                gestureSkillDic.Add(gestureSettings.gestureBank[i].name, SkillName + (i + 1).ToString());
            }
            SaveGestureSkillDic(gestureSkillDic);
        }
        return gestureSkillDic;
    }
    /// 
    /// 保存手势与技能之间的关系
    /// 
    private static void SaveGestureSkillDic(Dictionary dic)
    {
        string temp = "";
        int index = 0;
        foreach (var item in dic)
        {
            //规则:手势名-技能名;手势名-技能名
            temp += item.Key + "-" + item.Value;
            index++;
            if (index != dic.Count)
                temp += ";";
        }
        PlayerPrefs.SetString("GestureSkill", temp);
    }
    /// 
    /// 通过手势名获取技能名
    /// 
    public static string GetSkillNameByGestureName(string gestureName)
    {
        if (m_GestureSkillDic.ContainsKey(gestureName))
        {
            return m_GestureSkillDic[gestureName];
        }
        return null;
    }
    /// 
    /// 更换手势与技能之间的关系(更换技能)
    /// 
    /// 
    /// 
    public static void ChangeSkill(string gestureName, string newSkillName)
    {
        if (m_GestureSkillDic.ContainsKey(gestureName))
        {
            m_GestureSkillDic[gestureName] = newSkillName;
            SaveGestureSkillDic(m_GestureSkillDic);
        }
    }
    /// 
    /// 通过手势名获取技能图片
    /// 
    /// 
    public static Sprite GetSkilSpriteByGestureName(string gestureName)
    {
        if (m_GestureSkillDic.ContainsKey(gestureName))
        {
            return ResourcesManager.LoadSprite(m_GestureSkillDic[gestureName]);
        }
        return null;
    }
}

HPManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;


/// 
/// 血量管理类
/// 
public class HPManager : MonoBehaviour
{
    public int HP = 10000;

    private void Awake()
    {
        EventCenter.AddListener(EventDefine.UpdateHP, UpdateHP);
        EventCenter.AddListener(EventDefine.BombBrust, BombBrust);
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.UpdateHP, UpdateHP);
        EventCenter.RemoveListener(EventDefine.BombBrust, BombBrust);
    }
    /// 
    /// 炸弹爆炸
    /// 
    /// 
    private void BombBrust(Vector3 brustPos)
    {
        if (Vector3.Distance(transform.position, brustPos) < 10.0f)
        {
            UpdateHP(-20);
        }
    }
    /// 
    /// 更新血量
    /// 
    /// 
    private void UpdateHP(int count)
    {
        if (count < 0)
        {
            if (HP <= Mathf.Abs(count))//血量小于0  挂掉
            {
                //死亡
                HP = 0;  
                Death(); //加载当前活跃的场景
            }
            else
            {
                HP += count;  //增加血量
            }
        }
        else
        {
            HP += count;
        }
        EventCenter.Broadcast(EventDefine.UpdateHpUI, HP);  //广播更新血量的事件码
    }
    private void Death()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);  //加载当前场景
    }
}

Magazine

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/// 
/// 弹夹管理类
/// 
public class Magazine : MonoBehaviour
{
    /// 
    /// 子弹数量
    /// 
    private int BulletCount = 6;

    /// 
    /// 设置子弹的方法
    /// 
    /// 
    public void SetBulletCount(int count)
    {
        BulletCount = count;
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Backet")
        {
            if (transform.parent != null && transform.parent.GetComponentInChildren() != null)
            {
                Destroy(gameObject);
                transform.parent.GetComponentInChildren().Catch(false);
                //加子弹
                AmmoManager.Instance.UpdateBullet(BulletCount);
            }
        }
    }
}

Pistol

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;


/// 
/// 手枪
/// 
public class Pistol : MonoBehaviour
{
    public EventDefine ShotEvent;//射击事件  这两个要在面板上指定是哪个事件  分别是左右手  
    public EventDefine ReloadMagazineEvent;//换弹夹  指定类型在面板上赋值  为了方便广播事件

    public Transform m_StartPos; //起始位置
    public GameObject go_Point;
    public GameObject effect_HitOtherMask; //黑洞
    public GameObject effect_HitOther;//烟雾特效
    public GameObject effect_Fire; //火的特效
    public GameObject effect_Blood; //血特效
    public GameObject go_Magazine;//弹夹
    public AudioClip audio_Shot; //射击声音片段

    private LineRenderer m_LineRenderer; //渲染
    private Animator m_Anim;//动画
    private RaycastHit m_Hit;//射线
    public int m_CurrentBulletCount = 6; //弹夹数量
    private AudioSource m_AudioSource; 

    private void Awake()
    {
        m_AudioSource = GetComponent(); //获取组件
        m_LineRenderer = GetComponent();
        m_Anim = GetComponent();
        EventCenter.AddListener(ShotEvent, Shot);//添加射击监听  广播事件是分别执行左右手
        EventCenter.AddListener(ReloadMagazineEvent, ReloadMagazine);//添加换弹夹事件  广播时候左右手按下圆盘时候
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(ShotEvent, Shot);//移除监听射击事件
        EventCenter.RemoveListener(ReloadMagazineEvent, ReloadMagazine); //移除换弹夹事件
    }
    /// 
    /// 换弹夹
    /// 
    private void ReloadMagazine()
    {
        //代表是Main场景 则忽略
        if (SceneManager.GetActiveScene().buildIndex == 0) return;
        //如果手枪是隐藏的,则忽略
        if (gameObject.activeSelf == false) return;
        //如果当前正在播放开火的动画,则忽略
        if (m_Anim.GetCurrentAnimatorStateInfo(0).IsName("Fire")) return;
        //如果当前正在播放换弹夹的动画,则忽略
        if (m_Anim.GetCurrentAnimatorStateInfo(0).IsName("Reload")) return;

        if (GameObject.FindObjectOfType() != null)
            if (GameObject.FindObjectOfType().transform.localScale != Vector3.zero)
                return;

        int temp = m_CurrentBulletCount;  //当前数量
        m_CurrentBulletCount = AmmoManager.Instance.ReloadMagazine(); //单例模式
        if (m_CurrentBulletCount != 0)
        {
            m_Anim.SetTrigger("Reload");
            GameObject go = Instantiate(go_Magazine, transform.Find("Magazine").position, transform.Find("Magazine").rotation);
            go.GetComponent().SetBulletCount(temp);
        }
    }
    /// 
    /// 射击
    /// 
    private void Shot()
    {
        //代表是Main场景 则忽略
        if (SceneManager.GetActiveScene().buildIndex == 0) return;
        //如果手枪是隐藏的,则忽略
        if (gameObject.activeSelf == false) return;
        //如果当前正在播放开火的动画,则忽略
        if (m_Anim.GetCurrentAnimatorStateInfo(0).IsName("Fire")) return;
        //如果当前正在播放换弹夹的动画,则忽略
        if (m_Anim.GetCurrentAnimatorStateInfo(0).IsName("Reload")) return;

        if (m_CurrentBulletCount <= 0) return;
        m_CurrentBulletCount--; //子弹数量减减
        //播放射击动画
        m_Anim.SetTrigger("Shot");

        if (m_AudioSource.isPlaying == false)
        {
            m_AudioSource.clip = audio_Shot;
            m_AudioSource.Play();
        }
        Destroy(Instantiate(effect_Fire, m_StartPos.position, m_StartPos.rotation), 1.5f);

        if (m_Hit.collider != null)
        {
            //是否是僵尸
            if (m_Hit.collider.tag == "Zombie")
            {
                if (m_Hit.transform.GetComponent() != null)
                {
                    m_Hit.transform.GetComponent().Hit();
                }
                if (m_Hit.transform.GetComponent() != null)
                {
                    m_Hit.transform.GetComponent().Hit();
                }
                //实例化血的特效,1.5秒之后销毁
                Destroy(Instantiate(effect_Blood, m_Hit.point, Quaternion.LookRotation(m_Hit.normal)), 2f);  //旋转看向受伤的地方
            }
            else
            {
                GameObject mask = Instantiate(effect_HitOtherMask, m_Hit.point, Quaternion.LookRotation(m_Hit.normal));//黑洞遮罩
                mask.transform.parent = m_Hit.transform;
                Destroy(Instantiate(effect_HitOther, m_Hit.point, Quaternion.LookRotation(m_Hit.normal)), 2);//实例化烟雾 2秒后消失
            }
        }
    }
    /// 
    /// 画线
    /// 
    private void DrawLine(Vector3 startPos, Vector3 endPos, Color color)
    {
        m_LineRenderer.positionCount = 2;
        m_LineRenderer.SetPosition(0, startPos);
        m_LineRenderer.SetPosition(1, endPos);
        m_LineRenderer.startWidth = 0.001f;
        m_LineRenderer.endWidth = 0.001f;
        m_LineRenderer.material.color = color;
    }
    private void FixedUpdate()
    {
        if (Physics.Raycast(m_StartPos.position, m_StartPos.forward, out m_Hit, 100000, 1 << 0 | 1 << 2))  //检测第一层 第二层 如果1是0 的话表示是不检测
        {
            DrawLine(m_StartPos.position, m_Hit.point, Color.green);
            go_Point.SetActive(true);
            go_Point.transform.position = m_Hit.point;
        }
        else
        {
            DrawLine(m_StartPos.position, m_StartPos.forward * 100000, Color.red);
            go_Point.SetActive(false);
        }
    }
}

ZombieController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;



/// 
/// 控制器
/// 
public class ZombieController : MonoBehaviour
{
    public float m_WalkSpeed = 0.8f;//走路速度
    public float m_RunSpeed = 2;//跑步速度
    public float m_DistanceJudge = 1f;  //距离判断
    public float m_HitDealyTime = 2f;  //受伤延迟

    /// 
    /// 攻击时间间隔
    /// 
    public float m_AttackInterval = 3f;
    public AudioClip audio_Attack;
    public AudioClip audio_Walk;

    private NavMeshAgent m_Agent; //导航网格
    private Animator m_Anim;
    private Transform m_Target; //相机位置
    /// 
    /// 是否第一次攻击
    /// 
    private bool m_IsFirstAttack = true;
    private float m_Timer = 0.0f;
    /// 
    /// 是否正在攻击
    /// 
    private bool m_IsAttacking = false;
    /// 
    /// 是否正在受伤中
    /// 
    private bool m_IsHitting = false;
    /// 
    /// 僵尸是否死亡
    /// 
    private bool m_IsDeath = false;
    public bool IsDeath
    {
        get
        {
            return m_IsDeath;
        }
    }
    private AudioSource m_AudioSource;  //声效

    private void Awake()
    {
        m_AudioSource = GetComponent();
        m_Anim = GetComponent();
        m_Agent = GetComponent();
        m_Target = Camera.main.transform;  //相机信息
        EventCenter.AddListener(EventDefine.BombBrust, BombBrust); //监听炸弹爆炸的事件码
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.BombBrust, BombBrust);//移除炸弹爆炸的事件码
    }
    private void Start()
    {
        RandomWalkOrRun();
    }
    private void FixedUpdate()
    {
        if (m_IsDeath) return;
        if (m_IsHitting) return;

        Vector3 tempTargetPos = new Vector3(m_Target.position.x, transform.position.y, m_Target.position.z); //获取物体的位置

        if (Vector3.Distance(transform.position, tempTargetPos) < m_DistanceJudge) //判断相机跟物体之间的距离
        {
            if (m_Agent.isStopped == false)
            {
                m_Agent.isStopped = true; //停止导航
            }

            if (m_IsAttacking == false)
            {
                m_Timer += Time.deltaTime;
                if (m_Timer >= m_AttackInterval)
                {
                    m_Timer = 0.0f;
                    m_IsAttacking = true; //调用攻击的函数
                    Attack();
                }
            }
            if (m_Anim.GetCurrentAnimatorStateInfo(0).IsName("AttackBlendTree") == false) //第0层的播放动画名称
            {
                if (m_IsFirstAttack)  //标志位 只加一次0.5f  之后不加 避免判断距离越来越大
                {
                    m_DistanceJudge += 0.5f; //避免根据距离动画来回播放
                    m_IsFirstAttack = false; 
                    m_IsAttacking = true;
                    Attack();
                }
                else
                {
                    m_IsAttacking = false;
                }
            }
        }
        else
        {  //没达到距离 继续寻路
            if (m_Agent.isStopped)
            {
                m_DistanceJudge -= 0.5f; //避免根据距离动画来回播放
                m_Agent.isStopped = false;  //继续寻路
                m_IsFirstAttack = true;
                RandomWalkOrRun();//随机走或跑
            }
            m_Agent.SetDestination(Camera.main.transform.position);  //设置新的目的地
        }
    }
    /// 
    /// 炸弹爆炸
    /// 
    /// 
    private void BombBrust(Vector3 brustPos)
    {
        if (Vector3.Distance(transform.position, brustPos) < 10.0f)  //爆炸距离之内
        {
            BodyPartDrop[] drops = transform.GetComponentsInChildren();//查找子物体上的所有组件 数组
            foreach (var item in drops)
            {
                item.Hit();
            }
            Death();
        }
    }
    /// 
    /// 死亡
    /// 
    public void Death()
    {
        if (m_IsDeath) return; //如果挂掉就返回 不用重复执行
        PlayAnim(4, "Death", "DeathValue"); //4中随机死亡动画 
        m_Agent.isStopped = true; //停止寻路
        m_IsDeath = true;  
        Destroy(m_Agent); //销毁寻路组件  不销毁的话可能悬在半空中
        EventCenter.Broadcast(EventDefine.ZombieDeath);
    }
    /// 
    /// 左边受伤
    /// 
    public void HitLeft()
    {
        m_Anim.SetTrigger("HitLeft");
        m_Agent.isStopped = true;
        m_Anim.SetTrigger("Idle");
        m_IsHitting = true;
        StartCoroutine(HitDealy());  //受伤之后有一定的延迟
    }
    /// 
    /// 右边受伤
    /// 
    public void HitRight()
    {
        m_Anim.SetTrigger("HitRight");
        m_Agent.isStopped = true;
        m_Anim.SetTrigger("Idle");
        m_IsHitting = true;
        StartCoroutine(HitDealy());
    }
    /// 
    /// 随机受伤动画
    /// 
    public void Hit()
    {
        PlayAnim(3, "Hit", "HitValue"); //3种随机动画
        m_Agent.isStopped = true;
        m_Anim.SetTrigger("Idle");
        m_IsHitting = true;
        StartCoroutine(HitDealy());
    }
    IEnumerator HitDealy()
    {
        yield return new WaitForSeconds(m_HitDealyTime);
        m_Agent.isStopped = false;
        m_IsHitting = false;
        RandomWalkOrRun();
    }
    /// 
    /// 攻击
    /// 
    private void Attack()
    {
        if (m_AudioSource.isPlaying == false)
        {
            m_AudioSource.clip = audio_Attack;
            m_AudioSource.Play();
        }
        EventCenter.Broadcast(EventDefine.UpdateHP, -10);  //广播减少血量事件
        EventCenter.Broadcast(EventDefine.ScreenBlood);
        Vector3 targetPos = new Vector3(m_Target.position.x, transform.position.y, m_Target.position.z);
        transform.LookAt(targetPos);

        PlayAnim(6, "Attack", "AttackValue"); //随机攻击动画片段
    }
    /// 
    /// 随机播放跑或者走的动画
    /// 
    private void RandomWalkOrRun()
    {
        int ran = Random.Range(0, 2); //只随机0,1
        if (ran == 0)
        {
            //走
            WalkAnim();
            m_Agent.speed = m_WalkSpeed;
        }
        else
        {
            //跑
            RunAnim();
            m_Agent.speed = m_RunSpeed;
        }
    }
    /// 
    /// 走路动画
    /// 
    private void WalkAnim() 
    {
        if (m_AudioSource.isPlaying == false)
        {
            m_AudioSource.clip = audio_Walk;
            m_AudioSource.Play();
        }
        PlayAnim(3, "Walk", "WalkValue");
    }
    /// 
    /// 跑的动画
    /// 
    private void RunAnim()
    {
        PlayAnim(2, "Run", "RunValue");
    }

    /// 
    /// 随机动画片段  走路3个  跑步2个 0.5f递增
    /// 
    /// 
    /// 
    /// 
    private void PlayAnim(int clipCount, string triggerName, string floatName)
    {
        float rate = 1.0f / (clipCount - 1);  //等于0.5  或者 1
        m_Anim.SetTrigger(triggerName);  //设置动画触发器
        m_Anim.SetFloat(floatName, rate * Random.Range(0, clipCount));  //0.5*0、1、2 或 1*0、1
    }
}

HandManger:

HandManger

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HighlightingSystem;
using VRTK;

public enum GrabObjectType
{
    None,
    Other,
    Book,
    Pistol,
    Belt,
    Magazine,
    Bomb,
}
public enum HandAnimStateType
{
    None,
    Pistol,
}


/// 
/// 左右手管理类
/// 
public class HandManger : MonoBehaviour
{
    /// 
    /// 监听抓取按键按下的事件码
    /// 
    public EventDefine GrabEvent;  //定义不同类型 监听左右手柄不同的事件
    public EventDefine ShotEvent;
    public EventDefine UseBombEvent;
    public EventDefine UsePistolEvent;

    public GameObject go_Bomb;  //炸弹
    public float m_ThrowMulitiple = 1f;

    private Animator m_Anim; //动画
    /// 
    /// 是否可以抓取
    /// 
    private bool m_IsCanGrab = false;
    /// 
    /// 当前抓取的物体
    /// 
    public GameObject m_GrabObj = null;
    public GrabObjectType m_GrabObjectType = GrabObjectType.None;

    public StateModel[] m_StateModels;

    [System.Serializable]  //序列化
    public class StateModel
    {
        public HandAnimStateType StateType;
        public GameObject go;
    }

    /// 
    /// 判断手是否触碰到可以抓取的物体
    /// 
    private bool m_IsTrigger = false;
    /// 
    /// 是否使用手枪
    /// 
    private bool m_IsUsePistol = false;
    /// 
    /// 是否使用炸弹
    /// 
    private bool m_IsUseBomb = false;
    private VRTK_ControllerEvents controllerEvents;

    private void Awake()
    {
        m_Anim = GetComponent();
        controllerEvents = GetComponentInParent();
        EventCenter.AddListener(GrabEvent, IsCanGrab);
        EventCenter.AddListener(ShotEvent, Shot);
        EventCenter.AddListener(UseBombEvent, UseBomb);
        EventCenter.AddListener(UsePistolEvent, UsePistol);
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(GrabEvent, IsCanGrab);
        EventCenter.RemoveListener(ShotEvent, Shot);
        EventCenter.RemoveListener(UseBombEvent, UseBomb);
        EventCenter.RemoveListener(UsePistolEvent, UsePistol);
    }
    /// 
    /// 射击
    /// 
    private void Shot()
    {
        if (m_Anim.GetInteger("State") != (int)HandAnimStateType.Pistol) return;

        m_Anim.SetTrigger("Shot");
    }
    /// 
    /// 是否可以抓取物体的监听方法
    /// 
    /// 
    private void IsCanGrab(bool value)
    {
        if (value == false)
        {
            if (m_GrabObj != null && m_GrabObjectType == GrabObjectType.Bomb)
            {
                //代表拿的是炸弹
                ThrowBomb();
            }
        }
        //释放抓取的物体
        if (value)
        {
            if (m_GrabObj != null)
            {
                if (m_GrabObjectType == GrabObjectType.Other)
                {
                    m_GrabObj.transform.parent = null;
                    m_GrabObj = null;
                    m_GrabObjectType = GrabObjectType.None;
                }
                else if (m_GrabObjectType == GrabObjectType.Book)
                {
                    if (m_GrabObj.GetComponent().m_IsTrigger)
                    {
                        m_GrabObj.GetComponent().Put();
                    }
                    else
                    {
                        m_GrabObj.transform.parent = null;
                        m_GrabObj.transform.position = m_GrabObj.GetComponent().m_StratPos;
                        m_GrabObj.transform.rotation = m_GrabObj.GetComponent().m_StartRot;
                    }

                    m_GrabObj = null;
                    m_GrabObjectType = GrabObjectType.None;
                }
                else if (m_GrabObjectType == GrabObjectType.Belt || m_GrabObjectType == GrabObjectType.Magazine)
                {
                    m_GrabObj.transform.parent = null;
                    m_GrabObj.GetComponent().useGravity = true;
                    m_GrabObj.GetComponent().constraints = RigidbodyConstraints.None;
                    m_GrabObj = null;
                    m_GrabObjectType = GrabObjectType.None;
                }
                return;
            }
        }
        if (m_GrabObj == null)
            m_Anim.SetBool("Catch", value);
        m_IsCanGrab = value;

        PistolOrBombChangeHand();
    }
    /// 
    /// 投掷炸弹
    /// 
    private void ThrowBomb()
    {
        //更新炸弹数量
        AmmoManager.Instance.UpdateBomb();

        m_GrabObj.transform.parent = null; //设置父物体为空
        m_GrabObj.AddComponent();//添加刚体
        m_Anim.SetBool("Catch", false);//播放动画
        m_GrabObjectType = GrabObjectType.None; //抓取物体类型为空

        Vector3 velocity = controllerEvents.GetVelocity(); //获取手柄速度
        Vector3 angularVelocity = controllerEvents.GetAngularVelocity();//获取手柄角速度

        m_GrabObj.GetComponent().velocity = transform.parent.parent.TransformDirection(velocity) * m_ThrowMulitiple;//速度
        m_GrabObj.GetComponent().angularVelocity = transform.parent.parent.TransformDirection(angularVelocity); //角速度
        m_GrabObj.GetComponent().IsThrow = true;//可以扔
        m_GrabObj = null;
        m_IsUseBomb = false;

        UsePistol();//投掷玩之后切换成手枪
    }
    /// 
    /// 手枪换手 炸弹换手
    /// 
    private void PistolOrBombChangeHand()
    {
        //1.满足当前手没有抓取任何物体
        //2.当前手没有触碰到任何可以抓取的物体
        //3.另外一只手要保证拿着枪
        if (m_GrabObj == null && m_IsTrigger == false && m_IsCanGrab == false)
        {
            HandManger[] handMangers = GameObject.FindObjectsOfType();
            foreach (var handManger in handMangers)
            {
                if (handManger != this)
                {
                    //手枪换手
                    if (handManger.m_IsUsePistol)
                    {
                        UsePistol();
                        handManger.UnUsePistol();
                        m_StateModels[0].go.GetComponent().m_CurrentBulletCount =
                            handManger.m_StateModels[0].go.GetComponent().m_CurrentBulletCount;  //手枪换手 子弹同步
                    }
                    //炸弹换手
                    if (handManger.m_IsUseBomb)
                    {
                        handManger.UnUseBomb();
                        UseBomb();
                    }
                }
            }
        }
    }
    /// 
    /// 抓取
    /// 作用:一只手拿另外一种手的物体的一些逻辑处理
    /// 
    /// 
    public void Catch(bool value)
    {
        if (m_GrabObj != null)
        {
            m_GrabObj = null;
            m_GrabObjectType = GrabObjectType.None;
        }
        m_Anim.SetBool("Catch", value);
    }
    /// 
    /// 使用炸弹
    /// 
    private void UseBomb()
    {
        if (AmmoManager.Instance.IsHasBomb() == false) return;

        //判断当前右手是否拿着物品,如果拿着则卸掉
        if (m_GrabObj != null)
        {
            if (m_GrabObjectType == GrabObjectType.Pistol)
            {
                UnUsePistol();
            }
            else if (m_GrabObjectType == GrabObjectType.Belt || m_GrabObjectType == GrabObjectType.Magazine)
            {
                m_GrabObj.transform.parent = null;
                m_GrabObj.GetComponent().useGravity = true;
                m_GrabObj.GetComponent().constraints = RigidbodyConstraints.None; //解除
                m_GrabObj = null;
                m_GrabObjectType = GrabObjectType.None;
            }
            else if (m_GrabObjectType == GrabObjectType.Bomb)  //拿到炸弹就返回
            {
                return;
            }
        }
        Transform target = transform.parent.Find("BombTarget");  //重置炸弹位置
        GameObject bomb = Instantiate(go_Bomb, transform.parent);
        bomb.transform.localPosition = target.localPosition;
        bomb.transform.localRotation = target.localRotation;
        bomb.transform.localScale = target.localScale;

        m_GrabObj = bomb;
        m_GrabObjectType = GrabObjectType.Bomb;
        m_Anim.SetBool("Catch", true);
        m_IsUseBomb = true;
    }
    /// 
    /// 卸载炸弹
    /// 
    public void UnUseBomb()
    {
        m_IsUseBomb = false;
        Destroy(m_GrabObj);
        m_GrabObj = null;
        m_GrabObjectType = GrabObjectType.None;
        m_Anim.SetBool("Catch", false);
    }
    /// 
    /// 使用手枪
    /// 
    private void UsePistol()
    {
        if (m_GrabObj != null)
        {
            if (m_GrabObjectType == GrabObjectType.Belt || m_GrabObjectType == GrabObjectType.Magazine)
            {
                m_GrabObj.transform.parent = null;
                m_GrabObj.GetComponent().useGravity = true;
                m_GrabObj.GetComponent().constraints = RigidbodyConstraints.None;
                m_GrabObj = null;
                m_GrabObjectType = GrabObjectType.None;
            }
            else if (m_GrabObjectType == GrabObjectType.Bomb)
            {
                UnUseBomb();
            }
            else if (m_GrabObjectType == GrabObjectType.Pistol)
            {
                return;
            }
        }
        m_IsUsePistol = true;
        m_Anim.SetBool("Catch", false);
        m_GrabObjectType = GrabObjectType.Pistol;
        m_GrabObj = m_StateModels[0].go;
        //切换成拿枪的动画
        //显示手枪
        TurnState(HandAnimStateType.Pistol);
    }
    /// 
    /// 卸下手枪
    /// 
    public void UnUsePistol()
    {
        m_IsUsePistol = false;
        m_Anim.SetBool("Catch", false);
        m_GrabObjectType = GrabObjectType.None;
        m_GrabObj = null;
        TurnState(HandAnimStateType.None);
    }
    private void TurnState(HandAnimStateType stateType)
    {
        m_Anim.SetInteger("State", (int)stateType);
        foreach (var item in m_StateModels)
        {
            if (item.StateType == stateType && item.go.activeSelf == false)
            {
                item.go.SetActive(true);
            }
            else if (item.go.activeSelf)
            {
                item.go.SetActive(false);
            }
        }
    }
    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Others" || other.tag == "Book" || other.tag == "Pistol" || other.tag == "Belt" || other.tag == "Magazine")
        {
            m_IsTrigger = true;
        }
        if (other.GetComponent() != null)  //开启高亮  红色  注意引入命名空间
        {
            other.GetComponent().On(Color.red); 
        }
        if (other.tag == "Others" && m_IsCanGrab && m_GrabObj == null)
        {
            ProcessGrab(other);
            m_GrabObjectType = GrabObjectType.Other; //抓取物体的类型
        }
        else if (other.tag == "Book" && m_IsCanGrab && m_GrabObj == null)
        {
            ProcessGrab(other);
            m_GrabObjectType = GrabObjectType.Book; //抓取书
        }
        else if (other.tag == "Pistol" && m_IsCanGrab && m_GrabObj == null)
        {
            EventCenter.Broadcast(EventDefine.WearPistol);
            Destroy(other.gameObject);
            UsePistol();
        }
        else if (other.tag == "Belt" && m_IsCanGrab && m_GrabObj == null)
        {
            ProcessGrab(other);
            other.GetComponent().useGravity = false;
            other.GetComponent().constraints = RigidbodyConstraints.FreezeAll;
            m_GrabObjectType = GrabObjectType.Belt;
        }
        else if (other.tag == "Magazine" && m_IsCanGrab && m_GrabObj == null)
        {
            ProcessGrab(other);
            other.GetComponent().useGravity = false;
            other.GetComponent().constraints = RigidbodyConstraints.FreezeAll;
            m_GrabObjectType = GrabObjectType.Magazine;
        }
    }
    /// 
    /// 处理抓取
    /// 
    /// 
    private void ProcessGrab(Collider other)
    {
        //一只手拿另外一种手的物体的一些逻辑处理
        if (other.transform.parent != null)
        {
            if (other.transform.parent.tag == "ControllerRight" || other.transform.parent.tag == "ControllerLeft")
            {
                other.transform.parent.GetComponentInChildren().Catch(false);
            }
        }
        Catch(true);
        other.gameObject.transform.parent = transform.parent;
        m_GrabObj = other.gameObject;
    }
    private void OnTriggerExit(Collider other)
    {
        if (other.GetComponent() != null)
        {
            other.GetComponent().Off();  //关闭高亮
        }
        m_IsTrigger = false;
    }
}

UI:

AmmoManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// 
/// 弹药库的管理
/// 
public class AmmoManager : MonoBehaviour
{
    public static AmmoManager Instance;  //单例模式
    /// 
    /// 子弹数量
    /// 
    public int BulletCount;
    /// 
    /// 炸弹数量
    /// 
    public int BombCount;

    private Transform target; //目标物体
    private Text txt_Bullet;//子弹数量
    private Text txt_Bomb;//炸弹数量

    private void Awake()
    {
        Instance = this; //单例赋值
    }
    private void Start()
    {
        txt_Bullet = transform.Find("Bullet/Text").GetComponent();
        txt_Bomb = transform.Find("Bomb/Text").GetComponent();
        target = GameObject.FindGameObjectWithTag("CameraRig").transform; //查找目标物体
        EventCenter.AddListener(EventDefine.WearBelt, Show); //监听穿戴事件
        gameObject.SetActive(false); //默认隐藏
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.WearBelt, Show); //移除监听事件
    }

    /// 
    /// 实时跟踪位置和旋转信息
    /// 
    private void FixedUpdate()
    {
        float height = target.GetComponent().height;
        transform.position = new Vector3(Camera.main.transform.position.x, height, Camera.main.transform.position.z);
        transform.eulerAngles = new Vector3(transform.eulerAngles.x, Camera.main.transform.eulerAngles.y, 0);
    }
    /// 
    /// 显示弹药库界面
    /// 
    private void Show()
    {
        gameObject.SetActive(true); //显示界面
        UpdateBullet(0);//执行更新子弹的函数
        UpdateBomb(0);//执行更新炸弹的函数
    }
    /// 
    /// 重装弹夹
    /// 
    public int ReloadMagazine()
    {
        if (BulletCount >= 6)
        {
            UpdateBullet(-6);
            return 6;
        }
        else
        {
            int temp = BulletCount;
            BulletCount = 0;
            UpdateBullet(0);
            return temp;
        }
    }
    /// 
    /// 是否有手榴弹
    /// 
    /// 
    public bool IsHasBomb()
    {
        if (BombCount <= 0)
        {
            return false;
        }
        return true;
    }
    /// 
    /// 更新子弹数量
    /// 
    /// 
    public void UpdateBullet(int count)
    {
        BulletCount += count;
        txt_Bullet.text = BulletCount.ToString();
    }
    /// 
    /// 更新手榴弹数量
    /// 
    /// 
    public void UpdateBomb(int count = -1)
    {
        BombCount += count;
        txt_Bomb.text = BombCount.ToString();
    }
}

Loading

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;



/// 
/// 异步加载
/// 
public class Loading : MonoBehaviour
{
    public string LoadSceneName;
    private Text text;
    private AsyncOperation m_Ao; //异步加载操作
    private bool m_IsLoad = false;

    private void Awake()
    {
        text = GetComponent();
        gameObject.SetActive(false);
        EventCenter.AddListener(EventDefine.StartLoadScene, StartLoadScene);  //监听异步加载的事件
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.StartLoadScene, StartLoadScene); //移除监听事件
    }
    private void StartLoadScene()
    {
        gameObject.SetActive(true);
        StartCoroutine("Load");//只有引号才能停止协程
    }
    IEnumerator Load()
    {
        int startProcess = -1;
        int endProcess = 100;
        while (startProcess < endProcess)
        {
            startProcess++;
            Show(startProcess);
            if (m_IsLoad == false)
            {
                m_Ao = SceneManager.LoadSceneAsync(LoadSceneName); //异步加载场景
                m_Ao.allowSceneActivation = false;//先没有激活场景  加载完成后再激活
                m_IsLoad = true;
            }
            yield return new WaitForEndOfFrame(); //等待加载完成
        }
        if (startProcess == 100)
        {
            m_Ao.allowSceneActivation = true;
            StopCoroutine("Load");
        }
    }
    private void Show(int value)
    {
        text.text = value.ToString() + "%";
    }
}

RadialMenuManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



/// 
/// 圆环控制器
/// 
public class RadialMenuManager : MonoBehaviour
{
    private bool m_IsWearBelt = false;
    private bool m_IsWearPistol = false;

    private void Awake()
    {
        gameObject.SetActive(false); //默认圆环是隐藏的
        EventCenter.AddListener(EventDefine.WearBelt, WearBelt);  //监听手枪拿起和腰带佩戴上才可以 显示圆环
        EventCenter.AddListener(EventDefine.WearPistol, WearPistol);
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.WearBelt, WearBelt);
        EventCenter.RemoveListener(EventDefine.WearPistol, WearPistol);
    }
    /// 
    /// 腰带穿戴上的监听方法
    /// 
    private void WearBelt()
    {
        m_IsWearBelt = true;
        if (m_IsWearBelt && m_IsWearPistol)
        {
            gameObject.SetActive(true);  //腰带和枪都带上才能显示圆环  在广播带上枪和腰带的方法  Belt 17  HandManger 357
        }
    }
    /// 
    /// 枪拿起的监听方法
    /// 
    private void WearPistol()
    {
        m_IsWearPistol = true;
        if (m_IsWearBelt && m_IsWearPistol)
        {
            gameObject.SetActive(true);
        }
    }

    /// 
    /// 圆盘上点击手枪的函数
    /// 
    public void OnUsePistolClick()
    {
        HandManger handManger = transform.parent.parent.parent.GetComponentInChildren();  //获取手管理类 注意父级关系
        if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Pistol)   //判断手上握的是手枪 则卸载手枪
        {
            handManger.UnUsePistol();
        }
        if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Bomb) //握住炸弹则卸载炸弹
        {
            handManger.UnUseBomb();
        }
        EventCenter.Broadcast(EventDefine.UsePistol);  //广播使用手枪的事件码
        EventCenter.Broadcast(EventDefine.IsStartGestureRecognition, false);//广播使用手势的事件码  不可以使用
    }

    /// 
    /// 圆盘上点击炸弹的函数
    /// 
    public void OnUseBombClick()
    {
        HandManger handManger = transform.parent.parent.parent.GetComponentInChildren();  //避免左手拿到手枪之后不能继续切换
        if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Pistol)  
        {
            handManger.UnUsePistol(); //卸载手枪
        }
        if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Bomb)
        {
            handManger.UnUseBomb();//卸载炸弹
        }
        EventCenter.Broadcast(EventDefine.UseBomb); //广播使用炸弹的事件码 
        EventCenter.Broadcast(EventDefine.IsStartGestureRecognition, false); //广播使用手势的事件码 不可使用
    }
    /// 
    /// 圆盘上点击手势的按钮
    /// 
    public void OnUseGestureClick()
    {
        HandManger[] handMangers = GameObject.FindObjectsOfType();  //无论手上握住任何东西都卸载
        foreach (var handManger in handMangers)
        {
            if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Pistol)
            {
                handManger.UnUsePistol(); //手上有枪则卸载
            }
            if (handManger.m_GrabObj != null && handManger.m_GrabObjectType == GrabObjectType.Bomb)
            {
                handManger.UnUseBomb();//手上有炸弹则卸载
            }
        }
        EventCenter.Broadcast(EventDefine.IsStartGestureRecognition, true); //广播使用手势的事件码  可以使用手势  点击圆盘其他按钮的时候广播 不可用手势识别 false
    }
}

Gesture:

BaseGestureRecognition

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Edwon.VR;
using Edwon.VR.Gesture;


/// 
/// 手势识别基类  抽象类
/// 
public abstract class BaseGestureRecognition : MonoBehaviour
{
    private VRGestureSettings gestureSettings;
    protected VRGestureRig gestureRig;

    public abstract void OnGestureDetectedEvent(string gestureName, double confidence); //抽象的方法

    public virtual void Awake()  //虚方法 要重写
    {
        gestureSettings = Utils.GetGestureSettings();
        gestureRig = VRGestureRig.GetPlayerRig(gestureSettings.playerID);
        GestureRecognizer.GestureDetectedEvent += GestureRecognizer_GestureDetectedEvent; //监听事件 自动补全方法
    }
    public virtual void OnDestroy()  //虚方法
    {
        GestureRecognizer.GestureDetectedEvent -= GestureRecognizer_GestureDetectedEvent;//移除监听
    }
    /// 
    /// 当手势被检测到
    /// 
    /// 
    /// 
    /// 
    /// 
    private void GestureRecognizer_GestureDetectedEvent(string gestureName, double confidence, Handedness hand, bool isDouble = false) //手势名称  识别精度 左右手  是否双手
    {
        OnGestureDetectedEvent(gestureName, confidence);
    }
    /// 
    /// 开始手势识别  受保护
    /// 
    protected void BeginRecognition()
    {
        gestureRig.BeginDetect();
    }
}

GestureDetectedPanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Edwon.VR;
using Edwon.VR.Gesture;

public class GestureDetectedPanel : BaseGestureRecognition
{
    private Button btn_Back;
    private Text txt_GestureName;
    private Text txt_GestureConfidence;

    public override void Awake()
    {
        base.Awake();
        btn_Back = transform.Find("btn_Back").GetComponent

GestureEditPanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Edwon.VR;
using Edwon.VR.Gesture;

public class GestureEditPanel : MonoBehaviour
{
    public GameObject go_GestureExampleItem;
    public Material m_Mat;
    private Text txt_GestureName;
    private Button btn_Back;
    private Button btn_Record;

    private VRGestureSettings gestureSettings;
    private VRGestureRig gestureRig;
    /// 
    /// 手势所对应的所有的手势记录list
    /// 
    private List gestureExamples = new List();
    private List exampleObjList = new List();
    /// 
    /// 手势名字
    /// 
    private string m_GestureName;
    /// 
    /// 判断是否开始录制
    /// 
    private bool m_IsStartRecord = false;

    private void Awake()
    {
        gestureSettings = Utils.GetGestureSettings();
        gestureRig = VRGestureRig.GetPlayerRig(gestureSettings.playerID);

        EventCenter.AddListener(EventDefine.ShowGestureEditPanel, Show);
        EventCenter.AddListener(EventDefine.FinishedOnceRecord, FinishedOnceRecord);
        EventCenter.AddListener(EventDefine.UIPointHovering, UIPointHovering);
        Init();
    }
    private void Init()
    {
        txt_GestureName = transform.Find("txt_GestureName").GetComponent();
        btn_Back = transform.Find("btn_Back").GetComponent

GestureMainPanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Edwon.VR;
using Edwon.VR.Gesture;

/// 
/// 手势识别
/// 
public class GestureMainPanel : MonoBehaviour
{
    private Button btn_GestureInfo;
    private Button btn_GestureDetect;
    private VRGestureSettings gestureSettings;
    private VRGestureRig gestureRig;

    private void Awake()
    {
        gestureSettings = Utils.GetGestureSettings();//赋值
        gestureRig = VRGestureRig.GetPlayerRig(gestureSettings.playerID);

        btn_GestureInfo = transform.Find("btn_GestureInfo").GetComponent

SkillChoosePanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SkillChoosePanel : MonoBehaviour
{
    private string m_GestureName;

    private void Awake()
    {
        EventCenter.AddListener(EventDefine.ShowSkillChoosePanel, Show);
        Init();
    }
    private void Init()
    {
        transform.Find("btn_Back").GetComponent

三、效果图

VR开发实战HTC Vive项目之僵尸大战(语音唤醒与手势识别)_第2张图片

你可能感兴趣的:(VR开发实战HTC Vive项目之僵尸大战(语音唤醒与手势识别))