《SteamVR2.2.0官方教程》
《SteamVR2.2.0官方教程》 |
|
版本 |
作者 |
参与者 |
完成日期 |
备注 |
|
SteamVR2.2.0_Tutorials_V01_1.0 |
严立钻 |
|
2019.04.15 |
|
|
|
|
|
|
|
【XR游戏开发QQ群:784477094】
##《SteamVR2.2.0官方教程》发布说明:
++++“SteamVR2.2.0官方教程”:是对“SteamVR2.2.0”的官方教程(Tutorials)梳理总结;(2019年度的重点技术突破点确立为:“SteamVR”)(前面已经有了一个“V2.0”和“V2.2.0”开发指南了:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187,https://blog.csdn.net/VRunSoftYanlz/article/details/88784527;快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579;交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778;这个“官方教程”是基于前面几篇操作指南和快速入门的一个拓展,所以可以先粗略查阅一下这几篇博文;这里重点说明一下:实战是关键,所以官方教程是重中之重,后期还会基于熟悉官方示例的基础上拓展应用到现实应用中,敬请期待!
++++“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开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++++SteamVR2.2.0传送机制:https://blog.csdn.net/VRunSoftYanlz/article/details/89390866
++++SteamVR2.2.0官方教程:https://blog.csdn.net/VRunSoftYanlz/article/details/89324067
##《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开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++++A.1、快速入门(Getting started)
++++A.2、示例场景(Sample scene)
##A.1、快速入门(Getting started)
##A.1、快速入门(Getting started) |
##A.1、快速入门(Getting started)
++++立钻哥哥:交互系统(Interaction System)是游戏的核心,一般是交互系统先行设计开发,基于交互系统再进行游戏交互的设计和情景设计;那我们就从“交互系统”出发,快速入门吧!
++++关于SteamVR的快速入门,可查阅这个链接:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++获取更多关于SteamVR技术知识,可查阅这个分类:https://blog.csdn.net/vrunsoftyanlz/article/category/8582642
++++A.1.1、交互系统(Interaction System)的认知
++++A.1.2、入门指南(Getting started)
###A.1.1、交互系统(Interaction System)的认知
###A.1.1、交互系统(Interaction System)的认知 |
++A.1.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.2、入门指南(Getting Started)
###A.1.2、入门指南(Getting Started) |
++A.1.2、入门指南(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”传送区域预制体;
++1、新建场景
++++立钻哥哥:新建场景;当然,那需要先导入“SteamVR插件”;
++++SteamVR的Unity资源商店链接:https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647
++++SteamVR在Github上的Release:https://github.com/ValveSoftware/steamvr_unity_plugin/releases
++++新建工程后,导入SteamVR插件,那就可以开始新建一个测试场景了:
++2、删除“主摄像机”对象
++++立钻哥哥:删除“主摄像机(Main Camera)”;
++++如果需要做一款VR游戏,需要把摄像机调成VR视角;
++++[方法1]:使用预制的VR摄像机;
++++[方法2]:将普通的摄像机修改成VR摄像机;
++++Tips:比较详细的描述可参考“SteamVR简介”:https://blog.csdn.net/VRunSoftYanlz/article/details/86484254
++3、将“Player”预制体拖放到场景中
++++立钻哥哥:将“Assets/SteamVR/InteractionSystem/Core/Prefabs/”下的“Player.prefab”预制体拖到场景中;这个预制体设置了主要的玩家和手,它还挂钩到所有相关的“SteamVR Input”需要的动作;
++4、戴上头盔观察场景
++++立钻哥哥:现在我们就可以戴上头盔观察一下场景吧,里面有什么呢?估计是一个空白的场景,很可能有控制器呀!
++5、观察“Skeleton Input”控制器
++++立钻哥哥:如果我们的控制器是支持“Skeleton Input”的,操作时会看到双手触摸并按下控制器上的按钮;
++6、添加“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]:当一个附加对象获得焦点时发送,因为之前的焦点对象已经与手分离; +++++++++++++++++++++ //立钻哥哥:我们这里的【6、添加“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”组件实现的效果吧:
++7、添加“Throwable”可抛出组件
++++立钻哥哥:“将Throwable组件添加到对象中,将允许玩家拾取并抛出该物体”,“Throwable”是最基本的交互对象之一;当一只手悬停在这个物体上并按下其中一个抓取按钮(通常是扳机或手柄)时,玩家可以拿起这个物体;当按下按钮时,该对象被附在手上并保持在那里;当按钮被释放时,手中的任何速度都被赋予抛出的物体;这让我们可以创建可以拾取和抛出的基本对象;
++++立钻哥哥:只要把“Throwable”组件加到物体上,这个物体就可以被抛出了!那我们来看一下效果吧:
++++立钻哥哥:现在我们来剖析一下这个神奇的脚本“Throwable.cs”:
|
//
|
【XR游戏开发QQ群:784477094】
++立钻哥哥推荐的拓展学习链接(Link_Url):
|
立钻哥哥推荐的拓展学习链接(Link_Url) |
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++虚拟现实VR资讯: https://blog.csdn.net/VRunSoftYanlz/article/details/89165846
++++HTC_VIVE开发基础:https://blog.csdn.net/VRunSoftYanlz/article/details/81989970
++++Oculus杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82469850
++++Oculus安装使用:https://blog.csdn.net/VRunSoftYanlz/article/details/82718982
++++Unity+SteamVR=>VR:https://blog.csdn.net/VRunSoftYanlz/article/details/88809370
++++Unity减少VR晕眩症:https://blog.csdn.net/VRunSoftYanlz/article/details/89115518
++++SteamVR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86484254
++++SteamVR脚本功能分析:https://blog.csdn.net/VRunSoftYanlz/article/details/86531480
++++SteamVR2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.csdn.net/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.csdn.net/VRunSoftYanlz/article/details/89199778
++++SteamVR2.2.0官方教程:https://blog.csdn.net/VRunSoftYanlz/article/details/89324067
++++SteamVR/Extras:https://blog.csdn.net/VRunSoftYanlz/article/details/86584108
++++SteamVR/Input:https://blog.csdn.net/VRunSoftYanlz/article/details/86601950
++++OpenXR简介:https://blog.csdn.net/VRunSoftYanlz/article/details/85726365
++++VRTK杂谈:https://blog.csdn.net/VRunSoftYanlz/article/details/82562993
++++VRTK快速入门(杂谈):https://blog.csdn.net/VRunSoftYanlz/article/details/82955267
++++VRTK官方示例(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82955410
++++VRTK代码结构(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82780085
++++VRTK(SceneResources):https://blog.csdn.net/VRunSoftYanlz/article/details/82795400
++++VRTK_ControllerEvents:https://blog.csdn.net/VRunSoftYanlz/article/details/83099512
++++VRTK_InteractTouch:https://blog.csdn.net/VRunSoftYanlz/article/details/83120220
++++虚拟现实行业应用:https://blog.csdn.net/VRunSoftYanlz/article/details/88360157
++++Steam平台上的VR:https://blog.csdn.net/VRunSoftYanlz/article/details/88960085
++++Steam平台热销VR:https://blog.csdn.net/VRunSoftYanlz/article/details/89007741
++++VR实验:以太网帧的构成:https://blog.csdn.net/VRunSoftYanlz/article/details/82598140
++++实验四:存储器扩展实验:https://blog.csdn.net/VRunSoftYanlz/article/details/87834434
++++FrameVR示例V0913:https://blog.csdn.net/VRunSoftYanlz/article/details/82808498
++++FrameVR示例V1003:https://blog.csdn.net/VRunSoftYanlz/article/details/83066516
++++SwitchMachineV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++PlaySceneManagerV1022:https://blog.csdn.net/VRunSoftYanlz/article/details/83280886
++++Unity5.x用户手册:https://blog.csdn.net/VRunSoftYanlz/article/details/81712741
++++Unity面试题ABC:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++Unity面试题D:https://blog.csdn.net/VRunSoftYanlz/article/details/78630838
++++Unity面试题E:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity面试题F:https://blog.csdn.net/VRunSoftYanlz/article/details/78630945
++++Cocos2dx面试题:https://blog.csdn.net/VRunSoftYanlz/article/details/78630967
++++禅道[zentao]:https://blog.csdn.net/VRunSoftYanlz/article/details/83964057
++++Lua快速入门篇(Xlua拓展):https://blog.csdn.net/VRunSoftYanlz/article/details/81173818
++++Lua快速入门篇(XLua教程):https://blog.csdn.net/VRunSoftYanlz/article/details/81141502
++++Lua快速入门篇(基础概述):https://blog.csdn.net/VRunSoftYanlz/article/details/81041359
++++框架知识点:https://blog.csdn.net/VRunSoftYanlz/article/details/80862879
++++游戏框架(UI框架夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80781140
++++游戏框架(初探篇):https://blog.csdn.net/VRunSoftYanlz/article/details/80630325
++++.Net框架设计:https://blog.csdn.net/VRunSoftYanlz/article/details/87401225
++++从零开始学架构:https://blog.csdn.net/VRunSoftYanlz/article/details/88095895
++++设计模式简单整理:https://blog.csdn.net/vrunsoftyanlz/article/details/79839641
++++专题:设计模式(精华篇):https://blog.csdn.net/VRunSoftYanlz/article/details/81322678
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++Unity小游戏算法分析:https://blog.csdn.net/VRunSoftYanlz/article/details/87908365
++++Unity案例(Vehicle):https://blog.csdn.net/VRunSoftYanlz/article/details/82355876
++++UML类图:https://blog.csdn.net/vrunsoftyanlz/article/details/80289461
++++PowerDesigner简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86500084
++++Unity知识点0001:https://blog.csdn.net/vrunsoftyanlz/article/details/80302012
++++Unity知识点0008:https://blog.csdn.net/VRunSoftYanlz/article/details/81153606
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372628
++++Unity引擎基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.csdn.net/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.csdn.net/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.csdn.net/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.csdn.net/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.csdn.net/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.csdn.net/vrunsoftyanlz/article/details/79254902
++++Unity资源加密:https://blog.csdn.net/VRunSoftYanlz/article/details/87644514
++++PhotonServer简介:https://blog.csdn.net/VRunSoftYanlz/article/details/86652770
++++编写Photon游戏服务器:https://blog.csdn.net/VRunSoftYanlz/article/details/86682935
++++C#事件:https://blog.csdn.net/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.csdn.net/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.csdn.net/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.csdn.net/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.csdn.net/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.csdn.net/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++UnityAPI.Rigidbody刚体:https://blog.csdn.net/VRunSoftYanlz/article/details/81784053
++++UnityAPI.Material材质:https://blog.csdn.net/VRunSoftYanlz/article/details/81814303
++++UnityAPI.Android安卓:https://blog.csdn.net/VRunSoftYanlz/article/details/81843193
++++UnityAPI.AndroidJNI安卓JNI:https://blog.csdn.net/VRunSoftYanlz/article/details/81879345
++++UnityAPI.Transform变换:https://blog.csdn.net/VRunSoftYanlz/article/details/81916293
++++UnityAPI.WheelCollider轮碰撞器:https://blog.csdn.net/VRunSoftYanlz/article/details/82356217
++++UnityAPI.Resources资源:https://blog.csdn.net/VRunSoftYanlz/article/details/83155518
++++JSON数据结构:https://blog.csdn.net/VRunSoftYanlz/article/details/82026644
++++CocosStudio快速入门:https://blog.csdn.net/VRunSoftYanlz/article/details/82356839
++++Unity企业内训(目录):https://blog.csdn.net/VRunSoftYanlz/article/details/82634668
++++Unity企业内训(第1讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82634733
++++Unity企业内训(第2讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82861180
++++Unity企业内训(第3讲):https://blog.csdn.net/VRunSoftYanlz/article/details/82927699
++++Unity企业内训(第4讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83479776
++++Unity企业内训(第5讲):https://blog.csdn.net/VRunSoftYanlz/article/details/83963811
++++Unity企业内训(第6讲):https://blog.csdn.net/VRunSoftYanlz/article/details/84207696
++++钻哥带您了解产品原型:https://blog.csdn.net/VRunSoftYanlz/article/details/87303828
++++插件<Obi Rope>:https://blog.csdn.net/VRunSoftYanlz/article/details/83963905
++++计算机组成原理(教材篇):https://blog.csdn.net/VRunSoftYanlz/article/details/82719129
++++5G接入:云计算和雾计算:https://blog.csdn.net/VRunSoftYanlz/article/details/88372718
++++云计算通俗讲义:https://blog.csdn.net/VRunSoftYanlz/article/details/88652803
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--ww4ww--_--