117 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| using UnityEngine.XR;
 | |
| 
 | |
| namespace _PROJECT.NewHandPresence
 | |
| {
 | |
|     public class SmartHandPresence : MonoBehaviour
 | |
|     {
 | |
|         public bool showController;
 | |
|         public bool showHand;
 | |
| 
 | |
|         public InputDeviceCharacteristics controllerCharacteristics;
 | |
|         public List<ControllerInformationScriptableObject> controllerInformation;
 | |
| 
 | |
|         private InputDevice _targetDevice;
 | |
|         private GameObject _spawnedController;
 | |
|         private XRControllerAnimator _xrControllerAnimator;
 | |
| 
 | |
|         private GameObject _spawnedHandModel;
 | |
|         private Animator _handAnimator;
 | |
| 
 | |
|         private static readonly int Trigger = Animator.StringToHash("Trigger");
 | |
|         private static readonly int Grip = Animator.StringToHash("Grip");
 | |
| 
 | |
|         // Update is called once per frame
 | |
|         void Update()
 | |
|         {
 | |
|             if (!_targetDevice.isValid)
 | |
|             {
 | |
|                 TryInitialize();
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             UpdateModelVisibility(_spawnedController, showController && _spawnedController, UpdateControllerAnimation);
 | |
|             UpdateModelVisibility(_spawnedHandModel, showHand && _spawnedHandModel, UpdateHandAnimation);
 | |
|         }
 | |
| 
 | |
|         private void UpdateHandAnimation()
 | |
|         {
 | |
|             var triggerValue = GetFeatureValueOrZero(CommonUsages.trigger);
 | |
|             var gripValue = GetFeatureValueOrZero(CommonUsages.grip);
 | |
| 
 | |
|             _handAnimator.SetFloat(Trigger, triggerValue);
 | |
|             _handAnimator.SetFloat(Grip, gripValue);
 | |
|         }
 | |
| 
 | |
|         private float GetFeatureValueOrZero(InputFeatureUsage<float> feature)
 | |
|         {
 | |
|             return _targetDevice.TryGetFeatureValue(feature, out float value) ? value : 0;
 | |
|         }
 | |
| 
 | |
|         private void TryInitialize()
 | |
|         {
 | |
|             var devices = new List<InputDevice>();
 | |
|             InputDevices.GetDevicesWithCharacteristics(controllerCharacteristics, devices);
 | |
| 
 | |
|             Debug.Log("Found devices: " + devices.Count);
 | |
| 
 | |
|             if (devices.Count <= 0) return;
 | |
| 
 | |
|             _targetDevice = devices[0];
 | |
| 
 | |
|             Debug.Log("Found device: " + _targetDevice.name + _targetDevice.characteristics);
 | |
| 
 | |
|             ControllerInformationScriptableObject controllerInfo =
 | |
|                 controllerInformation.Find(x => _targetDevice.name.ToLower().Contains(x.controllerName.ToLower()));
 | |
| 
 | |
|             if (controllerInfo == null) controllerInfo = controllerInformation[0];
 | |
| 
 | |
|             var transform1 = transform.parent; // Right/Left hand direct position
 | |
| 
 | |
|             // --- Spawn hand model first ---
 | |
|             _spawnedHandModel = Instantiate(
 | |
|                 controllerInfo.handPrefab,
 | |
|                 transform1.TransformPoint(Quaternion.Euler(controllerInfo.handRotationOffset) * controllerInfo.handOffset),
 | |
|                 transform1.rotation * Quaternion.Euler(controllerInfo.handRotationOffset),
 | |
|                 transform1);
 | |
|             _handAnimator = _spawnedHandModel.GetComponent<Animator>();
 | |
| 
 | |
|             // --- Find the correct child in the hand prefab ---
 | |
|             Transform attachPoint = null;
 | |
|             if (_spawnedHandModel.name.Contains("Left"))
 | |
|                 attachPoint = _spawnedHandModel.transform.Find("hands:l_hand_world");
 | |
|             else if (_spawnedHandModel.name.Contains("Right"))
 | |
|                 attachPoint = _spawnedHandModel.transform.Find("hands:r_hand_world");
 | |
| 
 | |
|             if (attachPoint == null)
 | |
|             {
 | |
|                 Debug.LogWarning("Attach point not found in hand prefab, defaulting to hand root.");
 | |
|                 attachPoint = _spawnedHandModel.transform;
 | |
|             }
 | |
| 
 | |
|             // --- Spawn controller under the hand ---
 | |
|             _spawnedController = Instantiate(controllerInfo.controllerPrefab, attachPoint);
 | |
|             _spawnedController.transform.localPosition = controllerInfo.controllerOffset;
 | |
|             _spawnedController.transform.localRotation = Quaternion.Euler(controllerInfo.controllerRotationOffset);
 | |
| 
 | |
|             _xrControllerAnimator = _spawnedController.GetComponent<XRControllerAnimator>();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         private void UpdateControllerAnimation()
 | |
|         {
 | |
|             _xrControllerAnimator.UpdateAnimations(_targetDevice);
 | |
|         }
 | |
| 
 | |
|         private static void UpdateModelVisibility(GameObject obj, bool show, Action updateAnimation)
 | |
|         {
 | |
|             obj.SetActive(show);
 | |
|             if (show)
 | |
|             {
 | |
|                 updateAnimation();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |