【HTC-VIVE】10-Sample Interactable:简单交互实现

简单交互场景:

传送点,桌子,小球,提示Canvas与文字

 

SampleInteractable.png

Interactable 脚本:

可以交互得物体上要添加得脚本组件,用于手柄与之交互。

 

Interactable.png

  • 可设置的属性:

  • Activeate Action Set On Attach : 在附着物体时激活的事件集

  • Hide Hand On Attach : 在附着物体时,隐藏整个手,包括手柄与手的模型,分离时显示
  • Hide Skeleton On Attach :在附着物体时,只隐藏手模型,不包括手柄,分离时显示
  • Hide Controller On Attach : 在附着物体时,只隐藏手柄,不包括手模型,分离时显示

  • Hand Animation On Pickup : 在捡东西时,播放的手的动画
  • Set Range Of Motion On Pickup : 在捡起东西时,在骨骼上设置运动变化
  • Use Hand Object Attachment Point : 指定使用手的附着物体的位置点,还是直接使用手的位置作为挂载点

  • Hand Follow Transform : 想要手附着在某物上,并跟随其移动,指定该位置
  • Hand Follow Transform Position : 手跟随物体的位置移动
  • Hand Follow Transform Rotation : 手跟随物体的旋转进行旋转
  • Highlight On Hover : 可交互物体,在被手悬停触碰时,是否 外发光 高亮显示

  • Hide Highlight : 一些子物体,不高亮显示,例如:透明物体,VFX特效等

可访问的属性或方法:

  • attached To Hand : 获取该交互物体附着的手(返回 Hand)
  • isDestroying : 只读,获取该交互物体是否销毁中(返回 bool)
  • isHovering :只读,获取该交互物体是否被手悬停触碰状态中(返回 bool)
  • wasHovering : 只读,获取该交互物体是否被手悬停触碰(返回bool)


Sample Interactable 脚本:

1、该脚本是自定义脚本,可以在内部处理相关交互事件

2、内部这些方法的调用,都是Hand 脚步通过 SendMessage()方式来调用,因此内部的方法名必须与Hand中的名称一致,并且都有Hand类型参数传递,不要求都(声明)有接受者。

例如Hand脚本中:

Hand.png

 


在可交互的,附着的物体上可以处理的消息有:

  • OnHandHoverBegin( Hand hand ) : -----当手开始悬停在可交互物体上,被调用一次
  • OnHandHoverEnd( Hand hand ) : -----当手结束悬停在可交互物体上,被调用一次
  • HandHoverUpdate( Hand hand ) : -----当手一直悬停在可交互物体上,被每帧调用

  • OnAttachedToHand( Hand hand ) : -----当可交互物体刚被手抓取附着时,被调用一次
  • OnDetachedFromHand( Hand hand ) : -----当可交互物体刚被手释放分离时,被调用一次
  • HandAttachedUpdate( Hand hand ) : -----当可交互物体刚被手一直抓取附着时,被每帧调用

  • OnHandFocusAcquired( Hand hand ): -----当附加的GameObject成为主要附加对象时调用调用一次(就是说附加了很多物体到附加物栈中,到该物体成为栈顶时,调用一次)
  • OnHandFocusLost( Hand hand ) : ----当这个主要附加GameObject不再是栈顶对象时调用一次

SampleInteractable:

using UnityEngine;
using Valve.VR.InteractionSystem;

/// <summary>
/// 简单的交互
/// </summary>
public class SampleInteractable : MonoBehaviour {

    private TextMesh textMesh;//显示文字,输出状态

    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()
    {
        textMesh = GetComponentInChildren<TextMesh>();
        textMesh.text = "无手柄悬停!";

        interactable = this.GetComponent<Interactable>();
    }



    //-------------------------------------------------
    // 当手开始悬停在可交互物体上,被调用一次
    //-------------------------------------------------
    private void OnHandHoverBegin(Hand hand)
    {
        textMesh.text = "正在悬停的手柄: " + hand.name;
    }


    //-------------------------------------------------
    // 当手结束悬停在可交互物体上,被调用一次
    //-------------------------------------------------
    private void OnHandHoverEnd(Hand hand)
    {
        textMesh.text = "无手柄悬停!";
    }


    //-------------------------------------------------
    // 当手一直悬停在可交互物体上,被每帧调用
    //-------------------------------------------------
    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 OnAttachedToHand(Hand hand)
    {
        textMesh.text = "球体附着在:" + hand.name;
        attachTime = Time.time;
    }


    //-------------------------------------------------
    // 当可交互物体刚被手释放分离时,被调用一次
    //-------------------------------------------------
    private void OnDetachedFromHand(Hand hand)
    {
        textMesh.text = "球体从 " + hand.name+" 分离!";
    }



    //-------------------------------------------------
    //当可交互物体刚被手一直抓取附着时,被每帧调用
    //-------------------------------------------------
    private void HandAttachedUpdate(Hand hand)
    {
        textMesh.text = "球体附着在:" + hand.name + "\n附着时间: " + (Time.time - attachTime).ToString("F2");
    }


    //-------------------------------------------------
    // 当附加的GameObject成为主要附加对象时调用调用一次(就是说附加了很多物体到附加物栈中,到该物体成为栈顶时,调用一次)
    //-------------------------------------------------
    private void OnHandFocusAcquired(Hand hand)
    {
    }


    //-------------------------------------------------
    // 当这个主要附加GameObject不再是栈顶对象时调用一次
    //-------------------------------------------------
    private void OnHandFocusLost(Hand hand)
    {
    }

}

注:记住引入命名空间:using Valve.VR.InteractionSystem; 否则无法使用相关的类。


原文 https://www.jianshu.com/p/55293a49e86b

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值