当前位置: 代码迷 >> 综合 >> 使用手柄操作滑动条(Unity / Slider / Htc Vive)
  详细解决方案

使用手柄操作滑动条(Unity / Slider / Htc Vive)

热度:75   发布时间:2024-03-08 06:22:43.0

创建Slider

第一步:创建一个Canvas,右键选择UI,在选择Canvas
在这里插入图片描述

第二步:在Canvas下创建Slider,点击Canvas,右键选择UI,然后选择Slider
在这里插入图片描述

创建交互组件Sphere

点击Slider,右键选择3D Object,然后选择Sphere
在这里插入图片描述
然后移动Sphere的位置,将其移动到Slider子物体的第一行,成为Slider的第一个子物体
在这里插入图片描述

挂载交互脚本

在Slider上需要挂载 SliderControl 脚本,Sphere的移动位置根据自己的需求更改,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;namespace UnityVolumeRendering
{
    public class SliderControl : MonoBehaviour{
    private Slider slider;private Transform sphere;private Removable removable;//public void SetValue(float value)//{
    // slider = GetComponent<Slider>();// slider.value = value;// sphere = transform.GetChild(0);// sphere.localPosition = new Vector3(value * 140 - 70, 0, 0);//}// Use this for initializationvoid Start(){
    slider = GetComponent<Slider>();Debug.Log(slider.value);sphere = transform.GetChild(0);Debug.Log(sphere.name);removable = sphere.GetComponent<Removable>();//sphere.localPosition = Vector3.zero;//slider.value = (float)0.5;}// Update is called once per framevoid Update(){
    if (sphere.localPosition.x >= 70){
    slider.value = (float)1;}else if (sphere.localPosition.x <= -70){
    slider.value = 0;}else{
    slider.value = (sphere.localPosition.x + 70) / 140;}if (!removable.moving){
    if (sphere.localPosition.x >= 70){
    sphere.localPosition = new Vector3(70, 0, 0);}else if (sphere.localPosition.x <= -150){
    sphere.localPosition = new Vector3(-70, 0, 0);}else{
    sphere.localPosition = new Vector3(sphere.localPosition.x, 0, 0);}}}}
}

在Sphere上挂载 Interactable 脚本和 Removable脚本,代码如下:
Interactable

//======= Copyright (c) Valve Corporation, All rights reserved. ===============
//
// Purpose: This object will get hover events and can be attached to the hands
//
//=============================================================================using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;namespace Valve.VR.InteractionSystem
{
    //-------------------------------------------------------------------------public class Interactable : MonoBehaviour{
    [Tooltip("Activates an action set on attach and deactivates on detach")]public SteamVR_ActionSet activateActionSetOnAttach;[Tooltip("Hide the whole hand on attachment and show on detach")]public bool hideHandOnAttach = true;[Tooltip("Hide the skeleton part of the hand on attachment and show on detach")]public bool hideSkeletonOnAttach = false;[Tooltip("Hide the controller part of the hand on attachment and show on detach")]public bool hideControllerOnAttach = false;[Tooltip("The integer in the animator to trigger on pickup. 0 for none")]public int handAnimationOnPickup = 0;[Tooltip("The range of motion to set on the skeleton. None for no change.")]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;[Tooltip("Specify whether you want to snap to the hand's object attachment point, or just the raw hand")]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;// [Tooltip("The skeleton pose to apply when grabbing. Can only set this or handFollowTransform.")][HideInInspector]public SteamVR_Skeleton_Poser skeletonPoser;[Tooltip("Should the rendered hand lock on to and follow the object")]public bool handFollowTransform= true;[Tooltip("Set whether or not you want this interactible to highlight when hovering over it")]public bool highlightOnHover = true;protected MeshRenderer[] highlightRenderers;protected MeshRenderer[] existingRenderers;protected GameObject highlightHolder;protected SkinnedMeshRenderer[] highlightSkinnedRenderers;protected SkinnedMeshRenderer[] existingSkinnedRenderers;protected static Material highlightMat;[Tooltip("An array of child gameObjects to not render a highlight for. Things like transparent parts, vfx, etc.")]public GameObject[] hideHighlight;[Tooltip("Higher is better")]public int hoverPriority = 0;[System.NonSerialized]public Hand attachedToHand;[System.NonSerialized]public List<Hand> hoveringHands = new List<Hand>();public Hand hoveringHand{
    get{
    if (hoveringHands.Count > 0)return hoveringHands[0];return null;}}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(){
    if (highlightMat == null)
#if UNITY_URPhighlightMat = (Material)Resources.Load("SteamVR_HoverHighlight_URP", typeof(Material));
#elsehighlightMat = (Material)Resources.Load("SteamVR_HoverHighlight", typeof(Material));
#endifif (highlightMat == null)Debug.LogError("<b>[SteamVR Interaction]</b> Hover Highlight Material is missing. Please create a material named 'SteamVR_HoverHighlight' and place it in a Resources folder", this);if (skeletonPoser != null){
    if (useHandObjectAttachmentPoint){
    //Debug.LogWarning("<b>[SteamVR Interaction]</b> SkeletonPose and useHandObjectAttachmentPoint both set at the same time. Ignoring useHandObjectAttachmentPoint.");useHandObjectAttachmentPoint = false;}}}protected virtual bool ShouldIgnoreHighlight(Component component){
    return ShouldIgnore(component.gameObject);}protected virtual bool ShouldIgnore(GameObject check){
    for (int ignoreIndex = 0; ignoreIndex < hideHighlight.Length; ignoreIndex++){
    if (check == hideHighlight[ignoreIndex])return true;}return false;}protected virtual void CreateHighlightRenderers(){
    existingSkinnedRenderers = this.GetComponentsInChildren<SkinnedMeshRenderer>(true);highlightHolder = new GameObject("Highlighter");highlightSkinnedRenderers = new SkinnedMeshRenderer[existingSkinnedRenderers.Length];for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++){
    SkinnedMeshRenderer existingSkinned = existingSkinnedRenderers[skinnedIndex];if (ShouldIgnoreHighlight(existingSkinned))continue;GameObject newSkinnedHolder = new GameObject("SkinnedHolder");newSkinnedHolder.transform.parent = highlightHolder.transform;SkinnedMeshRenderer newSkinned = newSkinnedHolder.AddComponent<SkinnedMeshRenderer>();Material[] materials = new Material[existingSkinned.sharedMaterials.Length];for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++){
    materials[materialIndex] = highlightMat;}newSkinned.sharedMaterials = materials;newSkinned.sharedMesh = existingSkinned.sharedMesh;newSkinned.rootBone = existingSkinned.rootBone;newSkinned.updateWhenOffscreen = existingSkinned.updateWhenOffscreen;newSkinned.bones = existingSkinned.bones;highlightSkinnedRenderers[skinnedIndex] = newSkinned;}MeshFilter[] existingFilters = this.GetComponentsInChildren<MeshFilter>(true);existingRenderers = new MeshRenderer[existingFilters.Length];highlightRenderers = new MeshRenderer[existingFilters.Length];for (int filterIndex = 0; filterIndex < existingFilters.Length; filterIndex++){
    MeshFilter existingFilter = existingFilters[filterIndex];MeshRenderer existingRenderer = existingFilter.GetComponent<MeshRenderer>();if (existingFilter == null || existingRenderer == null || ShouldIgnoreHighlight(existingFilter))continue;GameObject newFilterHolder = new GameObject("FilterHolder");newFilterHolder.transform.parent = highlightHolder.transform;MeshFilter newFilter = newFilterHolder.AddComponent<MeshFilter>();newFilter.sharedMesh = existingFilter.sharedMesh;MeshRenderer newRenderer = newFilterHolder.AddComponent<MeshRenderer>();Material[] materials = new Material[existingRenderer.sharedMaterials.Length];for (int materialIndex = 0; materialIndex < materials.Length; materialIndex++){
    materials[materialIndex] = highlightMat;}newRenderer.sharedMaterials = materials;highlightRenderers[filterIndex] = newRenderer;existingRenderers[filterIndex] = existingRenderer;}}protected virtual void UpdateHighlightRenderers(){
    if (highlightHolder == null)return;for (int skinnedIndex = 0; skinnedIndex < existingSkinnedRenderers.Length; skinnedIndex++){
    SkinnedMeshRenderer existingSkinned = existingSkinnedRenderers[skinnedIndex];SkinnedMeshRenderer highlightSkinned = highlightSkinnedRenderers[skinnedIndex];if (existingSkinned != null && highlightSkinned != null && attachedToHand == false){
    highlightSkinned.transform.position = existingSkinned.transform.position;highlightSkinned.transform.rotation = existingSkinned.transform.rotation;highlightSkinned.transform.localScale = existingSkinned.transform.lossyScale;highlightSkinned.localBounds = existingSkinned.localBounds;highlightSkinned.enabled = isHovering && existingSkinned.enabled && existingSkinned.gameObject.activeInHierarchy;int blendShapeCount = existingSkinned.sharedMesh.blendShapeCount;for (int blendShapeIndex = 0; blendShapeIndex < blendShapeCount; blendShapeIndex++){
    highlightSkinned.SetBlendShapeWeight(blendShapeIndex, existingSkinned.GetBlendShapeWeight(blendShapeIndex));}}else if (highlightSkinned != null)highlightSkinned.enabled = false;}for (int rendererIndex = 0; rendererIndex < highlightRenderers.Length; rendererIndex++){
    MeshRenderer existingRenderer = existingRenderers[rendererIndex];MeshRenderer highlightRenderer = highlightRenderers[rendererIndex];if (existingRenderer != null && highlightRenderer != null && attachedToHand == false){
    highlightRenderer.transform.position = existingRenderer.transform.position;highlightRenderer.transform.rotation = existingRenderer.transform.rotation;highlightRenderer.transform.localScale = existingRenderer.transform.lossyScale;highlightRenderer.enabled = isHovering && existingRenderer.enabled && existingRenderer.gameObject.activeInHierarchy;}else if (highlightRenderer != null)highlightRenderer.enabled = false;}}/// <summary>/// Called when a Hand starts hovering over this object/// </summary>protected virtual void OnHandHoverBegin(Hand hand){
    wasHovering = isHovering;isHovering = true;hoveringHands.Add(hand);if (highlightOnHover == true && wasHovering == false){
    CreateHighlightRenderers();UpdateHighlightRenderers();}}/// <summary>/// Called when a Hand stops hovering over this object/// </summary>protected virtual void OnHandHoverEnd(Hand hand){
    wasHovering = isHovering;hoveringHands.Remove(hand);if (hoveringHands.Count == 0){
    isHovering = false;if (highlightOnHover && highlightHolder != null)Destroy(highlightHolder);}}protected virtual void Update(){
    if (highlightOnHover){
    UpdateHighlightRenderers();if (isHovering == false && highlightHolder != null)Destroy(highlightHolder);}}protected float blendToPoseTime = 0.1f;protected float releasePoseBlendTime = 0.2f;protected virtual void OnAttachedToHand(Hand hand){
    if (activateActionSetOnAttach != null)activateActionSetOnAttach.Activate(hand.handType);if (onAttachedToHand != null){
    onAttachedToHand.Invoke(hand);}if (skeletonPoser != null && hand.skeleton != null){
    hand.skeleton.BlendToPoser(skeletonPoser, blendToPoseTime);}attachedToHand = hand;}protected virtual void OnDetachedFromHand(Hand hand){
    if (activateActionSetOnAttach != null){
    if (hand.otherHand == null || hand.otherHand.currentAttachedObjectInfo.HasValue == false ||(hand.otherHand.currentAttachedObjectInfo.Value.interactable != null &&hand.otherHand.currentAttachedObjectInfo.Value.interactable.activateActionSetOnAttach != this.activateActionSetOnAttach)){
    activateActionSetOnAttach.Deactivate(hand.handType);}}if (onDetachedFromHand != null){
    onDetachedFromHand.Invoke(hand);}if (skeletonPoser != null){
    if (hand.skeleton != null)hand.skeleton.BlendToSkeleton(releasePoseBlendTime);}attachedToHand = null;}protected virtual void OnDestroy(){
    isDestroying = true;if (attachedToHand != null){
    attachedToHand.DetachObject(this.gameObject, false);attachedToHand.skeleton.BlendToSkeleton(0.1f);}if (highlightHolder != null)Destroy(highlightHolder);}protected virtual void OnDisable(){
    isDestroying = true;if (attachedToHand != null){
    attachedToHand.ForceHoverUnlock();}if (highlightHolder != null)Destroy(highlightHolder);}}
}

Removable
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR.InteractionSystem;
using Valve.VR;[RequireComponent(typeof(Interactable))]
public class Removable : MonoBehaviour {
          //以直接修改物体世界坐标的方式移动物体,而不是绑定在手柄上,parent不变public bool moving = false;public SteamVR_Action_Boolean trigger;private SteamVR_Behaviour_Pose trackedObj;private Interactable interactable;// Use this for initializationvoid Start () {
    interactable = this.GetComponent<Interactable>();moving = false;}//-------------------------------------------------// Called every Update() while a Hand is hovering over this object//-------------------------------------------------private void HandHoverUpdate(Hand hand){
    trackedObj = hand.GetComponent<SteamVR_Behaviour_Pose>();if (trigger.GetState(trackedObj.inputSource)){
    moving = true;transform.position = hand.transform.position;}else {
    moving = false;}if (moving){
    transform.position = hand.transform.position;}}
}
  相关解决方案