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();
|
|
}
|
|
}
|
|
}
|
|
} |