《SteamVR2.2.0官方教程(一)》(Yanlz+Unity+XR+VR+AR+MR+SteamVR+Valve+Oculus+Tutorials+Interaction+立钻哥哥++ok++)

《SteamVR2.2.0官方教程》

《SteamVR2.2.0官方教程》

版本html

做者git

参与者github

完成日期面试

备注算法

SteamVR2.2.0_Tutorials_V01_1.0数据库

严立钻编程

 

2019.04.15设计模式

 

 

 

 

 

 

 

##《SteamVR2.2.0官方教程》发布说明:

++++“SteamVR2.2.0官方教程”:是对“SteamVR2.2.0”的官方教程(Tutorials)梳理总结;(2019年度的重点技术突破点确立为:“SteamVR”)(前面已经有了一个“V2.0”和“V2.2.0”开发指南了:http://www.javashuo.com/article/p-wgdghzsl-er.htmlhttp://www.javashuo.com/article/p-hguaxolf-ew.html;快速入门:http://www.javashuo.com/article/p-fcmbsvpm-gb.html;交互系统:http://www.javashuo.com/article/p-ocssrxuq-gd.html;这个“官方教程”是基于前面几篇操做指南和快速入门的一个拓展,因此能够先粗略查阅一下这几篇博文;这里重点说明一下:实战是关键,因此官方教程是重中之重,后期还会基于熟悉官方示例的基础上拓展应用到现实应用中,敬请期待服务器

++++“SteamVR2.2.0官方教程”:定位在熟悉SteamVR框架网络

 

++++SteamVR的Github:https://github.com/ValveSoftware/steamvr_unity_plugin

++++SteamVR的QuickStart:https://valvesoftware.github.io/steamvr_unity_plugin/

++++SteamVR的Releases:https://github.com/ValveSoftware/steamvr_unity_plugin/releases

++++SteamVR2.2.0开发指南http://www.javashuo.com/article/p-hguaxolf-ew.html

++++SteamVR2.2.0快速入门http://www.javashuo.com/article/p-fcmbsvpm-gb.html

++++SteamVR2.2.0交互系统http://www.javashuo.com/article/p-ocssrxuq-gd.html

++++SteamVR2.2.0传送机制http://www.javashuo.com/article/p-ophuaicg-gh.html

++++SteamVR2.2.0官方教程http://www.javashuo.com/article/p-gblmlsya-gp.html

++++SteamVR2.2.0教程(一)http://www.javashuo.com/article/p-gblmlsya-gp.html

++++SteamVR2.2.0教程(二)http://www.javashuo.com/article/p-fyhwthit-kq.html

 

 

 

##《SteamVR2.2.0官方教程》目录

#第一篇:v2.2.0快速入门

#第二篇:v2.2.0官方教程

#第三篇:v2.2.0的API

#第四篇:v2.2.0框架结构

#第五篇:立钻哥哥对SteamVR的拓展

推广:【XR游戏开发QQ群:784477094

 

 

 

#第一篇:v2.2.0快速入门

#第一篇:v2.2.0快速入门

#第一篇:v2.2.0快速入门

++++立钻哥哥:在“Valve”发布了“The Lab”以后,SteamVR也采用了该项目的经验,建立了一个“交互系统(Interaction System)”,该系统提供了一些经常使用的交互应用,包括:“与Unity UI元素的交互(Interaction with Unity UI elements)”,“拾起,放下,扔出去(Pickup, Drop, and Throw)”,“投掷速度的多种变化(Multiple variations on throwing velocites)”,“弓箭(Bow and Arrow)”,“轮交互(Wheel interactions)”,“邻近按钮(Proximity button)”,“各类骨骼输入示例(Variety of Skeleton Input example)”,“传送(Teleporting)”,“使用抓握对象(Using held objects)”,“使用手持物体的手的骨架输入(Using Skeleton Input to from a hand around a held object)”等,这些都是很是好的应用案例,后期立钻哥哥将一一剖析拓展,敬请期待关注“SteamVR”分类:https://blog.csdn.net/vrunsoftyanlz/article/category/8582642)!

++++SteamVR2.0开发指南:http://www.javashuo.com/article/p-wgdghzsl-er.html

++++SteamVR2.2.0开发指南:http://www.javashuo.com/article/p-hguaxolf-ew.html

++++SteamVR2.2.0快速入门:http://www.javashuo.com/article/p-fcmbsvpm-gb.html

++++SteamVR2.2.0交互系统:http://www.javashuo.com/article/p-ocssrxuq-gd.html

++++A.一、快速入门(Getting started)

++++A.二、示例场景(Sample scene)

 

 

 

##A.一、快速入门(Getting started)

##A.一、快速入门(Getting started)

##A.一、快速入门(Getting started)

++++立钻哥哥:交互系统(Interaction System)是游戏的核心,通常是交互系统先行设计开发,基于交互系统再进行游戏交互的设计和情景设计;那咱们就从“交互系统”出发,快速入门吧!

++++关于SteamVR的快速入门,可查阅这个连接:http://www.javashuo.com/article/p-fcmbsvpm-gb.html

++++获取更多关于SteamVR技术知识,可查阅这个分类:https://blog.csdn.net/vrunsoftyanlz/article/category/8582642

++++A.1.一、交互系统(Interaction System)的认知

++++A.1.二、入门指南(Getting started)

 

 

 

###A.1.一、交互系统(Interaction System)的认知

###A.1.一、交互系统(Interaction System)的认知

++A.1.一、交互系统(Interaction System)的认知

++++立钻哥哥:在Valve发布“The Lab”以后,SteamVR也建立了一个“交互系统”,咱们能够在本身的项目中使用这些例子,该系统也更新使用了“SteamVR Input”和新的“SteamVR Skeleton Input”系统

++++[Interaction with Unity UI elements]:与Unity UI元素的交互

++++[Pickup, Drop, and Throw]:拾起,放下,扔出去

++++[Multiple variations on throwing velocities]:投掷速度的多种变化

++++[Bow and Arrow]:弓箭

++++[Wheel interactions]:轮交互

++++[Proximity button]:邻近按钮

++++[Variety of Skeleton Input example]:各类骨骼输入示例

++++[Teleporting]:传送

++++[Using held objects]:使用抓握对象

++++[Using Skeleton Input to from a hand around a held object]:使用手持物体的手的骨骼输入

 

++“The Lab”中的交互系统(Interaction System)

++++立钻哥哥:“交互系统(Interacion System)”是一系列脚本、预制体和其余资源,是“The Lab”中全部迷你游戏和其余场景的基础,这个系统最初被设计成轻量级和灵活的,这样他就能够支持咱们当时正在进行的全部实验

++++Steam平台上的“The Lab”连接:https://store.steampowered.com/app/450390/The_Lab/

 

 

 

 

###A.1.二、入门指南(Getting Started)

###A.1.二、入门指南(Getting Started)

++A.1.二、入门指南(Getting Started)

++++立钻哥哥:要获取示例,可查看“Assets/SteamVR/InteractionSystem/Samples/Scenes”中的“Interactions_Example”场景

++++Assets/SteamVR/InteractionSystem/Samples/立钻哥哥的测试场景(Interactions_Example).unity

++++1、新建场景

++++2、删除“主摄像机”对象

++++3、将“Player”预制体拖放到场景中

++++4、戴上头盔观察场景

++++5、观察“Skeleton Input”控制器

++++6、添加“Interactable”可交互组件

++++7、添加“Throwable”可抛出组件

++++8、添加“Skeleton Poser”骨架姿态组件

++++9、添加“Teleporting”传送预制体

++++10、添加“TeleportPoint”传送点预制体

++++11、添加“TeleportArea”传送区域预制体

 

 

++一、新建场景

++++立钻哥哥:新建场景;固然,那须要先导入“SteamVR插件”

++++SteamVR的Unity资源商店连接:https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647

++++SteamVR在Github上的Releasehttps://github.com/ValveSoftware/steamvr_unity_plugin/releases

++++新建工程后,导入SteamVR插件,那就能够开始新建一个测试场景了

 

 

 

++二、删除“主摄像机”对象

++++立钻哥哥:删除“主摄像机(Main Camera)”

++++若是须要作一款VR游戏,须要把摄像机调成VR视角

++++[方法1]:使用预制的VR摄像机

++++[方法2]:将普通的摄像机修改为VR摄像机

++++Tips:比较详细的描述可参考“SteamVR简介”http://www.javashuo.com/article/p-awcwwcaq-ea.html

 

 

 

++三、将“Player”预制体拖放到场景中

++++立钻哥哥:将“Assets/SteamVR/InteractionSystem/Core/Prefabs/”下的“Player.prefab”预制体拖到场景中;这个预制体设置了主要的玩家和手,它还挂钩到全部相关的“SteamVR Input”须要的动做

 

 

 

++四、戴上头盔观察场景

++++立钻哥哥:如今咱们就能够戴上头盔观察一下场景吧,里面有什么呢?估计是一个空白的场景,极可能有控制器呀!

 

 

 

++五、观察“Skeleton Input”控制器

++++立钻哥哥:若是咱们的控制器是支持“Skeleton Input”的,操做时会看到双手触摸并按下控制器上的按钮

 

 

 

++六、添加“Interactable”可交互组件

++++立钻哥哥:将“Interactable”组件添加到场景中的任何对象中,该对象上的全部其余组件将开始从玩家手中接收相关信息了

++++可参考:Assets/SteamVR/InteractionSystem/Samples/Scripts/InteractableExample.cs

//Purpose: Demonstrates how to create a simple interactable object.(立钻哥哥:目的:演示如何建立一个简单的可交互对象.

using UnityEngine;

using System.Collections;

 

namespace Valve.VR.InteractionSystem.Sample{

    [RequireComponent(typeof(Interactable))]

    public class InteractableExample : MonoBehaviour{

        private TextMesh generalText;

        private TextMesh hoveringText;

        private Vector3 oldPosition;

        private Quaternion oldRotation;

 

        private float attachTime;

 

        private Hand.AttachmentFlags attachmentFlags = Hand.defaultAttachmentFlags

            & (~Hand.AttachmentFlags.SnapOnAttach)

            & (~Hand.AttachmentFlags.DetachOthers)

            & (~Hand.AttachmentFlags.VelocityMovement);

        

        private Interactable interactable;

 

        void Awake(){

            var textMeshs = GetComponentsInChildren<TextMesh>()

            generalText = textMeshs[0];

            hoveringText = textMeshs[1];

 

            generalText.text = 立钻哥哥:No Hand Hovering!;

            hoveringText.text = 立钻哥哥:Hovering: False!;

 

            interactable = this.GetComponent<Interactable>();

        }

 

        //Called when a Hand starts hovering over this object.(立钻哥哥:当一只手开始悬停在该对象上时调用

        private void OnHandHoverBegin(){

            generalText.text = 立钻哥哥:Hovering hand:  + hand.name;

        }

 

        //Called when a Hand stops hovering over this object.(立钻哥哥:当一只手中止悬停在该对象上时调用.

        private void OnHandHoverEnd(Hand hand){

            generalText.text = 立钻哥哥:No Hand Hovering.;

        }

 

        //Called every Update() while a Hand is hovering over this object.(立钻哥哥:当一只手悬停在此对象上时调用每一个Update().

        private void HandHoverUpdate(Hand hand){

            GrabTypes startingGrabType = hand.GetGrabStarting();

            bool isGrabEnding = hand.IsGrabEnding(this.gameObject);

 

            if(interactable.attachedToHand == null && startingGrabType != GrabType.None){

                //Save our position/rotation so that we can restore it when we detach.(立钻哥哥:保存咱们的位置/旋转,以便咱们能够在分离时恢复它

                oldPosition = transform.position;

                oldRotation = transform.rotation;

 

                //Call this to continue receiving HandHoverUpdate messages, and prevent the hand from hovering over anything else.(立钻哥哥:调用此函数能够继续接收HandHoverUpdate消息,并防止手悬停在任何其余位置.

                hand.HoverLock(interactable);

 

                //Attach this object to the hand.(立钻哥哥:把这个物体系在手上.

                hand.AttachObject(gameObject, startingGrabType, attachmentFlags);

 

            }else if(isGrabEnding){

                //Detach this object from the hand.(立钻哥哥:将此对象从手中分离出来.

                hand.DetachObject(gameObject);

 

                //Call this to undo HoverLock.(立钻哥哥:调用此命令能够撤销HoverLock

                hand.HoverUnlock(interactable);

 

                //Restore position/rotation.(立钻哥哥:恢复/旋转位置

                transform.position = oldPosition;

                transform.rotation = oldRotation;

            }

        }    //立钻哥哥:private void HandHoverUpdate(Hand hand){}

 

        //Called when this GameObject becomes attached to the hand.(立钻哥哥:当GameObject(游戏物体)与手相连时调用.

        private void OnAttachedToHand(Hand hand){

            generalText.text = string.Format(立钻哥哥:Attached: {0}, hand.name);

            attachTime = Time.time;

        }

 

        //Called when this GameObject is detached from the hand.(立钻哥哥:当GameObject(游戏物体)与手分离时调用.

        private void OnDetachedFromHand(Hand hand){

            generalText.text = string.Format(立钻哥哥:Attached: {0} :: Time:{1:F2}, hand.name, (Time.time - attachTime));

        }

 

        private bool lastHovering = false;

        private void Update(){

            if(interactable.isHovering != lastHovering){

                hoveringText.text = string.Format(Hovering: {0}, interactable.isHovering);

                lastHovering = interactable.isHovering;

            }

        }    //立钻哥哥:private void Update(){}

 

        //Called when this attached GameObject becomes the primary attached object.(立钻哥哥:当这个附属游戏对象成为主要附属对象时调用.

        private void OnHandFocusAcquired(Hand hand){

        }

 

        //Called when another attached GameObject becomes the primary attached object.(立钻哥哥:当另外一个附加游戏对象成为主要附加对象时调用.

        private void OnHandFocusLost(Hand hand){

        }

 

    }    //立钻哥哥:public class InteractableExample:MonoBehaviour{}

 

}    //立钻哥哥:namespace Valve.VR.InteractionSystem.Sample{}

 

++++立钻哥哥:这里必须指出一点的是,SteamVR在这里没有采用delegate-event形式,而是采用了SendMessage(),这个是有争议的,可是不伤大雅!

//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Purpose: The hands used by the player in the vr interaction system.(立钻哥哥:用途:玩家在vr交互系统中使用的手

using UnityEngine;

using System.Threading;

 

namespace Valve.VR.InteractionSystem{

    //Links with an appropriate SteamVR controller and facilitates interactions with objects in the virtual world.(立钻哥哥:连接到适当的SteamVR控制器,并方便与虚拟世界中的对象进行交互.

    public class Hand : MonoBehaviour{

++++L170: _hoveringInteractable.SendMessage(OnHandHoverEnd, this, SendMessageOptions.DontRequireReceiver);

++++L185: _hoveringInteractable.SendMessage(OnHandHoverBegin, this, SendMessageOptions.DontRequireReceiver);

++++L384: currentAttachedObject.SendMessage(OnHandFocusLost, this, SendMessageOptions.DontRequireReceiver);

++++L560: objectToAttach.SendMessage(OnAttachedToHand, this, SendMessageOptions.DontRequireReceiver);

++++L656: attachedObjects[index].attachedObject.SendMessage(OnDetachedFromHand, this, SendMessageOptions.DontRequireReceiver);

++++L672: newTopObject.SendMessage(OnHandFocusAcquired, this, SendMessageOptions.DontRequireReceiver);

++++L1083: attachedObject.SendMessage(HandAttachedUpdate, this, SendMessageOptions.DontRequireReceiver);

++++L1088: hoveringInteractable.SendMessage(HandHoverUpdate, this, SendMessageOptions.DontRequireReceiver);

++++L1202: attachedInfo.interactable.gameObject.SendMessage(OnThrowableAttachEaseInCompleted, this, SendMessageOptions.DontRequireReceiver);

    }    //立钻哥哥:public class Hand:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

 

//立钻哥哥:SendMessageOptions

using System;

namespace UnityEngine{

    public enum SendMessageOptions{

        RequireReceiver,

        DontRequireReceiver

    }    //立钻哥哥:public enum SendMessageOptions{}

}    //立钻哥哥:namespace UnityEngine{}

 

//立钻哥哥:GameObject.SendMessage()发送消息

void SendMessage(string methodName, object value=null, SendMessageOptions options=SendMessageOptions.RequireReceiver);

++++[methodName]: 调用的方法名;

++++[value]:可选参数,被调用的方法传递的值;

++++[options]:若是目标对象方法不存在,是否引起错误;

++++[描述]:在此游戏对象全部MonoBehaviour上调用名称为methodName的方法;接收消息的方法能够经过不要参数的方法来选择忽略参数;当选项被设置为[SendMessageOptions.RequireReceiver]时,若是消息没有被任何一个组件处理,则会打印一个错误;

++++[注意]:消息不会发送到非激活的对象上(如,那些在编辑器或者经过SetActive已经关闭的对象);

 

using UnityEngine;

using System.Collections;

 

public class YanlzExampleClass : MonoBehaviour{

    void YanlzApplyDamage(float damage){

        Debug.Log(立钻哥哥:受到的攻击 + damage);

    }

 

    void MyExampleFunc(){

        gameObject.SendMessage(YanlzApplyDamage, 5.0f);

    }    

}    //立钻哥哥:public class YanlzExampleClass:MonoBehaviour{}

 

++++立钻哥哥:比较全面地熟悉了“InteractableExample.cs”和相关的“Hand.cs”,那咱们顺便熟悉一下“Interactable.cs”吧:

//立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Interactable.cs

//Purpose: This object will get hover events and can be attached to the hands.(立钻哥哥:用途:此对象将得到悬停事件,并能够附加到

using UnityEngine;

using UnityEngine.Event;

using System.Collections;

using System.Collections.Generic;

 

namespace Valve.VR.InteractionSystem{

    public class Interactable : MonoBehaviour{

        public SteamVR_ActionSet activateActionSetOnAttach;

        public bool hideHandOnAttach = true;

        public bool hideSkeletonOnAttach = false;

        public bool hideControllerOnAttach = false;

        public int handAnimationOnPickup = 0;

        public SkeletalMotionRangeChange setRangeOfMotionOnPickup = SkeletalMotionRangeChange.None;

 

        public delegate void OnAttachedToHandDelegate(Hand hand);

        public delegate void OnDetachedFromHandDelegate(Hand hand);

 

        public event OnAttachedToHandDelegate onAttachedToHand;

        public event OnDetachedFromHandDelegate onDetachedFromHand;

 

        public bool useHandObjectAttachmentPoint = true;

        public bool attachEaseIn = false;

    

        [HideInInspector]

        public AnimationCurve snapAttachEaseInCurve = AnimationCurve.EaseInOut(0.0f, 0.0f, 1.0f, 1.0f);

 

        public float snapAttachEaseInTime = 0.15f;

        public bool snapAttachEaseInCompleted = false;

 

        [HideInInspector]

        public SteamVR_Skeleton_Poser skeletonPoser;

 

        public bool handFollowTransform = true;

 

        public bool highlightOnHover = true;

        protected MeshRenderer[] highlightRenderers;

        protected MeshRenderer[] existingRenderers;

        protected GameObject highlightHolder;

        protected SkinnedMeshRenderer[] highlightSkinnedRenderers;

        protected SkinnedMeshRenderer[] existingSkinnedRenderers;

        protected static Material highlightMat;

        public GameObject[] hideHighlight;

 

        [System.NonSerialized]

        public Hand attachedToHand;

 

        [System.NonSerialized]

        public Hand hoveringHand;

 

        public bool isDestroying{  get;  protected set;  }

        public bool isHovering{  get;  protected set;  }

        public bool wasHovering{  get;  protected set;  }

 

        private void Awake(){

            skeletonPoser = GetComponent<SteamVR_Skeleton_Poser>();

        }

 

        protected virtual void Start(){

            highlightMat = (Material)Resources.Load(SteamVR_HoverHighlight, typeof(Material));

        }

 

        protected virtual bool ShouldIgnoreHighlight(Component component){}

        protected virtual bool ShouldIgnore(GameObject check){}

 

        protected virtual void CreateHighlightRenderers(){

            existingSkinnedRenderers = this.GetComponentsInChildren<SkinnedMeshRenderer>(true);

            highlightHolder = new GameObject(Highlighter);

            highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length];

        }

 

        protected virtual void UpdateHighlightRenderers(){}

        protected virtual void OnHandHoverBegin(Hand hand){}

        private void OnHandHoverEnd(Hand hand){}

        protected virtual void Update(){}

 

        protected float blendToPoseTime = 0.1f;

        protected float releasePoseBlendTime = 0.2f;

 

        protected virtual void OnAttachedToHand(Hand hand){}

        protected virtual void OnDetachedFromHand(Hand hand){}

        protected virtual void OnDestroy(){}

        protected virtual void OnDisable(){}

 

    }    //立钻哥哥:public class Interactable:MonoBehaviour{}

 

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

 

 

++++立钻哥哥:其实上面的那些都是了解,没有真正实战,实战才是关键,那咱们就开始操练起来:

//立钻哥哥:参考“InteractableExample.cs”编写一个脚本“YanlzVRDemoInteractable190416.cs”

//目的:能把那个风骚的Cube拿起来!

using UnityEngine;

using System.Collections;

 

namespace YanlzXR.VR.InteractionSystem.Sample{

    [RequireComponent(typeof(Interactable))]

    public class YanlzVRDemoInteractable190416 : MonoBehaviour{

        private Vector3 oldPosition;

        private Quaternion oldRotation;

 

        private Hand.AttachmentFlags attachmentFlags = Hand.defaultAttachmentFlags

            & (~Hand.AttachmentFlags.SnapOnAttach)

            & (~Hand.AttachmentFlags.DetachOthers)

            & (~Hand.AttachmentFlags.VelocityMovement);

 

        private Interactable interactable;

 

        void Awake(){

            Debug.Log(立钻哥哥:----YanlzVRDemoInteractable190416----[Awake()]----IN----);

            interactable = this.GetComponent<Interactable>();

        }

 

        //Called every Update() while a Hand is hovering over this object.(立钻哥哥:当一只手悬停在此对象上时每一个Update()都调用.

        private void HandHoverUpdate(Hand hand){

            GrabTypes startingGrabType = hand.GetGrabStarting();

            bool isGrabEnding = hand.IsGrabEnding(this.gameObject);

 

            if(interactable.attachedToHand == null && startingGrabType != GrabTypes.None){

                //Save our position/rotation so that we can restore it when we detach.(立钻哥哥:保存咱们的位置/旋转,以便咱们能够在分离时恢复它.

                oldPosition = transform.position;

                oldRotation = transform.rotation;

 

                //Call this to continue receiving HandHoverUpdate message, and prevent the hand from hovering over anything else.(立钻哥哥:调用此函数能够继续接收HandHoverUpdate消息,并防止手悬停在任何其余位置.

                hand.HoverLock(interactable);

 

                //Attach this object to the hand.(立钻哥哥:把这个物体系在手上.

                hand.AttachObject(gameObject, startingGrabType, attachmentFlags);

 

            }else if(isGrabEnding){

                //Detach this object from the hand.(立钻哥哥:将此对象从手中分离出来.

                hand.DetachObject(gameObject);

 

                //Call this to undo HoverLock.(立钻哥哥:调用此命令能够撤销HoverLock

                hand.HoverUnlock(interactable);

 

                //Restore position/rotation.(立钻哥哥:恢复旋转/位置

                transform.position = oldPosition;

                transform.rotation = oldRotation;

            }

 

        }    //立钻哥哥:private void HandHoverUpdate(Hand hand){}

 

    }    //立钻哥哥:public class YanlzVRDemoInteractable190416:MonoBehaviour{}

 

}    //立钻哥哥:namespace YanlzXR.VR.InteractionSystem.Sample{}

 

 

++知识点01:Hand.AttachmentFlags

++++立钻哥哥:The flags used to determine how an object is attached to the hand.用于肯定对象如何附加到手的标志

++++public const AttachmentFlags defaultAttachmentFlags = AttachmentFlags.ParentToHand | AttachmentFlags.DetachOthers | AttachmentFlags.DetachFromOtherHand | AttachmentFlags.TurnOnKinematic | AttachmentFlags.SnapOnAttach;

++++[Flags] public enum AttachmentFlags{

    SnapOnAttach = 1 << 0,

    DetachOthers = 1 << 1,

    DetachFromOtherHand = 1 << 2;

    ParentToHand = 1 << 3,

    VelocityMovement = 1 << 4,

    TurnOnKinematic = 1 << 5,

    TurnOffGravity = 1 << 6,

    AllowSidegrade = 1 << 7,

};

++++[SnapOnAttach]:The object should snap to the position of the specified attachment point on the hand.(立钻哥哥:[SnapOnAttach]: 将物体附着在手的指定位置。

++++[DetachOthers]:Other objects attached to this hand will be detached.立钻哥哥:[DetachOthers]:其余对象附加到这只手会分离.

++++[DetachFromOtherHand]:This object will be detached from the other hand.立钻哥哥:[DetachFromOtherHand]:这个对象将从另外一只手脱离

++++[ParentToHand]:The object will be parented to the hand.立钻哥哥:[ParentToHand]:对象将做为的子物体。

++++[VelocityMovement]:The object will attempt to move to match the position and rotation of the hand.立钻哥哥:[VelocityMovement]:对象将尝试移动到位置和旋转都匹配的手上。

++++[TurnOnKinematic]:The object will not respond to external physics.立钻哥哥:[TurnOnKinematic]: 对象不响应外部物理属性。

++++[TurnOffGravity]:The object will not respond to external physics.立钻哥哥:[TurnOffGravity]:外部物理对象不会回应

++++[AllowDidegrade]:The object is able to switch from a pinch grab to a grip grab. Decreases likelyhood of a good throw but also decreases likelyhood of accidental drop.立钻哥哥:AllowDidegrade]:对象能够切换从一个捏抓握抓。减小一个好的投掷的可能性,但也减小意外掉落的可能性

 

++知识点02:HandHoverUpdate

++++立钻哥哥:private void HandHoverUpdate(Hand hand){}

++++咱们来加个断点来调试跟踪一下,这个接口是从哪里调用过来的:

 

 

++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//立钻哥哥:L1076(void Valve.VR.InteractionSystem.Hand:Update())

protected virtual void Update(){

    UpdateNoSteamVRFallback();

 

    GameObject attachedObject = currentAttachedObject;

    if(attachedObject != null){

        attachedObject.SendMessage(HandAttachedUpdate, this, SendMessageOptions.DontRequireReceiver);

    }

 

    if(hoveringInteractable){

        //立钻哥哥:void YanlzXR.VR.InteractionSystem.Sample.YanlzVRDemoInteractable190416:HandHoverUpdate(Hand) ==>private void HandHoverUpdate(Hand hand){}

        hoveringInteractable.SendMessage(HandHoverUpdate, this, SendMessageOptions.DontRequireReceiver);

    }

}    //立钻哥哥:protected virtual void Update(){}

 

++知识点03:hand.GetGrabStarting()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public GrabType GetGrabStarting(GrabTypes explicitType=GrabType.None){

    if(explicitType != GrabTypes.None){

        if(noSteamVRFallbackCamera){

            if(Input.GetMouseButtonDown(0)){

                return explicitType;

            }

        }

 

        if(explicitType == GrabTypes.Pinch && grabPinchAction.GetStateDown(handType)){

            return GrabTypes.Pinch;

        }

 

        if(explicitType == GrabTypes.Grip && grabGripAction.GetStateDown(handType)){

            return GrabTypes.Grip;

        }

 

    }else{

        if(noSteamVRFallbackCamera){

            if(Input.GetMouseButtonDown(0)){

                return GrabType.Grip;

            }

        }

 

        if(grabPinchAction.GetStateDown(handType)){

            return GrabTypes.Pinch;

        }

 

        if(grabGripAction.GetStateDown(handType)){

            return GrabTypes.Grip;

        }

 

        return GrabTypes.None;

    }

 

    return GrabTypes.None;

}

 

++知识点04:hand.IsGrabEnding()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public bool IsGrabEnding(GameObject attachedObject){

    for(int attachedObjectIndex=0; attachedObjectIndex < attachedObjects.Count; attachedObjectIndex++){

        if(attachedObjects[attachedObjectIndex].attachedObject == attachedObject){

            return IsGrabbingWithType(attachedObjects[attachedObjectIndex].grabbedWithType) == false;

        }

    }

 

    return false;

}

 

++知识点05:hand.HoverLock()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Continue to hover over this object indefinitely, whether or not the Hand moves out of its interaction trigger volume.(立钻哥哥:不管手是否移出交互触发范围,都将无限期地悬停在该对象上

public void HoverLock(Interactable interactable){

    if(spewDebugText){

        HandDebugLog(立钻哥哥:HoverLock  + interactable);

    }

 

    hoverLocked = true;

 

    //[interactable]: The Interactable to hover over indefinitely.(立钻哥哥:[可交互的]:能够无限悬停的可交互的

    hoveringInteractable = interactable;

}

 

++知识点05:hand.AttachObject()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Attach a GameObject to this GameObject.(立钻哥哥:将GameObject(游戏物体)附加到这个GameObject(游戏物体)上。

//[objectToAttach]: The GameObject to attach.(立钻哥哥:[objectToAttach]:要附加的GameObject

//[flags]: The flags to use for attaching the object.(立钻哥哥:[flags]:用于附加对象的标志.

//[attachmentPoint]: Name of the GameObject in the hierarchy of this Hand which should act as the attachment point for this GameObject.(立钻哥哥:[attachmentPoint]:这只手的层次结构中GameObject的名称,它应该做为这个GameObject的链接点.

public void AttachObject(GameObject objectToAttach, GrabTypes grabbedWithType, AttachmentFlags flags=defaultAttachmentFlags, Transform attachmentOffset=null){

    AttachedObject attachedObject = new AttachedObject();

    attachedObject.attachmentFlags = flags;

    attachedObject.attachedOffsetTransform = attachmentOffset;

    attachedObject.attachTime = Time.time;

 

    if(flags == 0){

        flags = defaultAttachmentFlags;

    }

 

    //Make sure top object an stack is non-null.(立钻哥哥:确保栈顶对象非空.

    CleanUpAttachedObjectStack();

 

    ... ...

 

    attachedObjects.Add(attachedObject);

 

    UpdateHovering();

 

   objectToAttach.SendMessage(OnAttachedToHand, this, SendMessageOptions.DontRequireReceiver);

 

}    //立钻哥哥:public void AttachObject{}

 

++知识点05:hand.DetachObject()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Detache this GameObject from the attached object stack of this Hand.(立钻哥哥:从这只手的附加对象堆栈中分离这个GameObject.

//[objectToDetach]: The GameObject to detach from this Hand.(立钻哥哥:[objectToDetach]:要从这只手分离的GameObject.

public void DetachObject(GameObject objectToDetach, bool restoreOriginalParent=true){

    int index = attachedObjects.FindIndex(l => l.attachedObject == objectToDetach);

    if(index != -1){  ...  }

    ... ...

}

 

++知识点05:hand.HoverUnlock()

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Stop hovering over this object indefinitely.(立钻哥哥:中止无限期地悬停在这个物体上.

//[interactable]: The hover-locked Interactable to stop hovering over indefinitely.(立钻哥哥:[可交互]:锁定物体的可交互,以中止无限期地悬停

public void HoverUnlock(Interactable interactable){

    if(hoveringInteractable == interactable){

        hoverLocked = false;

    }

}

 

++立钻哥哥:Hand”类为“交互系统(Interaction System)”作了大部分繁重的工做;“Hand”检查它所悬停的对象(Interactables),并根据当前悬停状态向它们发送消息;一只手一次只能悬停在一个物体上;物体能够附着在手上,也能够从手上分离出来,只有一个对象能够是手的焦点对象,但同时能够将多个对象附加到手;一旦一个对象与手分离,那么与手相连的前一个对象(若是它仍然与手相连)就成为手的焦点对象;当没有任何东西附着在手上时,它老是会显示控制器;所附加的对象能够设置AttachmentFlags,该标记肯定手和对象在被附加后的行为;根据不一样的状况,能够将手锁定在悬停在其余物体或任何物体上

 

++“Hand”手发送给正在与之交互的对象的消息:

++++立钻哥哥、OnHandHoverBegin、HandHoverUpdate、OnHandHoverEnd、OnAttachedToHand、HandAttachedUpdate、OnDetachedFromHand、OnHandFocusLost、OnHandFocusAcquired;

++++[OnHandHoverBegin]:当手第一次开始悬停在对象上时发送

++++[HandHoverUpdate]:发送手悬停在对象上的每一帧

++++[OnHandHoverEnd]:当手离开悬停物体上时发送

++++[OnAttachedToHand]:当对象附加到hand上时发送

++++[HandAttachedUpdate]:当对象附在手上时,发送每一帧

++++[OnDetachedFromHand]:当对象脱离手时发送

++++[OnHandFocusLost]:当一个附加对象由于其余对象被附加到手上而失去焦点时发送

++++[OnHandFocusAcquired]:当一个附加对象得到焦点时发送,由于以前的焦点对象已经与手分离

+++++++++++++++++++++

//立钻哥哥:咱们这里的【六、添加“Interactable”可交互组件】中就应用到了“HandHoverUpdate(Hand hand)”

private void HandHoverUpdate(Hand hand){

    GrabTypes startingGrabType = hand.GetGrabStarting();

    bool isGrabEnding = hand.IsGrabEnding(this.gameObject);

 

    if(interactable.attachedToHand == null && startingGrabType != GrabTypes.None){

        oldPosition = transform.position;

        oldRotation = transform.rotation;

        hand.HoverLock(interactable);

        hand.AttachObject(gameObject, startingGrabType, attachmentFlags);

    }else if(isGrabEnding){

        hand.DetachObject(gameObject);

        hand.HoverUnlock(interactable);

        transform.position = oldPosition;

        transform.rotation = oldRotation;

    }

}    //立钻哥哥:private void HandHoverUpdate(Hand hand){}

 

++“Hand”手发送给它的子对象的消息

++++立钻哥哥:OnHandInitialized、OnParentHandHoverBegin、OnParentHandHoverEnd、OnParentHandInputFocusAcquired、OnParentHandInputFocusLost;

++++[OnHandInitialized]:经过将本身与“SteamVR”跟踪控制器的设备ID相关联,首次初始化手时发送

++++[OnParentHandHoverBegin]:当手开始悬停在某物上时发送

++++[OnParentHandHoverEnd]:当手离开悬停在某物上时发送

++++[OnParentHandInputFocusAcquired]:当游戏窗口得到输入焦点时发送

++++[OnParentHandInputFocusLost]:当游戏窗口失去输入焦点时发送

 

++“Hand”类中处理链接和分离的成员

++++立钻哥哥:AttachObject、DetachObject、currentAttachedObject;

++++[AttachObject]:使用传递的AttachmentFlags从手上附加对象

++++[DetachObject]:从手中分离对象,并可选地将其还原到其原始父对象

++++[currentAttachedObject]:这将返回手上的“in-focus”附加对象(若是有的话)

 

++“Hand”类中用来定制其行为的有用的属性和功能

++++立钻哥哥:otherHand、hoverSphereTransform、hoverSphereRadius、hoverLayerMask、hoverUpdateInterval、HoverLock、HoverUnlock、GetGrabStarting、GetGrabEnding;

++++[public Hand otherHand;]:这是Player上的另外一只手,这对于须要双手交互的对象(如长弓)很是有用

++++[public Transform hoverSphereTransform; public float hoverSphereRadius=0.05f;]:可用于自定义手的悬停范围

++++[public LayerMask hoverLayerMask=-1;]:这能够改变,使手只悬停在某些层的对象上

++++[public float hoverUpdateInterval=0.1f;]:能够根据游戏的需求定义悬停检查的频率

++++[public void HoverLock(Interactable interactable){}; public void HoverUnlock(Interactable interactable){};]:这是用来让手只悬停在一个特定的物体上;传递null将使手在悬停锁定时不悬停在其余物体上;此技术用于使手在传送弧处于活动状态时不悬停在物体上

++++[public GrabTypes GetGrabStarting(GrabTypes explicitType=GrabTypes.None){}; public GrabTypes GetGrabEnding(GrabTypes explicitType=GrabTypes.None){};]:这些用于肯定布尔抓取操做是否在那个时候被触发;抓握有两种类型:抓取和捏抓;这些一般与手柄按钮和触发器按钮相关联,但在“Knuckles控制器”上具备特殊功能

 

++Interactable(可交互的)

++++立钻哥哥:Interactable类更像是一个标识符,它向“手”标识该对象是可交互的

++++任何具备此“Interactable”组件的对象都将从“Hand”接收相关信息

++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Interactable.cs(立钻哥哥:此对象将得到悬停事件,并能够附加到手上)

 

 

 

++++立钻哥哥:好吧,拓展了这么多,貌似啥啥啥??!! =>好吧,那就看一下利用“Interactable”组件实现的效果吧:

 

 

 

++七、添加“Throwable”可抛出组件

++++立钻哥哥:“将Throwable组件添加到对象中,将容许玩家拾取并抛出该物体”,Throwable”是最基本的交互对象之一;当一只手悬停在这个物体上并按下其中一个抓取按钮(一般是扳机或手柄)时,玩家能够拿起这个物体;当按下按钮时,该对象被附在手上并保持在那里;当按钮被释放时,手中的任何速度都被赋予抛出的物体;这让咱们能够建立能够拾取和抛出的基本对象

 

++++立钻哥哥:只要把“Throwable”组件加到物体上,这个物体就能够被抛出了!那咱们来看一下效果吧:

 

++++立钻哥哥:如今咱们来剖析一下这个神奇的脚本“Throwable.cs”:

//Purpose: Basic throwable object.(立钻哥哥:用途:基本抛掷物.

using UnityEngine;

using UnityEngine.Events;

using System.Collections;

 

namespace Valve.VR.InteractionSystem{

     [RequireComponent(typeof(Interactable))]

    [RequireComponent(typeof(Rigidbody))]

    [RequireComponent(typeof(VelocityEstimator))]

    public class Throwable : MonoBehaviour{

        [EnumFlags]

        [Tooltip(The flags used to attach this object to the hand.(立钻哥哥:用于将此对象附加到手的标志.)]

        public Hand.AttachmentFlags attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.TurnOnKinematic;

    

        [Tooltip(The local point which acts as a positional and rotational offset to use while held.(立钻哥哥:局部点,在保持时起位置偏移和旋转偏移的做用.)]

        public Transform attachmentOffset;

 

        [Tooltip(How fast must this object be moving to attach due to a trigger hold instead of a trigger press?(-1 to disable.)(立钻哥哥:因为触发器保持而不是触发器按下,该对象移动到附加时的速度必须有多快?(-1禁用).)]

        public float catchingSpeedThreshold = -1;

 

        public ReleaseStyle releaseVelocityStyle = ReleaseStyle.GetFromHand;

 

        [Tooltip(This time offset used when releasing the object with the RawFromHand option.(立钻哥哥:使用RawFromHand选项释放对象时使用的时间偏移量.)]

        public float releaseVelocityTimeOffset = -0.011f;

    

        public float scaleReleaseVelocity = 1.1f;

 

        [Tooltip(When detaching the object, should it return to its original parent?(立钻哥哥:当分离对象时,它应该返回到原来的父对象吗?)]

        public bool restoreOriginalParent = flase;

 

        protected VelocityEstimator velocityEstimator;

        protected bool attached = false;

        protected float attachTime;

        protected Vector3 attachPosition;

        protected Quaternion attachRotation;

        protected Transform attachEaseInTransform;

 

        public UnityEvent onPickUp;

        public UnityEvent onDetachFromHand;

        public UnityEvent<Hand> onHeldUpdate;

 

        protected RigidbodyInterpolation handInterpolation = RigidbodyInterpolation.None;

        protected new Rigidbody rigidbody;

 

        [HideInInspector]

        public Interactable interactable;

 

        protected virtual void Awake(){

            velocityEstimator = GetComponent<VelocityEstimator>();

            interactable = GetComponent<Interactable>();

 

            rigidbody = GetComponent<Rigidbody>();

            rigidbody.maxAngularVelocity = 50.0f;

 

            if(attachmentOffset != null){

                //remove?

                //interactable.handFollowTransform = attachmentOffset;

            }

        }    //立钻哥哥:protected virtual void Awake(){}

 

        protected virtual void OnHandHoverBegin(Hand hand){

            bool showHint = false;

    

            //Catch the throwable by holding down the interaction button instead of pressing it. Only do this if the throwable is moving faster than the prescribed threshold speed, and if it isnt attached to another hand.(立钻哥哥:按下交互按钮,而不是按下按钮,就能够“捕捉”可扔物品。只有当投掷物的移动速度超过规定的阈值速度,而且没有附在另外一只手上时才这样作.

            if(!attached && catchingSpeedThreshold != -1){

                float catchingThreshold = catchingSpeedThreshold * SteamVR_Utils.GetLossyScale(Player.instance.trackingOriginTransform);

                GrabTypes bestGrabType = hand.GetBestGrabbingType();

 

                if(bestGrabType != GrabTypes.None){

                    if(rigidbody.velocity.magnitude >= catchingThreshold){

                        hand.AttachObject(gameObject, bestGrabType, attachmentFlags);

                        showHint = false;

                    }

                }

            }

 

            if(showHint){

                hand.ShowGrabHint();

            }

        }    //立钻哥哥:protected virtual void OnHandHoverBegin(Hand hand){}

 

        protected virtual void OnHandHoverEnd(Hand hand){

            hand.HideGrabHint();

        }

 

        protected virtual void HandHoverUpdate(Hand hand){

            GrabTypes startingGrabType = hand.GetGrabStarting();

            if(startingGrabType != GrabTypes.None){

                hand.AttachObject(gameObject, startingGrabType, attachmentFlags, attachmentOffset);

                hand.HideGrabHint();

            }

        }    //立钻哥哥:protected virtual void HandHoverUpdate(Hand hand){}

 

        protected virtual void OnAttachedToHand(Hand hand){

            //Debug.Log(<b>[SteamVR Interaction]</b> Pickup:  + hand.GetGrabStarting().ToString());

            hadInterpolation = this.rigidbody.interpolation;

            attached = true;

            onPickUp.Invoke();

            hand.HoverLock(null);

            rigidbody.interpolation = RigidbodyInterpolation.None;

            velocityEstimator.BeginEstimatingVelocity();

 

            attachTime = Time.time;

            attachPosition = transform.position;

            attachRotation = transform.rotation;

        }    //立钻哥哥:protected virtual void OnAttachedToHand(Hand hand){}

 

        protected virtual void OnDetachedFromHand(Hand hand){

            attached = false;

            onDetachFromHand.Invoke();

            hand.HoverUnlock(null);

            rigidbody.interpolation = hadInterpolation;

 

            Vector3 velocity;

            Vector3 angularVelocity;

            GetReleaseVelocities(hand, out velocity, out angularVelocity);

 

            rigidbody.velocity = velocity;

            rigidbody.angularVelocity = angularVelocity;

        }    //立钻哥哥:protected virtual void OnDetachedFromHand(Hand hand){}

   

        public virtual void GetReleaseVelocities(Hand hand, out Vector3 velocity, out Vector3 angularVelocity){

            if(hand.noSteamVRFallbackCamera && releaseVelocityStyle != ReleaseStyle.NoChange){

                //only type that works with fallback hand is short estimation.(立钻哥哥:只有使用备用手的类型是short estimate.

                releaseVelocityStyle = ReleaseStyle.ShortEstimation;    

           }

 

            switch(releaseVelocityStyle){

               case ReleaseStyle.ShortEstimation:

                    velocityEstimator.FinishEstimatingVelocity();

                    velocity = velocityEstimator.GetVelocityEstimate();

                    angularVelocity = velocityEstimator.GetAngularVelocityEstimate();

                    break;

                case ReleaseStyle.AdvancedEstimation:

                    hand.GetEstimatedPeakVelocities(out velocity, out angularVelocity);

                    break;

                case ReleaseStyle.GetFromHand:

                    velocity = hand.GetTrackedObjectVelocity(releaseVelocityTimeOffset);

                    angularVelocity = hand.GetTrackedObjectAngularVelocity(releaseVelocityTimeOffset);

                   break;

                default:

                case ReleaseStyle.NoChange:

                    velocity = rigidbody.velocity;

                    angularVelocity = rigidbody.angularVelocity;

                    break;    

            }    //立钻哥哥:switch(releaseVelocityStyle){}

 

            if(releaseVelocityStyle != ReleaseStyle.NoChange){

                velocity *= scaleReleaseVelocity;

            }

        }    //立钻哥哥:public virtual void GetReleaseVelocities(){}

 

        protected virtual void HandAttachedUpdate(Hand hand){

            if(hand.IsGrabEnding(this.gameObject)){

                hand.DetachObject(gameObject, restoreOriginalParent);

 

                //Uncomment to detach ourselves late in the frame. This is so that any vehicles the player is attached to have a chance to finish updating themselves. If we detach now, our position could be behind what it will be at the end of the frame, and the object may appear to teleport behind the hand when the player releases it.(立钻哥哥:取消注释,以便在稍后的帧中分离咱们本身。这样玩家所链接的任何物体都有机会完成自我更新。若是咱们如今分离,咱们的位置可能在帧后调用,当玩家释放这个物体时,它可能会出如今手的后面.

                //StartCoroutine(LateDetach(hand));    //立钻哥哥:稍后分离

            }

 

            if(onHeldUpdate != null){

                onHeldUpdate.Invoke(hand);

            }

        }    //立钻哥哥:protected virtual void HandAttachedUpdate(Hand hand){}

 

        protected virtual IEnumerator LateDetach(Hand hand){

            yield return new WaitForEndOfFrame();

 

            hand.DetachObject(gameObject, restoreOriginalParent);

        }    //立钻哥哥:protected virtual IEnumerator LateDetach(Hand hand){}

 

        protected virtual void OnHandFocusAcquired(Hand hand){

            gameObject.SetActive(true);

            velocityEstimator.BeginEstimatingVelocity();

        }    //立钻哥哥:protected virtual void OnHandFocusAcquired(Hand hand){}

 

        protected virtual void OnHandFocusLost(Hand hand){

           gameObject.SetActive(false);

            velocityEstimator.FinishEstimatingVelocity();

        }    //立钻哥哥:protected virtual void OnHandFocusLost(Hand hand){}

    }    //立钻哥哥:public class Throwable:MonoBehaviour{}

 

    public enum ReleaseStyle{

        NoChange,

        GetFromHand,

        ShortEstimation,

        AdvancedEstimation,

    }    //立钻哥哥:public enum ReleaseStyle{}

 

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

 

++知识点01:ReleaseStyle

++++立钻哥哥:public ReleaseStyle releaseVelocityStyle = ReleaseStyle.GetFromHand;

public enum ReleaseStyle{

    NoChange,

    GetFromHand,

     ShortEstimation,

    AdvancedEstimation,

}

 

++知识点02:VelocityEstimator

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

//Purpose: Estimates the velocity of an object based on change in position.(立钻哥哥:目的:根据物体位置的变化来估计物体的速度.

using UnityEngine;

using System.Collections;

namespace Valve.VR.InteractionSystem{

    public class VelocityEstimator : MonoBehaviour{

        public int velocityAverageFrames = 5;

        public int angularVelocityAverageFrames = 11;

        public bool estimateOnAwake = false;

        private Coroutine routine;

        private int sampleCount;

        private Vector3[] velocitySamples;

        private Vector3[] angularVelocitySamples;

 

        public void BeginEstimatingVelocity(){}

        public void FinishEstimatingVelocity(){}

        public Vector3 GetVelocityEstimate(){}

        public Vector3 GetAngularVelocityEstimate(){}

        public Vector3 GetAccelerationEstimate(){}

 

        void Awake(){}

        private IEnumerator EstimateVelocityCoroutine(){}

    }    //立钻哥哥:public class VelocityEstimator:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++[RequireComponent(typeof(VelocityEstimator))]

++++protected VelocityEstimator velocityEstimator;

++++velocityEstimator = GetComponent<VelocityEstimator>();

++++velocityEstimator.BeginEstimatingVelocity();

++++velocityEstimator.FinishEstimatingVelocity();

++++velocity = velocityEstimator.GetVelocityEstimate();

++++angularVelocity = velocityEstimator.GetAngularVelocityEstimate();

++++velocityEstimator.BeginEstimatingVelocity();

++++velocityEstimator.FinishEstimatingVelocity();

 

++知识点02:Hand

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Purpose: The hands used byt the player in the vr interaction system.(立钻哥哥:用途:VR交互系统中玩家使用的手.

using UnityEngine;

using System;

using System.Collections;

using System.Collections.Generic;

using System.Collections.ObjectModel;

using UnityEngine.Events;

using System.Threading;

 

namespace Valve.VR.InteractionSystem{

    //Links with an appropriate SteamVR controller and facilitates interactions with objects in the virtual world.(立钻哥哥:连接到适当的SteamVR控制器,并方便与虚拟世界中的对象进行交互.

    public class Hand : MonoBehaviour{

        //The flags used to determine how an object is attached to the hand.(立钻哥哥:用于肯定对象如何附加到手的标志.

        [Flags]

        public enum AttachmentFlags{}

 

        public const AttachmentFlags defaultAttachmentFlags = AttachmentFlags.ParentToHand | AttachmentFlags.DetachOthers | AttachmentFlags.DetachFromOtherHand | AttachmentFlags.TurnOnKinematic | AttachmentFlags.SnapOnAttach;

        public Hand otherHand;

        public SteamVR_Input_Sources handType;

        public SteamVR_Behaviour_Pose trackedObject;

        public SteamVR_Action_Boolean grabPinchAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(GrabPinch);

        public SteamVR_Action_Boolean grabGripAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(GrabGrip);

        public SteamVR_Action_Vibration hapticAction = SteamVR_Input.GetAction<SteamVR_Action_Vibration>(Haptic);

        public SteamVR_Action_Boolean uiInteractAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(InteractUI);

 

        public bool useHoverSphere = true;

        public Transform hoverSphereTransform;

        public float hoverSphereRadius = 0.05f;

        public LayerMask hoverLayerMask = -1;

        public float hoverUpdateInterval = 0.1f;

 

        public bool useControllerHoverComponent = true;

        public string controllerHoverComponent = tip;

        public float controllerHoverRadius = 0.075f;

 

        public bool useFingerJointHover = true;

        public SteamVR_Skeleton_JointIndexEnum fingerJointHover = SteamVR_Skeleton_JointIndexEnum.indexTip;

        public float fingerJointHoverRadius = 0.025f;

 

        [Tooltip(A transform on the hand to center attached objects on.(立钻哥哥:将手边的转换转换为将附加对象居中)]

        public Transform objectAttachmentPoint;

 

        public Camera noSteamVRFallbackCamera;

        public float noSteamVRFallbackMaxDistanceNoItem = 10.0f;

        public float noSteamVRFallbackMaxDistanceWithItem = 0.5f;

        private float noSteamVRFallbackInteractorDistance = -1.0f;

 

        public GameObject rendeModelPrefab;

        protected List<RenderModel> renderModels = new List<RenderModel>();

        protected RenderModel mainRenderModel;

        protected RenderModel hoverhighlightRenderModel;

 

        public bool showDebugText = false;

        public bool spewDebugText = false;

        public bool showDebugInteractable = false;

 

        public struct AttachedObject{

            public GameObject attachedObject;

            public Interactable interactable;

            public Rigidbody attachedRigidbody;

            public CollisionDetectionMode collisionDetectionMode;

            public bool attachedRigidbodyWasKinematic;

            public bool attachedRigidbodyUsedGravity;

            public GameObject originalParent;

            public bool isParentedToHand;

            public GrabTypes grabbedWithType;

            public AttachmentFlags attachmentFlags;

            public Vector3 initialRotationalOffset;

            public Quaternion initialRotationalOffset;

            public Transform attachedOffsetTransform;

            public Transform handAttachmentPointTransform;

            public Vector3 easeSourcePosition;

            public Quaternion easeSourceRotation;

            public float attachTime;

 

            public bool HasAttachFlag(AttachmentFlags flag){

                return (attachmentFlags & flag) == flag;

            }

        }    //立钻哥哥:public struct AttachedObject{}

 

        private List<AttachedObject> attachedObjects = new List<AttachedObject>();

        public ReadOnlyCollection<AttachedObject> AttachedObjects{}

        public bool hoverLocked{}

        private Interactable _hoveringInteractable;

        private TextMesh debugText;

        private int prevOverlappingColliders = 0;

        private const int ColliderArraySize = 16;

        private Collider[] overlappingColliders;

        private Player playerInstance;

        private GameObject applicationLostFocusObject;

        private SteamVR_Events.Action inputFocusAction;

        public bool isActive{}

        public bool isPoseValid{}

 

        //The Interactable object this Hand is currently hovering over.(立钻哥哥:这只手当前悬停的可交互对象.

        public Interactable hoveringInteractable{}

 

        //Active GameObject attached to this Hand.(立钻哥哥:活动的GameObject附在这只手上.

        public GameObject currentAttachedObject{}

 

        public AttachedObject? currentAttachedObjectInfo{}

        public SteamVR_Behaviour_Skeleton skeleton{}

        public void ShowController(bool permanent=false){}

        public void HideController(bool permanent=false){}

        public void ShowSkeleton(bool permanent=false){}

        public void HideSkeleton(bool permanent=false){}

        public bool HasSkeleton(){}

        public void Show(){}

        public void Hide(){}

        public void SetVisibility(bool visible){}

        public void SetSkeletonRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds=0.1f){}

        public void SetTemporarySkeletonRangeOfMotion(SkeletonMotionRangeChange temporaryRangeOfMotionChange, float blendOverSeconds=0.1f){}

        public void ResetTemporarySkeletonRangeOfMotion(float blendOverSeconds=0.1f){}

        public void SetAnimationState(int stateValue){}

        public void StopAnimation(){}

 

        //Attach a GameObject to this GameObject.(立钻哥哥:将GameObject(游戏物体)附加到这个GameObject(游戏物体)上.

        //[objectToAttach]: The GameObject to attach.(立钻哥哥:[objectToAttach]:要附加的GameObject.

        //[flags]: The flags to use for attaching the object.(立钻哥哥:[flags]:用于附加对象的标志.

        //[attachmentPoint]: Name of the GameObject in the hierarchy of this Hand which should act as the attachment point for this GameObject.(立钻哥哥:[attachmentPoint]:这只手的层次结构中GameObject的名称,它应该做为这个GameObject的链接点.

        public void AttachObject(GameObject objectToAttach, GrabType grabbedWithType, AttachmentFlags flags=defaultAttachmentFlags, Transform attachmentOffset=null){

            L348

            AttachedObject attachedObject = new AttachedObject();

            attachedObject.attachmentFlags = flags;

            attachedObject.attachedOffsetTransform = attachmentOffset;

            attachedObject.attachTime = Time.time;

            ....

            attachedObject.Add(attachedObject);

            UpdateHovering();

            objectToAttach.SendMessage(OnAttachedToHand, this, SendMessageOptions.DontRequireReceiver);

            L560(-L348=>212+1)

        }

 

        public bool ObjectIsAttached(GameObject go){}

        public void ForceHoverUnlock(){}

 

        //Detach this GameObject from the attached object stack of this Hand.(立钻哥哥:从这只手的附加对象堆栈中分离这个GameObject.

        //[objectToDetach]: The GameObject to detach from this Hand.(立钻哥哥:[objectToDetach]:要从这只手分离的GameObject.

        public void DetachObject(GameObject objectToDetach, bool restoreOriginalParent=true){

            L586

            int index = attachedObject.FindIndex(l=>l.attachedObject == objectToDetach);

            ... ...

            CleanUpAttachedObjectStack();

            L681(-L586=>95+1)

        }

 

        //Get the world velocity of the VR Hand.(立钻哥哥:获得VR手的世界速度

        public Vector3 GetTrackedObjectVelocity(float timeOffset=0){}

 

        //Get the world space angular velocity of the VR Hand.(立钻哥哥:获得VR手的世界空间角速度.

         public Vector3 GetTrackedObjectAngularVelocity(float timeOffset=0){}

 

        public void GetEstimatedPeakVelocities(out Vector3 velocity, out Vector3 angularVelocity){}

        private void CleanUpAttachedObjectStack(){}

        protected virtual void Awake(){}

        protected virtual void OnDestroy(){}

        protected virtual void OnTransformUpdated(SteamVR_Behaviour_Pose updatePose, SteamVR_Input_Sources updateSource){}

        protected virtual IEnumerator Start(){}

        protected virtual void UpdateHovering(){}

        protected virtual bool CheckHoveringForTransform(Vector3 hoverPosition, float hoverRadius, ref float closestDistance, ref Interactable closestInteractable, Color debugColor){}

        protected virtual void UpdateNoSteamVRFallback(){}

        private void UpdateDebugText(){}

        protected virtual void OnEnable(){}

        protected virtual void OnDisable(){}

        protected virtual void Update(){}

        public bool IsStilllHovering(Interactable interactable){}

        protected virtual void HandFollowUpdate(){}

        protected virtual void FixedUpdate(){}

 

        protected const float MaxVelocityChange = 10f;

        protected const float VelocityMagic = 6000f;

        protected const float AngularVelocityMagic = 50f;

        protected const float MaxAngularVelocityChange = 20f;

 

        protected void UpdateAttachedVelocity(AttachedObject attachedObjectInfo){}

        protected Vector3 TargetItemPosition(AttachedObject attachedObject){}

        protected Quaternion TargetItemRotation(AttachedObject attachedObject);

        protected bool GetUpdatedAttachedVelocites(AttachedObject attachedObjectInfo, out Vector3 velocityTarget, out Vector3 angularTarget){}

        protected virtual void OnInputFocus(bool hasFocus){}

        protected virtual void OnDrawGizmos(){}

        prvate void HandDebugLog(string msg){}

 

        //Continue to hover over this object indefinitely, whether or not the Hand moves out of its interaction trigger volume.(立钻哥哥:不管手是否移出交互触发范围,都将无限期地悬停在该对象上

        //[interactable]: The Interactable to hover over indefinitely.(立钻哥哥:[可交互的]:能够无限悬停的可交互的.

        public void HoverLock(Interactable interactable){}

 

        //Stop hovering over this object indefinitely.(立钻哥哥:中止无限期地悬停在这个物体上.

        //[interactable]: The hover-locked Interactable to stop hovering over indefinitely.(立钻哥哥:[可交互]:锁定悬停的可交互,以中止无限期地悬停.

        public void HoverUnlock(Interactable interactable){}

 

        public void TriggerHapticPulse(ushort microSecondsDuration){}

        public void TriggerHapticPulse(float duration, float frequency, float amplitude){}

        public void ShowGrabHint(){}

        public void HideGrabHint(){}

        public void ShowGrabHint(string text){}

        public GrabTypes GetGrabStarting(GrabTypes explicitType=GrabTypes.None){}

        public GrabTypes GetGrabEnding(GrabTypes explicitType=GrabTypes.None){}

        public bool IsGrabEnding(GameObject attachedObject){}

        public bool IsGrabbingWithType(GrabTypes type){}

        public bool IsGrabbingWithOppositeType(GrabTypes type){}

        public GrabTypes GetBestGrabbingType(){}

        public GrabTypes GetBestGrabbingType(GrabTypes preferred, bool forcePreference=false){}

        private void InitController(){}

        public void SetRenderModel(GameObject prefab){}

        public void SetHoverRenderModel(RenderModel hoverRenderModel){}

        public int GetDeviceIndex(){}

 

    }    //立钻哥哥:public class Hand:MonoBehaviour{}

 

    [System.Serializable]

    public class HandEvent : UnityEvent<Hand>();

 

        #if UNITY_EDITOR

            [UnityEditor.CustomEditor(typeof(Hand))]

            public class HandEditor : UnityEditor.Editor{

                //Custom Inspector GUI allows us to click from within the UI.(立钻哥哥:自定义检查器GUI容许咱们从UI中单击.

                pulic override void OnInspectorGUI(){

                    DrawDefaultInspector();

                }

           }    //立钻哥哥:public class HandEditor:UnityEditor.Editor{}

        #endif

 

    }    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++public Hand.AttachmentFlags attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.TurnOnKinematic;

++++public UnityEvent<Hand> onHeldUpdate;

++++protected virtual void OnHandHoverBegin(Hand hand){}

++++GrabTypes bestGrabType = hand.GetBestGrabbingType();

++++hand.AttachObject(gameObject, bestGrabType, attachmentFlags);

++++hand.ShowGrabHint();

++++protected virtual void OnHandHoverEnd(Hand hand){}

++++hand.HideGrabHint();

++++protected virtual void HandHoverUpdate(Hand hand){}

++++GrabTypes startingGrabType = hand.GetGrabStarting();

++++hand.AttachObject(gameObject, startingGrabType, attachmentFlags, attachmentOffset);

++++protected virtual void OnAttachedToHand(Hand hand){}

++++hand.HoverLock(null);

++++protected virtual void OnDetachedFromHand(Hand hand){}

++++hand.HoverUnlock(null);

++++GetReleaseVelocities(hand, out velocity, out angularVelocity);

++++public virtual void GetReleaseVelocities(Hand hand, out Vector3 velocity, out Vector3 angularVelocity){}

++++if(hand.noSteamVRFallbackCamera && releaseVelocityStyle!=ReleaseStyle.NoChange){}

++++hand.GetEstimatedPeakVelocities(out velocity, out angularVelocity);

++++velocity = hand.GetTrackedObjectVelocity(releaseVelocityTimeOffset);

++++angularVelocity = hand.GetTrackedObjectAngularVelocity(releaseVelocityTimeOffset);

++++protected virtual void HandAttachedUpdate(Hand hand){}

++++if(hand.IsGrabEnding(this.gameObject)){}

++++hand.DetachObject(gameObject, restoreOriginalParent);

++++onHeldUpdate.Invoke(hand);

++++protected virtual IEnumerator LateDetach(Hand hand){}

++++hand.DetachObject(gameObject, restoreOriginalParent);

++++protected virtual void OnHandFocusAcquired(Hand hand){}

++++protected virtual void OnHandFocusLost(Hand hand){}

 

++知识点03:UnityEvent

++++立钻哥哥:C:\Users\unity\AppData\Local\Temp\MetadataAsSource\4d44249b313b4410af4d2d6d08747e70\af4587a0fa6c4928911d2554e9cffda8\UnityEvent.cs

//程序集 UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

//E:\E_ProgramFiles_02\UnitySetup64-2018.3.0f2\Unity\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll

using System.Reflection;

using UnityEngine.Scripting;

namespace UnityEngine.Events{

    //A zero argument persistent callback that can be saved with the Scene.(立钻哥哥:能够与场景一块儿保存的零参数持久回调.

    public class UnityEvent : UnityEventBase{

        //Constructor.(立钻哥哥:构造函数

        [RquiredByNativeCode]

        public UnityEvent();

 

        //Add a no persistent listener to the UnityEvent.(立钻哥哥:向UnityEvent添加一个no持久性侦听器.

        //[call]: Callback function.(立钻哥哥:[call]:回调函数

        public void AddListener(UnityAction call);

 

        //Invoke all registered callbacks(runtime and persistent).(立钻哥哥:调用全部已注册的回调(运行时和持久回调)

        public void Invoke();

 

        //Remove a non persistent listener from the UnityEvent.(立钻哥哥:从UnityEvent中删除一个非持久性侦听器.

        public void RemoveListener(UnityAction call);

 

        protected override MethodInfo FindMethod_Impl(string name, object targetObj);

    }    //立钻哥哥:public class UnityEvent:UnityEventBase{}

}    //立钻哥哥:namespace UnitEngine.Events{}

++++public UnityEvent onPickUp;

++++public UnityEvent onDetachFromHand;

++++public UnityEvent<Hand> onHeldUpdate;

 

++知识点04:RigidbodyInterpolation

++++立钻哥哥:C:\Users\unity\AppData\Local\Temp\MetadataAsSource\4d44249b313b4410af4d2d6d08747e70\7c712a196dab48d19d50417cc6836298\RigidbodyInterpolation.cs

//程序集 UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

//E:\E_ProgramFiles_02\UnitySetup64-2018.3.0f2\Unity\Editor\Data\Managed\UnityEngine\UnityEngine.PhysicsModule.dll

namespace UnityEngine{

    //Rigidbody interpolation mode.(立钻哥哥:Rigidbody插值模式.

    public enum RigidbodyInterpolation{

        //No Interpolation.(立钻哥哥:没有插值.

        None = 0,

 

        //Interpolation will always lag a little bit behind but can be smoother than extrapolation.(立钻哥哥:插值老是有点落后,但能够比外推平滑.

        Interpolate = 1,

 

        //Extrapolation will predict the position of the rigidbody based on the current velocity.(立钻哥哥:外推法将根据电流速度来预测刚体的位置.

        Extrapolate = 2

    }    //立钻哥哥:public enum RigidbodyInterpolation{}

}    //立钻哥哥:namespace UnityEngine{}

++++protected RigidbodyInterpolation hadInterpolation = RigidbodyInterpolation.None;

++++rigidbody.interpolation = RigidbodyInterpolation.None;

 

++知识点05:SteamVR_Utils.GetLossyScale

++++立钻哥哥:\Assets\SteamVR\Scripts\SteamVR_Utils.cs

public static float GetLossyScale(Transform forTransform){

    float scale = 1f;

    while(forTransform != null && forTransform.parent != null){

        forTransform = forTransform.parent;

        scale *= forTransform.localScale.x;

    }

    return scale;

}    //立钻哥哥:public static float GetLossyScale(){}

++++float catchingThreshold = catchingSpeedThreshold * SteamVR_Utils.GetLossyScale(Player.instance.trackingOriginTransform);

 

++知识点06:hand.GetBestGrabbingType

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public GrabTypes GetBestGrabbingType(){

    return GetBestGrabbingType(GrabTypes.None);

}    //立钻哥哥:public GrabTypes GetBestGrabbingType(){}

++++GrabTypes bestGrabType = hand.GetBestGrabbingType();

 

++知识点07:GrabTypes

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\GrabTypes.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Valve.VR.InteractionSystem{

    public enum GrabTypes{

        None,

        Trigger,

        Pinch,

        Grip,

        Scripted,

    }    //立钻哥哥:public enum GrabTypes{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++GrabTypes bestGrabType = hand.GetBestGrabbingType();

++++if(bestGrabType != GrabType.None){}

++++GrabTypes startingGrabType = hand.GetGrabStarting();

++++if(startingGrabType != GrabType.None){}

 

++知识点08:hand.AttachObject

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Attach a GameObject to this GameObject.(立钻哥哥:将GameObject(游戏物体)附加到这个GameObject(游戏物体)上

//[objectToAttach]: The GameObject to attach.(立钻哥哥:[objectToAttach]:要附加的GameObject.

//[flags]: The flags to use for attaching the object.(立钻哥哥:[flags]:用于附加对象的标志.

//[attachmentPoint]: Name of the GameObject in the hierarchy of this Hand which should act as the attachment point for this GameObject.(立钻哥哥:[attachmentPoint]:这只手的层次结构中GameObject的名称,它应该做为这个GameObject的链接点.

public void AttachObject(GameObject objectToAttach, GrabTypes grabbedWithType, AttachmentFlags flags=defaultAttachmentFlags, Transform attachmentOffset=null){

    AttachedObject attachedObject = new AttachedObject();

    attachedObject.attachmentFlags = flags;

    attachedObject.attachedOffsetTransform = attachmentOffset;

    attachedObject.attachTime = Time.time;

 

    if(flags == 0){

        flags = defaultAttachmentFlags;

    }

 

    //Make sure top object on stack is non-null.(立钻哥哥:确保堆栈上的top对象非空.

    CleanUpAttachedObjectStack();

 

    //Detach the object if it is already attached so that it can get re-attached at the top of the stack.(立钻哥哥:若是对象已经附加,则将其分离,以即可以在堆栈顶部从新附加.

    if(ObjectIsAttached(objectToAttach)){

        DetachObject(objectToAttach);

    }

 

    //Detach from the other hand if requested.(立钻哥哥:若是须要,从另外一只手断开.

    if(attachedObject.HasAttachFlag(AttachmentFlags.DetachFromOtherHand)){

        if(otherHand != null){

            otherHand.DetachObject(objectToAttach);

        }

    }

 

    ... ...

 

    UpdateHovering();

 

    objectToAttach.SendMessage(OnAttachedToHand, this, SendMessageOptions.DontRequireReceiver);

}    //立钻哥哥:public void AttachObject(){}

++++hand.AttachObject(gameObject, bestGrabType, attachmentFlags);

++++hand.AttachObject(gameObject, startingGrabType, attachmentFlags, attachmentOffset);

 

++知识点09:hand.ShowGrabHint

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public void ShowGrabHint(){

    ControllerButtonHints.ShowButtonHint(this, grabGripAction);

}    //立钻哥哥:public void ShowGrabHint(){}

++++hand.ShowGrabHint();

 

++知识点10:hand.HideGrabHint

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public void HideGrabHint(){

    ControllerButtonHints.HideButtonHint(this, grabGripAction);

}    //立钻哥哥:public void HideGrabHint(){}

++++hand.HideGrabHint();

 

++知识点11:hand.HoverLock

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Continue to hover over this object indefinitely, whether or not the Hand moves out of its interaction trigger volume.(立钻哥哥:不管手是否移出交互触发范围,都将无限期地悬停在该对象上

//[interactable]: The Interactable to hover over indefinitely.(立钻哥哥:[interactable]:能够无限悬停的可交互的.

public void HoverLock(Interactable interactable){

    hoverLocked = true;

    hoveringInteractable = interactable;

}    //立钻哥哥:public void HoverLock(){}

++++hand.HoverLock(null);

 

++知识点12:velocityEstimator.BeginEstimatingVelocity

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

public void BeginEstimatingVelocity(){

    FinishEstimatingVelocity();

    routine = StartCoroutine(EstimateVelocityCoroutine());

}    //立钻哥哥:public void BeginEstimatingVelocity(){}

++++velocityEstimator.BeginEstimatingVelocity();

 

++知识点13:hand.HoverUnlock

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Stop hovering over this object indefinitely.(立钻哥哥:中止无限期地悬停在这个物体上.

//[interactable]: The hover-locked Interactable to stop hovering over indefinitely.(立钻哥哥:[interactable]:锁定悬停的可交互,以中止无限期地悬停

public void HoverUnlock(Interactable interactable){

    if(hoveringInteractable == interactable){

        hoverLocked = false;

    }

}    //立钻哥哥:public void HoverUnlock(){}

++++hand.HoverUnlock(null);

 

++知识点14:velocityEstimator.FinishEstimatingVelocity

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

public void FinishEstimatingVelocity(){

    if(routine != null){

        StopCoroutine(routine);

        routine = null;

    }

}    //立钻哥哥:public void FinishEstimatingVelocity(){}

++++velocityEstimator.FinishEstimatingVelocity();

 

++知识点15:velocityEstimator.GetVelocityEstimate

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

public Vector3 GetVelocityEstimate(){

    Vector3 velocity = Vector3.zero;

    int velocitySampleCount = Mathf.Min(sampleCount, velocitySamples.Length);

    if(velocitySampleCount != 0){

        for(int i = 0;  i < velocitySampleCount;  i++){

            velocity += velocitySamples[i];

        }

        velocity *= (1.0f / velocitySampleCount);

    }

    return velocity;

}    //立钻哥哥:public Vector3 GetVelocityEstimate(){}

++++velocity = velocityEstimator.GetVelocityEstimate();

 

++知识点16:velocityEstimator.GetAngularVelocityEstimate

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

public Vector3 GetAngularVelocityEstimate(){

    Vector3 angularVelocity = Vector3.zero;

    int angularVelocitySampleCount = Mathf.Min(sampleCount, angularVelocitySamples.Length);

    if(angularVelocitySampleCount != 0){

        for(int i = 0;  i < angularVelocitySampleCount;  i++){

            angularVelocity += angularVelocitySamples[i];

        }

        angularVelocity *= (1.0f / angularVelocitySampleCount);

    }

    return angularVelocity;

}    //立钻哥哥:public Vector3 GetAngularVelocityEstimate(){}

++++angularVelocity = velocityEstimator.GetAngularVelocityEstimate();

 

++知识点17:hand.GetEstimatedPeakVelocites

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public void GetEstimatedPeakVelocites(out Vector3 velocity, out Vector3 angularVelocity){

    trackedObject.GetEstimatedPeakVelocities(out velocity, out angularVelocity);

    velocity = Player.instance.trackingOriginTransform.TransformVector(velocity);

    angularVelocity = Player.instance.trackingOriginTransform.TransformDirection(angularVelocity);

}    //立钻哥哥:public void GetEstimatedPeakVelocites(){}

++++hand.GetEstimatedPeakVelocities(out velocity, out angularVelocity);

 

++知识点18:hand.GetTrackedObjectVelocity

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\VelocityEstimator.cs

//Get the world velocity of the VR Hand.(立钻哥哥:获得VR手的世界速度.

public Vector3 GetTrackedObjectVelocity(float timeOffset=0){

    if(trackedObject == null){

        Vector3 velocityTarget, angularTarget;

        GetUpdatedAttachedVelocities(currentAttachedObjectInfo.Value, out velocityTarget, out angularTarget);

        return velocityTarget;

    }

 

    if(isActive){

        if(timeOffset == 0){

            return Player.instance.trackingOriginTransform.TransformVector(trackedObject.GetVelocity());

        }else{

            Vector3 velocity;

            Vector3 angularVelocity;

            trackedObject.GetVelocitiesAtTimeOffset(timeOffset, out velocity, out angularVelocity);

            return Player.instance.trackingOriginTransform.TransformVector(velocity);

        }

    }

 

    return Vector3.zero;

}    //立钻哥哥:public Vector3 GetTrackedObjectVelocity(){}

++++velocity = hand.GetTrackedObjectVelocity(releaseVelocityTimeOffset);

 

++知识点19:hand.GetTrackedObjectAngularVelocity

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Get the world space angular velocity of the VR Hand.(立钻哥哥:获得VR手的世界空间角速度.

public Vector3 GetTrackedObjectAngularVelocity(float timeOffset=0){

    if(trackedObject == null){

        Vector3 velocityTarget, angularTarget;

        GetUpdateAttachedVelocities(currentAttachedObjectInfo.Value, out velocityTarget, out angularTarget);

        return angularTarget;

    }

 

    if(isActive){

        if(timeOffset == 0){

            return Player.instance.trackingOriginTransform.TransformDirection(trackedObject.GetAngularVelocity());

        }else{

            Vector3 velocity;

            Vector3 angularVelocity;

 

            trackedObject.GetVelocitiesAtTimeOffset(timeOffset, out velocity, out angularVelocity);

            return Player.instance.trackingOriginTransform.TransformDirection(angularVelocity);

        }

    }

 

    return Vector3.zero;

}    //立钻哥哥:public Vector3 GetTrackedObjectAngularVelocity(){}

++++angularVelocity = hand.GetTrackedObjectAngularVelocity(releaseVelocityTimeOffset);

 

++知识点20:hand.IsGrabEnding

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

public bool IsGrabEnding(GameObject attachedObject){

    for(int attachedObjectIndex=0;  attachedObjectIndex < attachedObjects.Count;  attachedObjectIndex++){

        if(attachedObjects[attachedObjectIndex].attachedObject==attachedObject){

            return IsGrabbingWithType(attachedObjects[attachedObjectIndex].grabbedWithType)==false;

        }

    }

    return false;

}    //立钻哥哥:public bool IsGrabEnding(){}

++++if(hand.IsGrabEnding(this.gameObject)){}

 

++知识点21:hand.DetachObject

++++立钻哥哥:\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Detach this GameObject from the attached object stack of this Hand.(立钻哥哥:从这只手的附加对象堆栈中分离这个GameObject.

//[objectToDetach]: The GameObject to detach from this Hand.(立钻哥哥:[objectToDetach]:要从这只手分离的GameObject.

public void DetachObject(GameObject objectToDetach, bool restoreOriginalParent=true){

    int index = attachedObjects.FindIndex(l=>l.attachedObject==objectToDetach);

    if(index != -1){

        GameObject prevTopObject = currentAttachedObject;

        ... ...

    }

 

    attachedObjects.RemoveAt(index);

    CleanUpAttachedObjectStack();

    GameObject newTopObject = currentAttachedObject;

    hoverLocked = false;

    ... ...

}    //立钻哥哥:public void DetachObject(){}

++++hand.DetachObject(gameObject, restoreOriginalParent);

 

 

 

 

 

++八、添加“Skeleton Poser”骨架姿态组件

++++立钻哥哥:将“SteamVR_Skeleton_Poser”组件添加到带有“Interactable”的GameObject(游戏物体)中,并在与之交互时摆出咱们想要的手的样子

++++[Pose]类型的动做表示三维空间中的位置和旋转,通常用于跟踪VR控制器;(在Unity中对应类为“SteamVR_Action_Pose”);

++++[Skeleton]类型的动做可以获取用户在持握手柄控制器时的手指关节数据,经过返回数据,结合手部渲染模型,可以更加真实的呈现手部在虚拟世界的姿态,虽然不及像“Leap Motion”等设备获取手指输入那样精确,可是足以得到良好的沉浸感;(在Unity中对应类为:“SteamVR_Action_Skeleton”);

++++[SteamVR_Behaviour_Pose]:姿态行为组件(SteamVR_Behaviour_Pose)是跟踪对象的方向;将其添加到GameObject(游戏对象)中,以自动设置转换的位置和旋转,以匹配咱们跟踪的对象(一般是控制器);它还包含速度数据和各类辅助函数用于经常使用的定向函数

++++[SteamVR_Behaviour_Skeleton]:使用“SteamVR骨骼输入”(SteamVR_Behaviour_Skeleton)来帮助咱们猜想每一个关节的位置;根据当前使用的控制器和跟踪系统的不一样,精度也有所不一样;这也能够将GameObject内联到控制器中;因此咱们不须要在同一个物体上有一个姿态和一个骨架行为

++++[Skeleton Input(骨骼输入)]:内联的“Knuckles Valve”已经发布了一个系统,以得到骨骼手数据独立于咱们使用的控制器;有些控制器对单个关节的手部跟踪数据有很高的保真度,有些控制器只有咱们用于近似关节数据的按钮;【With Controller(带控制器)】:咱们的最佳近似值,在现实世界中,咱们手中的关节是围绕在控制器周围的;【Without Controller(不须要控制器)】:基于“控制器”数据,咱们估计打开或关闭咱们的手,当咱们试图持平或握拳紧握手

++++[Skeleton Poser(骨骼姿态)]:SteamVR_Skeleton_Poser”组件脚本被设计成独立于“SteamVR交互系统”运行,而且能够添加到咱们本身的系统中;这个组件将在后面补充比较详细的描述,请继续往下查阅吧!(官方Demo连接:https://valvesoftware.github.io/steamvr_unity_plugin/tutorials/Skeleton-Poser.html

++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs

using System;

using System.Collections;

using UnityEngine;

using Valve.VR;

using System.Collectons.Generic;

using System.Linq;

 

namespace Valve.VR{

    public class SteamVR_Skeleton_Poser : MonoBehaviour{

        public GameObject previewLeftHandPrefab;

        public GameObject previewRightHandPrefab;

 

        public SteamVR_Skeleton_Pose skeletonMainPose;

        public List<SteamVR_Skeleton_Pose> skeletonAdditionalPose = new List<SteamVR_Skeleton_Pose>();

 

        [SerializeField]

        protected bool showLeftPreview = false;

        protected bool showRightPreview = true;

        protected GameObejct previewLeftInstance;

        protected GameObject previewRightInstance;

        protected int previewPoseSelection = 0;

 

        public int blendPoseCount{}

 

        public List<PoseBlendingBehaviour> blendingBehaviours = new List<PoseBlendingBehaviour>();

        public SteamVR_Skeleton_PoseSnapshot blendedSnapShotL;

        public SteamVR_Skeleton_PoseSnapshot blendedSnapShortR;

        private SkeletonBlendablePose[] blendPoses;

        private int boneCount;

        private bool poseUpdateThisFrame;

        public float scale;

 

        protected void Awake(){}

 

        //Set the blending value of a blendingBehaviour. Works best on Manual type behaviours.(立钻哥哥:设置混合行为的混合值。最适用于手动类型的行为.

        public void SetBlendingBehaviourValue(string behaviourName, float value){}

 

        //Get the blending value of a blendingBehaviour.(立钻哥哥:获取混合行为的混合值

        public float GetBlendingBehaviourValue(string behaviourName){}

 

        //Enable or disable a blending behaviour.(立钻哥哥:启用或禁用混合行为.

        public void SetBlendingBehaviourEnabled(string behaviourName, bool value){}

 

        //Check if a blending behaviour is enabled.(立钻哥哥:检查是否启用了混合行为

        public bool GetBlendingBehaviourEnabled(string behaviourName){}

 

        //Get a blending behaviour by name.(立钻哥哥:经过名称得到混合行为

        public PoseBlendingBehaviour GetBlendingBehaviour(string behaviourName){}

 

        public SteamVR_Skeleton_Pose GetPoseByIndex(int index){}

        private SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Source inputSource){}

 

        //Retrieve the final animated pose, to be applied to a hand skeleton.(立钻哥哥:检索要应用于手部骨骼的最终动画姿式.

        public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources handType){}

        public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Behaviour_Skeleton skeletonBehaviour){}

 

        //Updates all pose animation and blending. Can be called from different places without performance concerns, as it will only let itself run once per frame.(立钻哥哥:更新全部的姿态动画和混合。能够从不一样的地方调用,而不须要考虑性能问题,由于它只容许本身在每帧中运行一次.

        public void UpdatePose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource){}

 

        protected void ApplyBlenderBehaviours(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource, SteamVR_Skeleton_PoseSnapshot snapshot){}

 

        protected void LateUpdate(){}

 

        //Weighted average of n vector2s.(立钻哥哥:n个向量的加权平均

        public Vector3 BlendVectors(Vector3[] vectors, float[] weights){}

 

        //Weighted average of n quaternions.(立钻哥哥:n个四元数的加权平均

        protected Quaternion BlendQuaternions(Quaternion[] quaternions, float[] weights){}

    

        //A SkeletonBlendablePose holds a reference to a Skeleton_Pose scriptableObject, and also contains some helper functions. Also handles pose-specific animation like additive finger motion.(立钻哥哥:SkeletonBlendablePose持有对Skeleton_Pose脚本对象的引用,而且还包含一些帮助函数。还处理特定位置的动画,如添加手指运动.

        public class SkeletonBlendablePose{

            public SteamVR_Skeleton_Pose pose;

            public SteamVR_Skeleton_PoseSnapshot snapshotR;

            public SteamVR_Skeleton_PoseSnapshot snapshotL;

 

            //Get the snapshot of this pose with effects such as additive finger animation applied.(立钻哥哥:使用添加手指动画等效果获取此姿态的快照.

            public SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource){}

 

            public void UpdateAdditiveAnimation(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource){}

 

            //Init based on an existing Skeleton_Pose.(立钻哥哥:初始化基于一个现有的骨架姿态.

            public SkeletonBlendablePose(SteamVR_Skeleton_Pose p){}

 

            //Copy tht base pose into the snapshots.(立钻哥哥:将基本姿式复制到快照中

            public void PoseToSnapshots(){}

 

            public SkeletonBlendablePose(){}

 

        }    //立钻哥哥:public class SkeletonBlendablePose{}   

 

        //A filter applied to the base pose. Blends to a secondary pose by a certain weight. Can be masked per-finger.(立钻哥哥:用于基本位姿的滤波器。经过必定的重量调整到第二个姿式。每一个手指均可以蒙面.

        [System.Serializable]

        public class PoseBlendingBehaviour{

            public string name;

            public bool enabled = true;

            public float influence = 1;

            public int pose = 1;

            public float value = 0;

            public SteamVR_Action_Single action_single;

            public SteamVR_Action_Boolean action_bool;

            public float smoothingSpeed = 0;

            public BlenderTypes type;

            public bool useMask;

            public SteamVR_Skeleton_HandMask mask = new SteamVR_Skeleton_HandMask();

            public bool previewEnabled;

 

            //Performs smoothing based on deltaTime parameter.(立钻哥哥:基于deltaTime参数执行平滑.

            public void Update(){}

 

            //Apply blending this behaviours pose to an existing snapshot.(立钻哥哥:将此行为的姿态混合应用于现有快照.

            public void ApplyBlending(SteamVR_Skeleton_PoseSnapshot snapshot, SkeletonBlendablePose[] blendPose, SteamVR_Input_Sources inputSource){}

 

            public PoseBlendingBehaviour(){}

 

            public enum BlenderTypes{

                Manual,

                AnalogAction,

                BooleanAction

            }    //立钻哥哥:public enum BlenderTypes{}

 

        }    //立钻哥哥:public class PoseBlendingBehaviour{}

 

    }    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

 

 

    //PoseSnapshots hold a skeleton pose for one hand, as well as storing which hand they contain. They have several functions for combining BlendablePoses.(立钻哥哥:PoseSnapshots为一只手保留一个骨架的姿式,同时也保存了它们包含的那只手。他们有几个功能,以结合可调和的姿式.

    public class SteamVR_Skeleton_PoseSnapshot{

        public Vector3 position;

        public Quaternion rotation;

        public Vector3[] bonePositions;

        public Quaternion[] boneRotations;

 

        public SteamVR_Skeleton_PoseSnapshot(int boneCount, SteamVR_Input_Sources source){}

 

        //Perform a deep copy from one poseSnapshot to another.(立钻哥哥:执行从一个位置到另外一个位置的深度复制.

        public void CopyFrom(SteamVR_Skeleton_PoseSnapshot source){}

 

    }    //立钻哥哥:public class SteamVR_Skeleton_PoseSnapshot{}

 

    //Simple mask for fingers.(立钻哥哥:简单的手指遮罩

    [System.Serializable]

    public class SteamVR_Skeleton_HandMask{

        public bool palm;

        public bool thumb;

        public bool index;

        public bool middle;

        public bool ring;

        public bool pinky;

        public boo[] values = new bool[6];

 

        public void SetFinger(int i, bool value){}

        public bool GetFinger(int i){}

 

        public SteamVR_Skeleton_HandMask(){}

 

        //All elements on.(立钻哥哥:全部的元素.

        public void Reset(){}

 

        protected void Apply(){}

 

        public static readonly SteamVR_Skeleton_HandMask fullMask = new SteamVR_Skeleton_HandMask();

 

    }    //立钻哥哥:public class SteamVR_Skeleton_HandMask{}

 

}    //立钻哥哥:namespace Valve.VR{}

 

++SteamVR_Skeleton_Poser相关的类

++++立钻哥哥SteamVR_Skeleton_Poser”相关的平级类有:“public class SteamVR_Skeleton_PoseSnapshot{}”和“public class SteamVR_Skeleton_HandMask{}”,注意:这两个类没有继承MonoBehaviour,应该是一个数据类

++++“public class SteamVR_Skeleton_Poser:MonoBehaviour{}”内嵌的类有:“public class SkeletonBlendablePose{}”和“public class PoseBlendingBehaviour{}”,注意:这没有继承MonoBehaviour,应该是一个数据类

namespace Valve.VR{

    public class SteamVR_Skeleton_Poser : MonoBehaviour{

        //A SkeletonBlendablePose holds a reference to a Skeleton_Pose scriptableObject, and also contains some helper functions. Also handles pose-specific animation like additive finger motion.(立钻哥哥:SkeletonBlendablePose持有对Skeleton_Pose脚本对象的引用,而且还包含一些帮助函数。还处理特定位置的动画,如添加手指运动.

        public class SkeletonBlendablePose{

        }    //立钻哥哥:public class SkeletonBlendablePose{}   

 

        //A filter applied to the base pose. Blends to a secondary pose by a certain weight. Can be masked per-finger.(立钻哥哥:用于基本位姿的滤波器。经过必定的重量调整到第二个姿式。每一个手指均可以蒙面.

        [System.Serializable]

        public class PoseBlendingBehaviour{

        }    //立钻哥哥:public class PoseBlendingBehaviour{}

 

    }    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

 

    //PoseSnapshots hold a skeleton pose for one hand, as well as storing which hand they contain. They have several functions for combining BlendablePoses.(立钻哥哥:PoseSnapshots为一只手保留一个骨架的姿式,同时也保存了它们包含的那只手。他们有几个功能,以结合可调和的姿式.

    public class SteamVR_Skeleton_PoseSnapshot{

    }    //立钻哥哥:public class SteamVR_Skeleton_PoseSnapshot{}

 

    //Simple mask for fingers.(立钻哥哥:简单的手指遮罩

    [System.Serializable]

    public class SteamVR_Skeleton_HandMask{

    }    //立钻哥哥:public class SteamVR_Skeleton_HandMask{}

 

}    //立钻哥哥:namespace Valve.VR{}

 

++知识点01:SteamVR_Skeleton_Poser

++++立钻哥哥SteamVR_Skeleton_Poser”组件是在“v2.2RC1”版本中增长的,简化了建立姿式,很容易与“SteamVR骨骼系统”兼容,例如,检查“交互系统”场景中的对象,或者将组件添加到“Interactable”中

++++SteamVR_Skeleton_Poser”脚本被设计成独立于“SteamVR交互系统”,而且能够添加到咱们本身的系统中

++++咱们能够将“SteamVR_Skeleton_Poser”组件添加到带有“Interactable”的GameObject(游戏物体)中,并在与之交互时摆出咱们想要的手的样子;(You can then add the SteamVR_Skeleton_Poser component to a GameObject with an Interactable and pose how you want the hand to look when interacting with it.

namespace Valve.VR{

    public class SteamVR_Skeleton_Poser : MonoBehaviour{

        public class SkeletonBlendablePose{}

        public class PoseBlendingBehaviour{}

    }

}

++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Interactable.cs

public class Interactable : MonoBehaviour{

++++public SteamVR_Skeleton_Poser skeletonPoser;

++++skeletonPoser = GetComponent<SteamVR_Skeleton_Poser>();

++++if(skeletonPoser != null){}

++++if(skeletonPoser != null && hand.skeleton != null){}

++++hand.skeleton.BlendToPoser(skeletonPoser, blendToPoseTime);

}    //立钻哥哥:public class Interactable : MonoBehaviour{}

++++-\Assets\SteamVR\Input\SteamVR_Behaviour_Skeleton.cs

public class SteamVR_Behaviour_Skeleton : MonoBehaviour{

++++SteamVR_Skeleton_Poser blendPoser;

++++if(blendPoser != null && skeletonBlend < 1){}

++++blendSnapshot = blendPoser.GetBlendedPose(this);

++++blendPoser = poser;(public void BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime=0.1f){})

++++if(blendPoser != null){}

++++SteamVR_Skeleton_Pose_Hand minPose = blendPoser.skeletonMainPose.GetHand(inputSource);

++++public void BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime = 0.1f){}

}    //立钻哥哥:public class SteamVR_Behaviour_Skeleton:MonoBehaviour{}

++++\Assets\SteamVR\Input\Editor\SteamVR_Skeleton_PoserEditor.cs

[CustomEditor(typeof(SteamVR_Skeleton_Poser))]

public class SteamVR_Skeleton_PoserEditor : Editor{

++++private SteamVR_Skeleton_Poser poser;

++++poser = (SteamVR_Skeleton_Poser)target;

++++preview.transform.parent = poser.transform;

++++handData.position = thisSkeleton.transform.InverseTransformPoint(poser.transform.position);

++++EditorUtility.SetDirty(poser.skeletonMainPose);

++++poser.poseNames = new string[skeletonAdditionalPosesProperty.arraySize + 1];

++++poser.poseNames[i] = skeletonMainPoseProperty.objectReferenceValue = null ? [not set] : skeletonMainPoseProperty.objectReferenceValue.name +  (MAIN);

++++poser.poseNames[i] = skeletonAdditionalPosesProperty.GetArrayElementAtIndex(i-1).objectReferenceValue == null ? [not set] : skeletonAdditionalPosesProperty.GetArrayElementAtIndex(i - 1).objectReferenceValue.name;

++++int poseSelected = GUILayout.Toolbar(activePoseIndex, poser.poseNames);

++++blenderPose.intValue = EditorGUILayout.Popup(Pose, blenderPose.intValue, poser.poseNames);

++++poser.blendingBehaviours[i].mask.Reset();

++++poser = (SteamVR_Skeleton_Poser)target;

++++if(blenderType.intValue == (int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderType.Manual){}

++++if(blenderType.intValue == (int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderTypes.AnalogAction){}

++++if(blenderType.intValue == (int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderTypes.BooleanAction){}

}    //立钻哥哥:public class SteamVR_Skeleton_PoserEditor:Editor{}

++++public class SteamVR_Skeleton_Poser:MonoBehaviour{}

 

++知识点02:SKeletonBlendablePose

++++立钻哥哥A SkeletonBlendablePose holds a reference to a Skeleton_Pose scriptableObject, and also contains some helper functions. Also handles pose-specific animation like additive finger motion.SkeletonBlendablePose持有对Skeleton_Pose脚本对象的引用,而且还包含一些帮助函数。还处理特定位置的动画,如添加手指运动

namespace Valve.VR{

    public class SteamVR_Skeleton_Poser : MonoBehaviour{

        public class SkeletonBlendablePose{

            public SteamVR_Skeleton_Pose pose;

            public SteamVR_Skeleton_PoseSnapshot snapshotR;

            public SteamVR_Skeleton_PoseSnapshot snapshotL;

 

            public SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource){}

            public void UpdateAdditiveAnimation(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource){}

            public SkeletonBlendablePose(SteamVR_Skeleton_Pose p){}

            public void PoseToSnapshots(){}

            public SkeletonBlendlePose(){}

        }    //立钻哥哥:public class SkeletonBlendablePose{}

    }    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

}     //立钻哥哥:namespace Valve.VR{}

++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs

public class SteamVR_Skeleton_Poser:MonoBehaviour{

++++private SkeletonBlendablePose[] blendPoses;

++++blendPoses = new SkeletonBlendablePose[skeletonAdditionalPoses.Count + 1];

++++blendPoses[i] = new SkeletonBlendablePose(GetPoseByIndex(i));

++++blendPoses[i].PoseToSnapshots();

++++blendPoses[0].UpdateAdditiveAnimation(skeletonAction, inputSource);

++++snap.CopyFrom(blendPoses[0].GetHandSnapshot(inputSource));

++++blendPoses[blendingBehaviours[behaviourIndex].pose].UpdateAdditiveAnimation(skeletonAction, inputSource);

++++blendingBehaviours[behaviourIndex].ApplyBlending(snapshot, blendPoses, inputSource);

++++public void ApplyBlending(SteamVR_Skeleton_PoseSnapshot snapshot, SkeletonBlendablePose[] blendPoses, SteamVR_Input_Sources inputSource){}

++++SteamVR_Skeleton_PoseSnapshot targetSnapshot = blendPoses[pose].GetHandSnapshot(inputSource);

++++public int blendPoseCount{  get  {  return blendPoses.Length;  }  }

++++public SkeletonBlendablePose(SteamVR_Skeleton_Pose p){}

++++public SkeletonBlendablePose(){}

}    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

++++public class SkeletonBlendablePose{}

 

++知识点03:PoseBlendingBehaviour

++++立钻哥哥A filter applied to the base pose. Blends to a secondary pose by a certain weight. Can be masked per-finger.用于基本位姿的滤波器。经过必定的重量调整到第二个姿式。每一个手指均可以蒙面

[System.Serializable]

public class PoseBlendingBehaviour{

    public string name;

    public bool enabled = true;

    public float influence = 1;

    public int pose = 1;

    public float value = 0;

    public SteamVR_Action_Single action_single;

    public SteamVR_Action_Boolean action_bool;

    public float smoothingSpeed = 0;

    public BlenderType type;

    public bool useMask;

    public SteamVR_Skeleton_HandMask mask = new SteamVR_Skeleton_HandMask();

    public bool previewEnabled;

 

    public void Update(float deltaTime, SteamVR_Input_Sources inputSource){}

    public void ApplyBlending(SteamVR_Skeleton_PoseSnapshot snapshot, SkeletonBlendingPose[] blendPoses, SteamVR_Input_Sources inputSource){}

    public PoseBlendingBehaviour{}

    public enum BlenderTypes{}

}    //立钻哥哥:public class PoseBlendingBehaviour{}

++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs

public class SteamVR_Skeleton_Poser : MonoBehaviour{

++++public List<PoseBlendingBehaviour> blendingBehaviours = new List<PoseBlendingBehaviour>();

++++PoseBlendingBehaviour behaviour = blendingBehaviours.Find(b=>b.name==behaviourName);

++++for(int behaviourIndex=0; behaviourIndex < blendingBehaviours.Count; behaviourIndex++){}

++++blendingBehaviours[behaviourIndex].Update(Time.deltaTime, inputSource);

++++if(blendingBehaviour[behaviourIndex].enabled && blendingBehaviours[behaviourIndex].influence * blendingBehaviours[behaviourIndex].value > 0.01f){}

++++if(blendingBehaviours[behaviourIndex].pose != 0){}

++++blendPoses[blendingBehaviours[behaviourIndex].pose].UpdateAdditiveAnimation(skeletonAction, inputSource);

++++blendingBehaviours[behaviourIndex].ApplyBlending(snapshot, blendPoses, inputSource);

++++public PoseBlendingBehaviour GetBlendingBehaviour(string behaviourName){}

++++public PoseBlendingBehaviour{}

}    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

++++\Assets\SteamVR\Input\Editor\SteamVR_Skeleton_PoserEditor.cs

[CustomEditor(typeof(SteamVR_Skeleton_Poser))]

public class SteamVR_Skeleton_PoserEditor : Editor{

++++if(blenderType.intValue==(int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderType.Manual){}

++++if(blenderType.intValue==(int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderTypes.AnalogAction){}

++++if(blenderType.intValue==(int)SteamVR_Skeleton_Poser.PoseBlendingBehaviour.BlenderTypes.BooleanAction){}

}    //立钻哥哥:public class SteamVR_Skeleton_PoserEditor:Editor{}

++++public class PoseBlendingBehaviour{}

 

++知识点04:SteamVR_Skeleton_PoseSnapshot

++++立钻哥哥PoseSnapshots hold a skeleton pose for one hand, as well as storing which hand they contain. They have several functions for combining BlendablePoses.PoseSnapshots为一只手保留一个骨架的姿式,同时也保存了它们包含的那只手。他们有几个功能,以结合可调和的姿式

public class SteamVR_Skeleton_PoseSnapshot{

    public SteamVR_Input_Sources inputSource;

    public Vector3 position;

    public Quaternion rotation;

    public Vector3[] bonePositions;

    public Quaternion[] boneRotations;

 

    public SteamVR_Skeleton_PoseSnapshot(int boneCount, SteamVR_Input_Sources source){}

    public void CopyFrom(SteamVR_Skeleton_PoseSnapshot source){}

}    //立钻哥哥:public class SteamVR_Skeleton_PoseSnapshot{}

++++\Assets\SteamVR\Input\SteamVR_Behaviour_Skeleton.cs

public class SteamVR_Behaviour_Skeleton : MonoBehaviour{

++++protected SteamVR_Skeleton_PoseSnapshot blendSnapshot;

++++blendSnapshot = blendPoser.GetBlendedPose(this);

++++SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], blendedRangeOfMotionPosition, skeletonBlend));

++++Quaternion poseRotation = blendSnapshot.boneRotations[boneIndex];

++++SetBonePosition(boneIndex, blendSnapshot.bonePositions[boneIndex]);

++++SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], bonePositions[boneIndex], skeletonBlend));

}    //立钻哥哥:public class SteamVR_Behaviour_Skeleton:MonoBehaviour{}

++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs

public class SteamVR_Skeleton_Poser : MonoBehaviour{

++++public SteamVR_Skeleton_PoseSnapshot blendedSnapshotL;

++++blendedSnapshotL = new SteamVR_Skeleton_PoseSnapshot(boneCount, SteamVR_Input_Sources.LeftHand);

++++if(intpusource == SteamVR_Input_Sources.LeftHand){ return blendedSnapshotL; }

++++if(inputSource == SteamVR_Input_Sources.LeftHand){ blendedSnapshotL = snap; }

++++public SteamVR_Skeleton_PoseSnapshot blendedSnapshotR;

++++blendedSnapshotR = new SteamVR_Skeleton_PoseSnapshot(boneCount, SteamVR_Input_Sources.RightHand);

++++if(inputSource == SteamVR_Input_Sources.LeftHand){}else{ return blendedSnapshotR; }

++++if(inputSource == SteamVR_Input_Sources.RightHand){ blendedSnapshotR = snap; }

++++private SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource){}

++++public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources handType){}

++++public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Behaviour_Skeleton skeletonBehaviour){}

++++SteamVR_Skeleton_PoseSnapshot snap = GetHandSnapshot(inputSource);

++++snap.CopyFrom(blendPoses[0].GetHandSnapshot(inputSource));

++++ApplyBlenderBehaviours(skeletonAction, inputSource, snap);

++++if(inputSource == SteamVR_Input_Sources.RightHand){ blendedSnapshotR = snap; }

++++if(inputSource == SteamVR_Input_Sources.LeftHand){ blendedSnapshotL = snap; }

++++protected void ApplyBlenderBehaviours(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource, SteamVR_Skeleton_PoseSnapshot snapshot){}

++++blendingBehaviours[behaviourIndex].ApplyBlending(snapshot, blendPoses, inputSource);

}    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

++++\Assets\SteamVR\InteractionSystem\Core\Scripts\Hand.cs

//Links with an appropriate SteamVR controller and facilitates interactions with objects in the virtual world.(立钻哥哥:连接到适当的SteamVR控制器,并方便与虚拟世界中的对象进行交互.

public class Hand : MonoBehaviour{

++++SteamVR_Skeleton_PoseSnapshot pose = attachedObject.interactable.skeletonPoser.GetBlendedPose(skeleton);

++++objectToAttach.transform.position = this.transform.TransformPoint(pose.position);

++++objectToAttach.transform.rotation = this.transform.rotation * pose.rotation;

++++SteamVR_Skeleton_PoseSnapshot pose = null;

++++pose = currentAttachedObjectInfo.Value.interactable.skeletonPoser.GetBlendedPose(skeleton);

++++if(pose == null){}

}    //立钻哥哥:public class Hand:MonoBehaviour{}

++++public class SteamVR_Skeleton_PoseSnapshot{}

 

++知识点05:SteamVR_Skeleton_HandMask

++++立钻哥哥Simple mask for fingers.简单的手指遮罩

[System.Serializable]

public class SteamVR_Skeleton_HandMask{

    public bool palm;

    public bool thumb;

    public int index;

    public bool middle;

    public bool ring;

    public bool pinky;

    public bool[] values = new bool[6];

 

    public void SetFinger(int i, bool value){}

    public bool GetFinger(int i){}

    public SteamVR_Skeleton_HandMask(){}

    public void Reset(){}

    protected void Apply(){}

 

    public static readonly SteamVR_Skeleton_HandMask fullMask = new SteamVR_Skeleton_HandMask();

}    //立钻哥哥:public class SteamVR_Skeleton_HandMask{}

++++\Assets\SteamVR\Input\SteamVR_Skeleton_Poser.cs

public class SteamVR_Skeleton_Poser : MonoBehaviour{

++++public SteamVR_Skeleton_HandMask mask = new SteamVR_Skeleton_HandMask();

++++if(mask.GetFinger(0) || useMask==false){}

++++if(mask.GetFinger(SteamVR_Skeleton_JointIndexes.GetFingerForBone(boneIndex)+1) || useMask==false){}

++++public static readonly SteamVR_Skeleton_HandMask fullMask = new SteamVR_Skeleton_HandMask();

}    //立钻哥哥:public class SteamVR_Skeleton_Poser:MonoBehaviour{}

++++public class SteamVR_Skeleton_HandMask{}

 

 

++++立钻哥哥:通过上面对“SteamVR_Skeleton_Poser”组件的学习,如今咱们来实践一下吧!

----尝试1:直接在一个Cube上挂载“SteamVR_Skeleton_Poser”组件,没有能拿起来!

----尝试2:那咱们就添加一个“Throwable”组件吧,由于这个组件会自动加载“Interactable”组件;其实咱们须要的是验证“SkeletonPoserInteractable”之间的配合关系呢!(立钻哥哥:仍是没有手势呢!!)

----尝试3:参考官方Demo示例,挂载缺失的脚本,看看能不能有奇迹出现呢?(比对后缺乏脚本:“InteractableHoverEvents.cs”、“TargetHitEffect.cs”):挂载了这两个脚本,运行后仍是没有出现手呢!?运行前却是有一只手了?仅在运行前能显示出来,运行后就没有了!

----尝试4:对比各个脚本差别,配置参数,只能再试一次了,不行就只能暂时跳过这个环节,后期补充一个专题;(嗯,有一个重大的发现:示例有一个空物体来承载全部脚本:请看“尝试5”)

----尝试5:在比对配置时,发现示例的可抛物是有层级的,父类是个空物体,把须要抓取的物品做为子物体处理的,咱们先尝试一下吧!(依次挂载脚本:“SteamVR_Skeleton_Poser.cs(抓取失败,可是没有配置)”、“Throwable.cs(能够抓取了)”),先挂这两个脚本,其次先配置一下“SteamVR_Skeleton_Poser”组件的配置;经过“PoserEditor”能够配置手势,可是仍是没有出现手势匹配;那咱们继续添加脚本“InteractableHoverEvents.cs”和“TargetHitEffect.cs”,单挂脚本没有任何做用;那就来比对配置一下参数吧,貌似仍是不行呀!

++++立钻哥哥:通过第一轮的各类尝试,尚未成功,暂且跳过这个环节,后期会推出对于“SteamVR_Skeleton_Poser”组件的专题,请在“SteamVR”分类中查阅:

https://blog.csdn.net/vrunsoftyanlz/article/category/8582642

+++++立钻哥哥:官网也有关于“Skeleton Poser”的教程,后期会根据这个教程整理一个专题:

https://valvesoftware.github.io/steamvr_unity_plugin/tutorials/Skeleton-Poser.html

 

++【Introduction】(介绍)

++++立钻哥哥:The Skeleton Poser system has a straightforward purpose: when picking up physical objects, your in-game hands should morph to poses holding the objects. These rock solid poses can be authored and tweaked right in the Unity editor, for quick iteration as your game progresses. You can apply fancy effects on top of these poses such as additive per-finger animation and dynamic grips, and multi-pose blending.骨架手势”系统有一个简单的目的:当你拿起实物时,你在游戏中的手应该变造成拿着实物的姿式。这些固定的姿式能够在Unity编辑器编写和调整,加快游戏迭代的速度。您能够在这些姿态之上应用一些奇特的效果,好比添加每一个手指的动画和动态握把,以及多姿态混合

++++The value of this system comes from the simplified workflow. Instead of dealing with imported animations and nightmarish animation graphs, poses are stored as compact assets and animations are applied automatically based on the pose associated with whatever youre holding. This allows more complex hand behaviour on a smaller time budget.(立钻哥哥:该系统的价值来自于简化的工做流。与处理导入的动画和噩梦般的动画图形不一样,pose存储为压缩资源,并根据与您所持有的任何内容相关联的姿式自动应用动画。这使得更复杂的手行为在更小的时间预算.

++++These are the basic of what these tools can do. What makes them superior to built in Unity animations is that, again, poses are authored right in the scene view, and complex behaviours can be stacked with the flick of a few switches.(立钻哥哥:这些是这些工具的基本功能。它们优于Unity动画的地方在于,一样的,姿式是在场景视图中建立的,复杂的行为能够经过一些开关堆叠起来.

++++To add hand poses to any object in your game, just add the SteamVR_Skeleton_Poser script to it. There are two sections of the Poser script, and we will be covering both in this tutorial.(立钻哥哥:要向游戏中的任何对象添加手部姿式,只需添加“SteamVR_Skeleton_Poser”脚本便可。不易处理的脚本有两个部分,咱们将涵盖在本教程.

 

++【Pose Editor】(姿态编辑器)

++++立钻哥哥:The pose editor is for creating and editing Poses(SteamVR_Skeleton_Pose) which can be saved as ScriptableObjects into your project and used on this object or any other in the game.pose编辑器用于建立和编辑pose (SteamVR_Skeleton_Pose),它能够做为“脚本对象”保存到您的项目中,并用于该对象或游戏中的任何其余对象

++++When you first add the script to a GameObject you will see an option to either select a pose from the project, or create a new one.(立钻哥哥:当您第一次将脚本添加到GameObject时,您将看到一个选项,要么从项目中选择一个姿式,要么建立一个新姿式.

++++The preview the poses youre authoring, click the hand Icons in the Left Hand and Right Hand sections to toggle the previews on and off in the scene. These preview skeletons hold all your modifications in their transforms, so remember not to disable a hand with changes unless they have been saved the Save Pose button.(立钻哥哥:预览你正在创做的姿式,点击“左手”和“右手”部分的手势图标,在场景中切换预览。这些预览框架在它们的转换中包含全部的修改,因此请记住,除非已经保存了“Save Pose”按钮,不然不要禁用带有更改的手.

++++The hands instantiated in the scene when you do this are temporary and will be destroyed when the game is run, as long as the script has kept track of them properly. It is good practice to disable both hand previews before applying to a prefab, as the skeletons are messy, large, and unnecessary in a prefab.(立钻哥哥:当你这样作时,在场景中实例化的手是临时的,而且在游戏运行时将被销毁,只要脚本正确地跟踪它们。在应用到预置以前禁用双手预览是一个很好的实践,由于在预置中骨架是混乱的、大的、没必要要的.

++++Its easiest to edit the poses when just one is enabled, but for some of the buttons in this tab to work you need both preview hands to be enabled. If a button is greyed out, you likely need to enable one or both skeletons to activate it.(立钻哥哥:当只启用一个时,编辑姿式是最简单的,可是要使这个选项卡中的一些按钮工做,您须要启用两个预览手。若是一个按钮是灰色的,您可能须要启用一个或两个骨架来激活它

++++If you want to modify the skeletons pose, just open up the hierarchy underneath your interactable object. You can see that a vr glove skeleton has been added to it, and you can go in and edit the transforms of these bones to form your pose.(立钻哥哥:若是您想修改骨架的姿态,只需打开interactable对象下面的层次结构。你能够看到一个“vr手套”骨架被添加到其中,你能够进入并编辑这些骨骼的变换来造成你的姿式

++++If you want to make asymmetrical poses: if you have, say an asymmetrical object: you can author a different pose for the right hand and left hand. For simple or symmetrical objects, though, you probably want the same pose for both hands, so you can copy any single-hand modifications youve made over the other hand with the Copy x Pose to y hand buttons. When the pose is copied, the hands are automatically mirrored across your object, and often give perfect results. Be careful with this operation, as it will permanently overwrite the other hands pose.(立钻哥哥:若是你想作一个不对称的姿式:若是你有,好比说一个不对称的物体:你能够为右手和左手设计一个不一样的姿式。不过,对于简单或对称的对象,您可能但愿两只手的姿式相同,所以您可使用“将x位姿复制到y位手”按钮复制对另外一只手进行的任何单手修改。当姿式被复制时,手会自动地在你的对象上镜像,而且一般会获得完美的结果。当心这个操做,由于它会永久地覆盖另外一只手的姿式.

++++Its a good idea to make backups of really important poses if youre going to be editing them, as the work can be lost easily.(立钻哥哥:若是你要编辑一些很是重要的姿式,备份是一个好主意,由于这些动做很容易丢失

++++To add more usable poses to an object, or to create a new pose, hit the little plus button next to the list of poses at the top. Youll see a new tab is created with no pose selected by default, and again you can either select one from the project or create a new pose. The poses added to a single SteamVR_Skeleton_Poser will be the poses available for blending later on. The order of these doesnt matter except for the first pose, labeled(MAIN), which will be the base pose.(立钻哥哥:要向对象添加更多可用的姿式,或建立一个新的姿式,请单击顶部的姿式列表旁边的小加号按钮。您将看到建立了一个新选项卡,默认状况下没有选择任何姿式,一样,您能够从项目中选择一个姿式,也能够建立一个新姿式。添加到单个“SteamVR_Skeleton_Poser”中的姿式将是稍后用于“混合”的姿式。这些的顺序可有可无,除了第一个姿式,标记为(MAIN),这将是基本姿式

++++Underneath each of the hand icons you may have noticed all the options for finger movement. This is for additive animation where you want the skeletal systems individual finger animation to apply on top of the poses that youve created. By default this will be set to static, but there are three other options.(立钻哥哥:在每一个手的图标下面,你可能已经注意到了手指移动的全部选项。这是为“添加动画”,您但愿骨骼系统的个别手指动画应用于您所建立的姿式之上。默认状况下,这将被设置为静态,但还有其余三个选项.

----[Static]: No additive animation;(立钻哥哥:[静态]:无添加动画;

----[Free]: If you do not want your pose to apply to that finger at all, and in that case its listen only to the skeleton system.(立钻哥哥:([自由]):若是你不但愿你的姿式应用到手指上,在这种状况下,它只听骨架系统

----[Extend]: If the pose that in the hand is in will be the tightest possible grip of that finger, lifting it up when the player lifts their finger up. This will probably be the most common, as poses are mainly going to be wrapping around objects.(立钻哥哥:[伸展]:若是手的姿式是手指最紧的握法,那么当玩家抬起手指时就把手指举起来。这多是最多见的,由于姿式主要是围绕着物体

----[Contract]: The opposite of extend, where whatever pose the finger is in will be the maximum extended value of the finger, and it will only be allowed to contract further towards the fist pose. Im not sure when that one would be used but we added it just in case.(立钻哥哥:[收缩]:与伸展相反,不管手指处于什么姿式,都是手指的最大伸展值,只容许手指向第一个姿式进一步收缩。我不肯定何时会用到这个可是咱们加了以防万一

 

++【Blending Editor】(混合编辑器)

++++立钻哥哥:The next tab is the blending editor. This is what you will use if you want to create more complicated behaviours, i.e. blending between multiple poses.(立钻哥哥:下一个选项卡是混合编辑器。若是你想创造更复杂的行为,好比多个姿式之间的混合,你可使用这个.

++++To start, youll want to hit the plus button at the bottom to add a new blending behaviour, called New Behaviour by default. You can enable and disable behavious, and they have an influence slider where you can turn them off and on with more of a ramp if you dont want to harshly enable and disable them during runtime.(立钻哥哥:首先,您须要点击底部的“plus按钮”来添加一个新的混合行为,默认状况下称为“new behavior”。你能够启用和禁用这个行为,它们有一个影响滑块,若是你不想在运行时严格地启用和禁用它们,你可使用更多的斜坡来关闭和打开它们.

++++They have a target pose that they will be blending to which by default is the main pose. This is poor design, because since the main pose is the base, this wont do anything. Instead, youll want to set this to one of the secondary poses youve added on the pose editor list.(立钻哥哥:他们有一个目标“姿式”,他们将混合其中的默认是主要的姿式。这是一个糟糕的设计,由于因为主要的姿式是基础,这不会作任何事情。相反,您将但愿将此设置为您在pose编辑器列表中添加的辅助姿式之一.

++++There are three different types of Blending Behavious: ManualAnalogBoolean.(立钻哥哥:有三种不一样类型的混合行为:手动混合、模拟混合、布尔混合.

----[Manual]:What you would use if you want this blending to be controlled by a script or just set in the inspector right here with this value slider. Does nothing on its own.(立钻哥哥:(手动):你会使用若是你想要这种混合控制的一套脚本或检查员用这个值在这里滑块。它本身什么也不作

----[Analog]:Lets you map this blending behaviour weight to one of the analog actions in your project. Smoothing speed lets you apply a little bit of smoothing to this. Zero means no smoothing, anything above zero is going to be slow smoothing getting faster and faster as the value goes up. An appropriate value would be somewhere between 10 and 30, although you may not want any smoothing at all since this is an analog action.(立钻哥哥:(模拟):让这种混合行为映射到一个模拟行动在您的项目中。平滑速度可让你对它进行一点平滑。零意味着没有平滑,任何大于零的都是缓慢平滑,随着数值的增长,平滑的速度愈来愈快。一个适当的值应该在10到30之间,尽管您可能根本不须要任何平滑,由于这是一个模拟操做

----[Boolean]:This is very similar to the analog action, except it can be mapped to a boolean action in your project such as a button press. In this behaviour type the smoothing is probably a little bit more important, because if you dont have any smoothing its going to be an instant jump. Again, a value between 10 and 30 is recommended.(立钻哥哥:(布尔):这很是相似于模拟行动,除了它能够被映射到一个布尔行动项目中如一个按钮按下。在这种行为类型中平滑可能更重要一些,由于若是你没有平滑,它将是一个瞬间的跳跃。一样,建议值在10到30之间

++++立钻哥哥:The final option in every blending behaviour is the mask. Anybody whos used Unitys humanoid animation system will find this UI very familiar, and those who havent will find it is pretty self-explanatory. If you do not use the mask the blending behavior will be applied to the entire hand. If you do opt in for the mask, them you can select different parts of the hand to apply blending to. Green parts will have the blending behavior applied to them, and gray parts will not.每种混合行为的最后一个选项是蒙版。任何使用过Unity类人动画系统的人都会发现这个UI很是熟悉,而那些没有使用过的人会发现它很是容易理解。若是您不使用蒙版,混合行为将适用于整个手。若是你选择了蒙版,你能够选择手的不一样部位进行混合。绿色部分将应用混合行为,而灰色部分不会

----Remember, you can stack multiple blending behaviours on top of each other and they will be applied in order. Using this, you can create some really cool complicated hand behaviours.(立钻哥哥:记住,您能够将多个混合行为堆叠在一块儿,它们将按顺序应用。使用这个,你能够创造一些很是酷的复杂的手的行为

 

++【Manual Behaviours】(手动操做)

++++立钻哥哥:Analog and Boolean behaviours animate automatically, but you do have to modify manual ones through code. Luckily, this is very easy. Heres an example script that would modulate a Behaviour named Example Behaviour using a since wave:(立钻哥哥:模拟和布尔行为自动动画,但你必须修改手动经过代码。幸运的是,这很简单。下面是一个示例脚本,它将使用since wave来调节名为“示例行为”的行为

using UnityEngine;

using System.Collections;

using Valve.VR;

 

public class PoseModulator : MonoBehaviour{

    SteamVR_Skeleton_Poser poser;

 

    private void Start(){

        poser = GetComponent<SteamVR_Skeleton_Poser>();

    }

 

    private void Update(){

        poser.SetBlendingBehaviourValue(Example Behaviour, Mathf.Sin(Time.time * 10)/2 + 0.5f);

    }

 

}    //立钻哥哥:public class PoseModulator:MonoBehaviour{}

 

++And the result(结果):

 

 

++【Scaling】(缩放)

++++立钻哥哥:Lots of games are made at different scales for any number of reasons. What matters is that your player may be scaled up or down. The poses are applied at runtime at whatever the player scale is, which is great, but the pose authoring tools are done at a normal scale by default. This will be a problem if youre making objects that should be interactable at larger scales, as the preview you get as you work on a pose will not match the pose that you see in the game. To solve this, we added a property, Preview Pose Scale, that lets you change the working scale of the pose editor.因为各类缘由,许多游戏都是以不一样的规模制做的。重要的是你的玩家可能被放大或缩小。姿态在运行时以任意玩家比例应用,这很好,但默认状况下,姿态创做工具是在正常比例下完成的。这将是一个问题,若是你正在制做的对象在更大的尺度上应该是可交互的,由于你在一个姿式上获得的预览与你在游戏中看到的姿式不匹配。为了解决这个问题,咱们添加了一个属性“预览姿态缩放”,它容许您更改位姿编辑器的工做缩放

----This value should be set to whatever your players scale will be.(立钻哥哥:这个值应该设置为你的玩家的规模将是什么.

----Poses saved from different Preview Scales will be indistinguishable, it is merely a helper for the editor to show what your poses will look applied from differently scaled hands.(立钻哥哥:从不一样的预览比例保存的姿式将是没法区分的,它只是一个帮助编辑器显示你的姿式将从不一样比例的手看起来应用.

 

++【Conclusion】(总结)

++++立钻哥哥:I hope this tutorial helped you get started creating your own hand poses!我但愿本教程能帮助您开始建立本身的手部姿式

++立钻哥哥:好吧,都看完“官方教程”了,感受仍是一头雾水,无论怎样,咱们再尝试一次,看看可否获得想要的“手势动做”!

++++步骤1:新建一个Cube,缩放到想要的比例后,挂上“SteamVR_Skeleton_Poser”看一下效果,由于根据教程就只须要挂上这个脚本就能够的呢!

++++步骤2:须要添加一个“Throwable”组件;==??能抓取,可是没有显示手??

++++总之,仍是失败了,这里就再也不继续了,有兴趣的能够查阅“SteamVR”分类,立钻哥哥会推出一个关于“SteamVR_Skeleton_Poser”组件的专题,来全面研究学习一下,此次就不拓展了!

++++那仍是官方标准的手势匹配的例子吧:

++++SteamVR分类:https://blog.csdn.net/vrunsoftyanlz/article/category/8582642

 

 

 

++九、添加“Teleporting”传送预制体

++++立钻哥哥:To add teleporting to your scene drag in the Teleporting prefab from Teleport/Prefabs into your scene. This will set up all the teleport logic.在场景中添加“远程传送”功能,请将“远程传送”预制件从“Teleport/Prefabs”拖动到场景中,这将设置全部的传送逻辑

++++关于“传送机制”有一篇专门的博客:http://www.javashuo.com/article/p-ophuaicg-gh.html

++++“The Lab(Valve的实验室)”的传送系统支持传送到特定的传送点或更通用的传送区;重要的类是“Teleport”、“TeleportPoint”、“TeleportArea

++++Teleport/Prefabs”下的预制体“Teleporting”包括了传送系统运做的全部逻辑;向场景中添加“TeleportPoints”或“TeleportAreas”,能够添加玩家能够传送到的点

++++Teleport.cs”这个类处理“Teleporting传送”的大部分逻辑;当触摸板被按下时,传送指针就会出现,当指针指向一个有效的点,松开便可传送玩家;(咱们也能够按下键盘上的“T”,在2D备份模式下,能够打开传送指针),“Teleport.cs”该类跟踪场景中的全部传送端口标记,并根据传送端口指针的状态通知它们淡入/淡出

++++在某些状况下,在地板上使用不一样于传送网格的网格是颇有用的,在这种状况下,传送系统将追踪它击中传送网的位置,并试图将其放置在地板网孔上,这样作的目的是尝试将场景中的视觉地板与玩家游戏区域中的物理地板匹配起来

++++Teleport.cs”中有一些属性可能须要调整:“tracerLayerMask”、“floorFixupMask”、“floorFixupMaximumTraceDistance”、“ShowPlayAreaMarker”、“arcDistance”等

----[tracerLayerMask]:这是传送指针将尝试命中的全部层

----[floorFixupMask]:地板所在的层

----[floorFixupMaximumTraceDistance]:查找地板的最大跟踪距离

----[ShowPlayAreaMarker]:这将切换是否显示传送时玩家游戏区域的矩形,这能够帮助玩家在他们的物理空间中找到方向

----[arcDistance]:传送弧应该走多远,增长这个数字将容许玩家在场景中传送得更远,这个值可能须要为每一个场景进行调整

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\Teleport.cs

//Purpose: Handles all the teleport logic.(立钻哥哥:用途:处理全部的传送逻辑.

using UnityEngine;

using UnityEngine.Events;

using System.Collections;

 

namespace Valve.VR.InteractionSystem{

    public class Teleport : MonoBehaviour{

        public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteaVR_Action_Boolean>(Teleport);

 

        private Hand pointerHand = null;

        private Player player = null;

        private TeleportArc teleportArc = null;

 

        private static Teleport _instance;

        public static Teleport instance{}

 

        void Awake(){  instance = this;  }

 

        private void UpdatePointer(){}

        private void TeleportPlayer(){}

    }    //立钻哥哥:public class Teleport:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

 

++++TeleportMarkerBase(传送标记基类):这是全部传送标记的基类;它包含“Teleport”类指望出如今全部Teleport标记中的方法;咱们能够用这个做为基类来建立一个新的传送标记;传送标记能够锁定或解锁,玩家不能传送到锁定的标记

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportMarkerBase.cs

//Purpose: Base class for all the objects that the player can teleport to.(立钻哥哥:用途:玩家能够传送到的全部对象的基类.

using UnityEngine;

 

namespace Valve.VR.InteractionSystem{

    public abstract class TeleportMarkerBase : MonoBehaviour{

        public bool locked = false;

        public bool markerActive = false;

 

        public virtual bool showReticle{}

        public void SetLocked(bool locked){}

        public virtual void TeleportPlayer(Vector3 pointedAtPosition){}

        public abstract void UpdateVisuals();

        public abstract void Highlight(bool highlight);

        public abstract void SetAlpha(float tintAlpha, float alphaPercent);

        public abstract bool ShouldActivate(Vector3 playerPosition);

        public abstract bool ShouldMovePlayer();

    }    //立钻哥哥:public abstract class TeleportMarkerBase:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++TeleportArea(传送区域):这是一个由网格组成的传送区;当传送到这些东西上时,玩家将会准确地传送到他们所指向的地方(加上地板固定);将“TeleportArea”组件添加到任何带有碰撞体和网格渲染器的对象中,以容许玩家在其上传送

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportArea.cs

//Purpose: An area that the player can teleport to.(立钻哥哥:用途:玩家能够传送到的区域.

using UnityEngine;

#if UNITY_EDITOR

    using UnityEditor;

#endif

 

namespace Valve.VR.InteractionSystem{

    public class TeleportArea : TeleportMarkerBase{

        public Bounds meshBounds{}

        private MeshRenderer areaMesh;

 

        public void Awake(){

            areaMesh = GetComponent<MeshRenderer>();

            tintColorId = Shader.PropertyToID(_TintColor);

            CalculateBounds();

        }

 

        public void Start(){}

 

        public override bool ShouldActivate(Vector3 playerPosition){}

        public override bool ShouldMovePlayer(){}

        public override void Highlight(bool highlight){}

        public override void SetAlpha(float tintAlpha, float alphaPercent){}

        public override void UpdateVisuals(){}

        private bool CalculateBounds(){}

        private Color GetTintColor(){}

    }    //立钻哥哥:public class TeleportArea:TeleportMarkerBase{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

 

++++[Teleporting]:传送预制体处理系统的全部传送逻辑

++++TeleportPoint(传送点):这是玩家能够传送到的传送点;当传送到这些东西上时,玩家将会在点的原点进行传送,而无论他们所指向的点在哪里

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportPoint.cs

//Purpose: Single location that the player can teleport to.(立钻哥哥:用途:单一的位置,玩家能够传送到.

using UnityEngine;

using UnityEngine.UI;

#if UNITY_EDITOR

    using UnityEditor;

#endif

 

namespace Valve.VR.InteractionSystem{

    public class TeleportPoint : TeleportMarkerBase{

        public enum TeleportPointType{

            MoveToLocation,

            SwitchToNewScene

        };

 

        public TeleportPointType teleportType = TeleportPointType.MoveToLocation;

 

        public override bool showReticle{}

        void Awake(){}

        void Start(){}

        void Update(){}

        public override bool ShouldActivate(Vector3 playerPosition){}

        public override bool ShouldMovePlayer(){}

        public override void Highlight(bool highlight){}

        public override void UpdateVisuals(){}

        public override void SetAlpha(float tintAlpha, float alphaPercent){}

        public void SetMeshMaterials(Material material, Color textColor){}

        public void TeleportToScene(){}

        public void GetRelevantComponents(){}

        public void ReleaseRelevantComponents(){}

        public void UpdateVisualsInEditor(){}

    }    //立钻哥哥:public class TeleportPoint:TeleportMarkerBase{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++TeleportArc(传送弧):这将为传送端口指针绘制弧线,并为传送端口系统进行物理跟踪

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportArc.cs

//Purpose: Displays the arc lines for teleporting and does the traces.(立钻哥哥:用途:显示用于远程传送的弧线并进行跟踪.

using UnityEngine;

 

namespace Valve.VR.InteractionSystem{

    public class TeleportArc : MonoBehaviour{

        public int segmentColor = 60;

        public float thickness = 0.01f;

 

        void Start(){}

        void Update(){}

        private void CreateLineRendererObjects(){}

        public void SetArcData(Vector3 position, Vector3 velocity, bool gravity, bool pointerAtBadAngle){}

        public void Show(){}

        public void Hide(){}

        public bool DrawArc(out RaycastHit hitInfo){}

        private void DrawArcSegment(int index, float startTime, float endTime){}

        public void SetColor(Color color){}

        private float FindProjectileCollison(out RaycastHit hitInfo){}

        public Vector3 GetArcPositionAtTime(float time){}

        private void HideLineSegments(int startSegment, int endSegment){}

    }    //立钻哥哥:public class TeleportArc:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++AllowTeleportWhileAttachedToHand(容许传送时附加在手):默认状况下,咱们不能用一只手来传送东西,将此“AllowTeleportWhileAttachedToHand”组件添加到附加对象上能够绕过该规则

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\AllowTeleportWhileAttachedToHand.cs

//Purpose: Adding this component to an object will allow the player to initiate teleporting while that object is attached to their hand.(立钻哥哥:目的:将这个组件添加到一个对象将容许玩家在该对象与他们的手链接时启动传送

using UnityEngine;

namespace Valve.VR.InteractionSystem{

    public class AllowTeleportWhileAttachedToHand : MonoBehaviour{

        public bool teleportAllowed = true;

        public bool overrideHoverLock = true;

    }    //立钻哥哥:public class AllowTeleportWhileAttachedToHand:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++IgnoreTeleportTrace(忽略传送跟踪):将其添加到带有碰撞体的对象将容许传送跟踪穿透它;另外一种处理方法是将该对象放在TeleportArc不检查的另外一个层上

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\IgnoreTeleportTrace.cs

//Purpose: Allows the teleport arc trace to pass through any colliders on this object.(立钻哥哥:目的:容许传送弧跟踪经过该对象上的任何碰撞器

using UnityEngine;

using System.Collections;

namespace Valve.VR.InteractionSystem{

    public class IgnoreTeleportTrace : MonoBehaviour{

    }    //立钻哥哥:public class IgnoreTeleportTrace:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++Teleporting(Prefab)(传送预制体):这个预制体设置了整个传送系统;拖拽这个预制体到场景中会在游戏中打开传送指针;全部的传送系统的视觉和声音能够经过这个预制的属性来改变

++++TeleportPoint(Prefab)(传送点预制体):将这些添加到场景中,以添加玩家能够传送到的位置

++++立钻哥哥:通过大量的相关知识拓展,貌似没有什么用!毕竟,咱们须要的是实战!实战!实战!!!那咱们接下来操练起来吧!

----首先,咱们直接拖一个预制体(\Assets\SteamVR\InteractionSystem\Teleport\Prefabs\Teleporting.prefab)到场景中,运行一下看看效果吧

----运行很顺利,并且效果也还不错,没有什么明显的bug,能够直接拿来用的,若是想实现传送功能,还须要继续往下操做“十、添加TeleportPoint传送点预制体”和“十一、添加TeleportArea传送区域预制体

++++立钻哥哥:通过上面的操练,这个“Teleporting”预制体仍是比较顺利的运行了,那咱们就来看看这个预制体中的核心代码吧!(核心代码就两个:“Teleport.cs”和“TeleportArc.cs”)

++++[Teleport.cs]:处理全部的传送逻辑!这个解释已经很是明确了,这个脚本很是很是重要呀!

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\Teleport.cs

//Purpose: Handles all the teleport logic.(立钻哥哥:用途:处理全部的传送逻辑.

using UnityEngine;

using UnityEngine.Events;

using System.Collections;

 

namespace Valve.VR.InteractionSystem{

    public class Teleport : MonoBehaviour{

        public SteamVR_Action_Boolean teleportAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(Teleport);

 

        public LayerMask traceLayerMask;

        public LayerMask floorFixupTraceLayerMask;

        public float floorFixupMaximumTraceDistance = 1.0f;

        public Material areaVisibleMaterial;

        public Material areaLockedMaterial;

        public Material areaHighlightedMaterial;

        public Material pointVisibleMaterial;

        public Material pointLockedMaterial;

        public Material pointHighlightedMaterial;

        public Transform destinationReticleTransform;

        public Transform invalidReticleTransform;

        public GameObject playAreaPreviewCorner;

        public GameObject playAreaPreviewSide;

        public Color pointerValidColor;

        public Color pointerInvalidColor;

        public Color pointerLockedColor;

        public bool showPlayAreaMarker = true;

 

        public float teleportFadeTime = 0.1f;

        public float meshFadeTime = 0.2f;

        public float arcDistance = 10.0f;

 

        [Header(Effects(立钻哥哥:效果))]

        public Transform onActivateObjectTransform;

        public Transform onDeactivateObjectTransform;

        public float activateObjectTime = 1.0f;

        public float deactivateObjectTime = 1.0f;

 

        [Header(Audio Sources(立钻哥哥:声音来源))]

        public AudioSource pointerAudioSource;

        public AudioSource loopingAudioSource;

        public AudioSource headAudioSource;

        public AudioSource reticleAudioSource;

 

        [Header(Sounds(立钻哥哥:音效))]

        public AudioClip teleportSound;

        public AudioClip pointerStartSound;

        public AudioClip pointerLoopSound;

        public AudioClip pointerStopSound;

        public AudioClip goodHighlightSound;

        public AudioClip badHighlightSound;

 

        [Header(Debug(立钻哥哥:调试))]

        public bool debugFloor = false;

        public bool showOffsetReticle = false;

        public Transform offsetReticleTransform;

        public MeshRenderer floorDebugSphere;

        public LineRenderer floorDebugLine;

 

        private LineRenderer pointerLineRenderer;

        private GameObject teleportPointerObject;

        private Transform pointerStartTransform;

        private Hand pointerHand = null;

        private Player player = null;

        private TeleportArc teleportArc = null;

 

        private bool visible = false;

 

        private TeleportMarkerBase[] teleportMarkers;

        private TeleportMarkerBase pointedAtTeleportMarker;

        private TeleportMarkerBase teleportingToMarker;

        private Vector3 pointedAtPosition;

        private Vector3 prevPointedAtPosition;

        private bool teleporting = false;

        private float currentFadeTime = 0.0f;

 

        private float meshAlphaPercent = 1.0f;

        private float pointerShowStartTime = 0.0f;

        private float pointerHideStartTime = 0.0f;

        private bool meshFading = false;

        private float fullTintAlpha;

   

        private float invalidReticleMinScale = 0.2f;

        private float invalidReticleMaxScale = 1.0f;

        private float invalidReticleMinScaleDistance = 0.4f;

        private float invalidReticleMaxScaleDistance = 2.0f;

        private Vector3 invalidReticleScale = Vector3.one;

        private Quaternion invalidReticleTargetRotation = Quaternion.identity;

 

        private Transform playAreaPreviewTransform;

        private Transform[] playAreaPreviewCorners;

        private Transform[] playAreaPreviewSides;

 

        private float loopingAudioMaxVolume = 0.0f;

 

        private Coroutine hintCoroutine = null;

 

        private bool originalHoverLockState = false;

        private Interactable originalHoveringInteractable = null;

        private AllowTeleportWhileAttachedToHand allowTeleportWhileAttached = null;

 

        private Vector3 startingFeetOffset = Vector3.zero;

        private bool movedFeetFarEnough = false;

 

        SteamVR_Events.Action chaperoneInfoInitializedAction;

 

        //Events(立钻哥哥:事件)

        public static SteamVR_Events.Event<float> ChangeState = new SteamVR_Events.Event<float>();

        public static SteamVR_Events.Action<float> ChangeSceneAction(UnityAction<float> action){};

        public static SteamVR_Events.Event<TeleportMarkderBase> Player = new SteamVR_Events.Event<TeleportMarkerBase>();

        public static SteamVR_Events.Action<TeleportMarkerBase> PlayerAction(UnityAction<TeleportMarkerBase> actionsss){}

        public static SteamVR_Events.Event<TeleportMarkerBase> PlayerPre = new SteamVR_Events.Event<TeleportMarkerBase>();

        public static SteamVR_Events.Action<TeleportMarkerBase> PlayerPreAction(UnityAction<TeleportMarkerBase> action){}

 

        private static Teleport _instance;

        public static Teleport instance{}

 

        void Awake(){

            _instance = this;

            chaperoneInfoInitializedAction = ChaperoneInfo.InitializedAction(OnChaperoneInfoInitialized);

 

            pointerLineRenderer = GetComponentInChildren<LineRenderer>();

            teleportPointerObject = pointerLineRenderer.gameObject;

    

            int tintColorID = Shader.PropertyToID(_TintColor);

            fullTintAlpha = pointVisibleMaterial.GetColor(tintColorID).a;

 

            teleportArc = GetComponent<TeleportArc>();

            teleportArc.traceLayerMask = traceLayerMask;

 

            loopingAudioMaxVolue = loopingAudioSource.volume;

 

            playAreaPreviewCorner.SetActive(false);

            playAreaPreviewSide.SetActive(false);

 

            float invalidReticleStartingScale = invalidReticleTransform.localScale.x;

            invalidReticleMinScale *= invalidReticleStartingScale;

            invalidReticleMaxScale *= invalidReticleStartingScale;

        }    //立钻哥哥:void Awake(){}

 

        void Start(){

            teleportMarkers = GameObject.FindObjectsOfType<TeleportMarkerBase>();

            HidePointer();

            player = InteractionSystem.Player.instance;

 

            if(player == null){

                Debug.LogError(<b>立钻哥哥:[SteamVR Interaction]</b> Teleport: No Player instance found in map.);

                Destroy(this.gameObject);

                return;

            }

 

            CheckForSpawnPoint();

            Invoke(ShowTeleportHint, 5.0f);

        }    //立钻哥哥:void Start(){}

 

        void OnEnable(){

            chaperoneInfoInitializedAction.enabled = true;

            OnChaperoneInfoInitialized();

        }

 

        void OnDisable(){

            chaperoneInfoInitializedAction.enabled = false;

            HidePointer();

        }

 

        private void CheckForSpawnPoint(){}

        pubic void HideTeleportPointer(){}

        void Update(){}

        private void UpdatePointer(){}

        void FixedUpdate(){}

        private void OnChaperoneInfoInitialized(){}

        private void HidePointer(){}

        private void ShowPointer(Hand newPointerHand, Hand oldPointerHand){}

        private void UpdateTeleportColors(){}

        private void PlayAudioClip(AudioSource source, AudioClip clip){}

        private void PlayPointerHaptic(bool validLocation){}

        private void TryTeleportPlayer(){}

        private void InitiateTeleportFade(){}

        private void TeleportPlayer(){}

        private void HighlightSelected(TeleportMarkerBase hitTeleportMarker){}

        public void ShowTeleportHint(){}

        public void CancelTeleportHint(){}

        private IEnumerator TeleportHintCoroutine(){}

        public bool IsEligibleForTeleport(Hand hand){}

        private bool ShouldOverrideHoverLock(){}

        private bool WasTeleportButtonReleased(Hand hand){}

        private bool IsTeleportButtonDown(Hand hand){}

        private bool WasTeleportButtonPressed(Hand hand){}

        private Transform GetPointerStartTransform(Hand hand){}

    }    //立钻哥哥:public class Teleport:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportArc.cs

//Purpose: Displays the arc lines for teleporting and does the traces.(立钻哥哥:用途:显示用于远程传送的弧线并进行跟踪

using UnityEngine;

 

namespace Valve.VR.InteractionSystem{

    public class TeleportArc : MonoBehaviour{

        public int segmentCount = 60;

        public float thickness = 0.01f;

        public float arcDuration = 3.0f;

        public float segmentBreak = 0.025f;

        public float arcSpeed = 0.2f;

        public Material material;

 

        [HideInInspector]

        public int traceLayerMask = 0;

 

        private LineRenderer[] lineRenderers;

        private float arcTimeOffset = 0.0f;

        private float prevThickness = 0.0f;

        private int prevSegmentCount = 0;

        private bool showArc = true;

        private Vector3 startPos;

        private Vector3 projectileVelocity;

        private bool useGravity = true;

        private Transform arcObjectsTransform;

        private bool arcInvalid = false;

        private float scale = 1;

 

        void Start(){}

        void Update(){}

        private void CreateLineRendererObjects(){}

        public void SetArcData(Vector3 position, Vector3 velocity, bool gravity, bool pointerAtBadAngle){}

        public void Show(){}

        public void Hide(){}

        public bool DrawArc(out RaycastHit hitInfo){}

        private void DrawArcSegment(int index, float startTime, float endTime){}

        public void SetColor(Color color){}

        private float FindProjectileCollision(out RaycastHit hitInfo){}

        public Vector3 GetArcPositionAtTime(float time){}

       private void HideLineSegments(int startSegment, int endSegment){}

    }    //立钻哥哥:public class TeleportArc:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++立钻哥哥:这个“Teleporting”预制体,咱们就先了解到这里,接下来看看“TeleportPoint”和“TeleportArea”预制体吧;

 

 

++十、添加“TeleportPoint”传送点预制体

++++立钻哥哥:在前面咱们剖析了“Teleporting”这个预制体,这个预制体处理系统的全部传送逻辑,是一个很是重要的预制体哟;那这个“TeleportPoint(传送点)”也很是关键,这里提供了传送点功能逻辑

++++从“\Assets\SteamVR\InteractionSystem\Teleport\Prefabs\”下拖入这个预制体“TeleportPoint.prefab”到场景中,就能够生成一个传送点

++++立钻哥哥:上面展现了“TeleportPoint(传送点)”的效果,还不错,没有什么大的问题,那咱们就能够根据这个初步Demo,来展开咱们的想象了,替换成咱们想要的功能和UI

++++\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportPoint.cs

//Purpose: Single location that the player can teleport to.(立钻哥哥:用途:单一的位置,玩家能够传送到.

using UnityEngine;

using UnityEngine.UI;

#if UNITY_EDITOR

    using UnityEditor;

#endif

 

namespace Valve.VR.InteractionSystem{

    public class TeleportPoint : TeleportMarkerBase{

        public enum TeleportPointType{

            MoveToLocation,

            SwitchToNewScene

        };

 

        public TeleportPointType teleportType = TeleportPointType.MoveToLocation;

 

        void Awake(){}

        void Start(){}

        void Update(){}

    }    //立钻哥哥:public class TeleportPoint:TeleportMarkerBase{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++TeleportMarkerBase(传送标记基类):这是全部传送标记的基类;它包含“Teleport”类指望出现的全部Teleport标记中的方法;咱们能够用这个做为基类来建立一个新的传送标记;传送标记能够锁定或解锁,玩家不能传送到锁定的标记

//\Assets\SteamVR\InteractionSystem\Teleport\Scripts\TeleportMarkerBase.cs

//Purpose: Base class for all the objects that the player can teleport to.(立钻哥哥:用途:玩家能够传送到的全部对象的基类.

using UnityEngine;

namespace Valve.VR.InteractionSystem{

    public abstract class TeleportMarkerBase : MonoBehaviour{

        public bool locked = false;

        public bool markerActive = true;

 

        public virtual bool showReticle{}

        public void SetLocked(bool locked){}

        public virtual void TeleportPlayer(Vector3 pointedAtPosition){}

        public abstract void UpdateVisuals();

        public abstract void Highlight(bool highlight);

        public abstract void SetAlpha(float tintAlpha, float alphaPercent);

        public abstract bool ShouldActivate(Vector3 playerPosition);

        public abstract bool ShouldMovePlayer();

    }    //立钻哥哥:public abstract class TeleportMarkerBase:MonoBehaviour{}

}    //立钻哥哥:namespace Valve.VR.InteractionSystem{}

++++[TeleportPoint(传送点)]:这是玩家能够传送到的传送点;当传送到这些东西上时,玩家将会在点的原点进行传送,而无论他们所指向的点在哪里

++++[TeleportPoint(Prefab)(传送点预制体)]:将预制体添加到场景中,以添加玩家能够传送到的位置

 

++++立钻哥哥:这里篇幅有过长了,尚未写完呢!只能分开几篇了!

++++SteamVR2.2.0教程(一)http://www.javashuo.com/article/p-gblmlsya-gp.html

++++SteamVR2.2.0教程(二)http://www.javashuo.com/article/p-fyhwthit-kq.html

 

 

 

【XR游戏开发QQ群:784477094

++立钻哥哥推荐的拓展学习连接(Link_Url)

立钻哥哥推荐的拓展学习连接(Link_Url)

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++++虚拟现实VR资讯: http://www.javashuo.com/article/p-fqrqdjkb-w.html

++++HTC_VIVE开发基础http://www.javashuo.com/article/p-mhcdmelt-bt.html

++++Oculus杂谈http://www.javashuo.com/article/p-unmgvyjw-ce.html

++++Oculus安装使用http://www.javashuo.com/article/p-ulvvimkb-cr.html

++++Unity+SteamVR=>VRhttp://www.javashuo.com/article/p-asetqfsg-da.html

++++Unity减小VR晕眩症http://www.javashuo.com/article/p-cendayuh-dt.html

++++SteamVR简介http://www.javashuo.com/article/p-awcwwcaq-ea.html

++++SteamVR脚本功能分析http://www.javashuo.com/article/p-ajqgwdev-ek.html

++++SteamVR2.0开发指南http://www.javashuo.com/article/p-wgdghzsl-er.html

++++SteamVR2.2.0开发指南http://www.javashuo.com/article/p-hguaxolf-ew.html

++++SteamVR2.2.0快速入门http://www.javashuo.com/article/p-fcmbsvpm-gb.html

++++SteamVR2.2.0交互系统http://www.javashuo.com/article/p-ocssrxuq-gd.html

++++SteamVR2.2.0官方教程http://www.javashuo.com/article/p-gblmlsya-gp.html

++++SteamVR/Extrashttp://www.javashuo.com/article/p-qrebqbra-he.html

++++SteamVR/Inputhttp://www.javashuo.com/article/p-avbvrjff-ga.html

++++OpenXR简介http://www.javashuo.com/article/p-qgsgcamr-eu.html

++++VRTK杂谈http://www.javashuo.com/article/p-gsryrkjk-eb.html

++++VRTK快速入门(杂谈)http://www.javashuo.com/article/p-bgvfnmia-cm.html

++++VRTK官方示例(目录)http://www.javashuo.com/article/p-dsnjffvq-ea.html

++++VRTK代码结构(目录)http://www.javashuo.com/article/p-wfilzqyd-es.html

++++VRTK(SceneResources)http://www.javashuo.com/article/p-ryptqvzl-hm.html

++++VRTK_ControllerEventshttp://www.javashuo.com/article/p-sciqvywx-hv.html

++++VRTK_InteractTouchhttp://www.javashuo.com/article/p-ggucvtwz-hq.html

++++虚拟现实行业应用http://www.javashuo.com/article/p-dtgguvvf-ec.html

++++Steam平台上的VRhttp://www.javashuo.com/article/p-wuvvtohn-bo.html

++++Steam平台热销VRhttp://www.javashuo.com/article/p-uyiidcdy-ba.html

++++VR实验:以太网帧的构成http://www.javashuo.com/article/p-fnfhdcgt-bp.html

++++实验四:存储器扩展实验http://www.javashuo.com/article/p-hutumxis-dd.html

++++FrameVR示例V0913http://www.javashuo.com/article/p-xnlrngai-cw.html

++++FrameVR示例V1003http://www.javashuo.com/article/p-ztazxpkv-bd.html

++++SwitchMachineV1022http://www.javashuo.com/article/p-tqkoklov-s.html

++++PlaySceneManagerV1022http://www.javashuo.com/article/p-tqkoklov-s.html

++++Unity5.x用户手册http://www.javashuo.com/article/p-ufnzpmga-s.html

++++Unity面试题ABChttp://www.javashuo.com/article/p-mwacxwca-gm.html

++++Unity面试题Dhttp://www.javashuo.com/article/p-wuwcrclr-s.html

++++Unity面试题Ehttp://www.javashuo.com/article/p-hmabbtmc-ba.html

++++Unity面试题Fhttp://www.javashuo.com/article/p-olslkfao-cq.html

++++Cocos2dx面试题http://www.javashuo.com/article/p-daozmsii-cz.html

++++禅道[zentao]http://www.javashuo.com/article/p-rqsvjwtk-cz.html

++++Lua快速入门篇(Xlua拓展):http://www.javashuo.com/article/p-rrszijom-cm.html

++++Lua快速入门篇(XLua教程):http://www.javashuo.com/article/p-pduvmusb-ho.html

++++Lua快速入门篇(基础概述)http://www.javashuo.com/article/p-shernvtt-u.html

++++框架知识点http://www.javashuo.com/article/p-eufbowgf-u.html

++++游戏框架(UI框架夯实篇)http://www.javashuo.com/article/p-cvemoigb-cu.html

++++游戏框架(初探篇)http://www.javashuo.com/article/p-zfpoilbc-hy.html

++++.Net框架设计http://www.javashuo.com/article/p-bvqhwwfm-cu.html

++++从零开始学架构http://www.javashuo.com/article/p-xbebwfbh-gd.html

++++设计模式简单整理http://www.javashuo.com/article/p-rngqugib-hg.html

++++专题:设计模式(精华篇)http://www.javashuo.com/article/p-nbohnaya-hw.html

++++U3D小项目参考https://blog.csdn.net/vrunsoftyanlz/article/details/80141811

++++Unity小游戏算法分析http://www.javashuo.com/article/p-stddpwad-eg.html

++++Unity案例(Vehicle)http://www.javashuo.com/article/p-wxnfscgy-dy.html

++++UML类图http://www.javashuo.com/article/p-sxberuew-bm.html

++++PowerDesigner简介http://www.javashuo.com/article/p-deknpwxv-cu.html

++++Unity知识点0001http://www.javashuo.com/article/p-ryvdxxjr-ep.html

++++Unity知识点0008http://www.javashuo.com/article/p-kxgstxls-gu.html

++++U3D_Shader编程(第一篇:快速入门篇)http://www.javashuo.com/article/p-kyppgrac-gz.html

++++U3D_Shader编程(第二篇:基础夯实篇)http://www.javashuo.com/article/p-qkyowtli-hv.html

++++Unity引擎基础http://www.javashuo.com/article/p-beommoeb-ka.html

++++Unity面向组件开发http://www.javashuo.com/article/p-eigmuvut-dt.html

++++Unity物理系统http://www.javashuo.com/article/p-nqvvciwv-kd.html

++++Unity2D平台开发http://www.javashuo.com/article/p-ycaagdtj-hs.html

++++UGUI基础http://www.javashuo.com/article/p-rukxwckw-mc.html

++++UGUI进阶http://www.javashuo.com/article/p-wcatruhq-gt.html

++++UGUI综合http://www.javashuo.com/article/p-dkccmqii-gg.html

++++Unity动画系统基础http://www.javashuo.com/article/p-mbrdouxy-dq.html

++++Unity动画系统进阶http://www.javashuo.com/article/p-aqaqpbkh-bp.html

++++Navigation导航系统http://www.javashuo.com/article/p-dswwllas-t.html

++++Unity特效渲染http://www.javashuo.com/article/p-ckojjyfj-bp.html

++++Unity数据存储http://www.javashuo.com/article/p-bvlzynso-m.html

++++Unity中Sqlite数据库http://www.javashuo.com/article/p-ejutsbxl-ca.html

++++WWW类和协程http://www.javashuo.com/article/p-dbwmhsav-cy.html

++++Unity网络http://www.javashuo.com/article/p-sqrlntgh-dw.html

++++Unity资源加密http://www.javashuo.com/article/p-qbtlzpck-bo.html

++++PhotonServer简介http://www.javashuo.com/article/p-cjotdrlu-z.html

++++编写Photon游戏服务器http://www.javashuo.com/article/p-mrqkaqlj-dn.html

++++C#事件http://www.javashuo.com/article/p-zmwruvql-gm.html

++++C#委托http://www.javashuo.com/article/p-uozpymaf-gh.html

++++C#集合http://www.javashuo.com/article/p-sfqfdqsf-ex.html

++++C#泛型http://www.javashuo.com/article/p-xrttqngo-ee.html

++++C#接口http://www.javashuo.com/article/p-vhlfplgv-dm.html

++++C#静态类https://blog.csdn.net/vrunsoftyanlz/article/details/78630979

++++C#中System.String类http://www.javashuo.com/article/p-olslkfao-cq.html

++++C#数据类型http://www.javashuo.com/article/p-hmabbtmc-ba.html

++++Unity3D默认的快捷键http://www.javashuo.com/article/p-wuwcrclr-s.html

++++游戏相关缩写http://www.javashuo.com/article/p-mwacxwca-gm.html

++++UnityAPI.Rigidbody刚体http://www.javashuo.com/article/p-phaztrtw-w.html

++++UnityAPI.Material材质http://www.javashuo.com/article/p-ntyoqcng-q.html

++++UnityAPI.Android安卓http://www.javashuo.com/article/p-fyyfgkck-q.html

++++UnityAPI.AndroidJNI安卓JNIhttp://www.javashuo.com/article/p-kvxjsnzf-w.html

++++UnityAPI.Transform变换http://www.javashuo.com/article/p-bfgrrhxl-cq.html

++++UnityAPI.WheelCollider轮碰撞器http://www.javashuo.com/article/p-smnaoooi-cn.html

++++UnityAPI.Resources资源http://www.javashuo.com/article/p-utqnokva-bu.html

++++JSON数据结构http://www.javashuo.com/article/p-dljbtddn-g.html

++++CocosStudio快速入门http://www.javashuo.com/article/p-qldbaqqa-v.html

++++Unity企业内训(目录)http://www.javashuo.com/article/p-oefbctlf-mn.html

++++Unity企业内训(第1讲)http://www.javashuo.com/article/p-ehlblkrj-mc.html

++++Unity企业内训(第2讲)http://www.javashuo.com/article/p-tiecmlwc-ma.html

++++Unity企业内训(第3讲)http://www.javashuo.com/article/p-mlpucjnv-ma.html

++++Unity企业内训(第4讲)http://www.javashuo.com/article/p-vfalurum-kz.html

++++Unity企业内训(第5讲)http://www.javashuo.com/article/p-ncrckqey-kv.html

++++Unity企业内训(第6讲)http://www.javashuo.com/article/p-gcrucvtb-ku.html

++++钻哥带您了解产品原型http://www.javashuo.com/article/p-hhgxuwjv-kt.html

++++插件<Obi Rope>http://www.javashuo.com/article/p-rmhegsmj-kr.html

++++计算机组成原理(教材篇)http://www.javashuo.com/article/p-sejaldpf-kr.html

++++5G接入:云计算和雾计算http://www.javashuo.com/article/p-yqdivhsk-km.html

++++云计算通俗讲义http://www.javashuo.com/article/p-rkzxxaay-mc.html

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

--_--VRunSoft:lovezuanzuan--_--ww4ww--_--