using System.Collections; using System.Collections.Generic; using UnityEngine; using Fusion; using Fusion.XR.Host.Rig; namespace Fusion.XR.Host.SimpleHands { public class OSFHandRepresentation : MonoBehaviour, IHandRepresentation { public HandCommand currentCommand; public SkinnedMeshRenderer handMeshRenderer; public Animator handAnimator; [Header("Animation layers and configuration")] public string pinchAnimationParameter = "Pinch"; public string flexAnimationParameter = "Flex"; public string poseAnimationParameter = "Pose"; public string pointAnimationLayer = "Point Layer"; public string thumbAnimationLayer = "Thumb Layer"; public float maxGripToPinch = 0.05f; private void Awake() { if (handMeshRenderer == null) handMeshRenderer = GetComponentInChildren(); if (handAnimator == null) handAnimator = GetComponentInChildren(); if (handAnimator == null) handAnimator = GetComponentInParent(); } public bool IsMeshDisplayed => handMeshRenderer.enabled; public void DisplayMesh(bool shouldDisplay) { if(handMeshRenderer && handMeshRenderer.enabled != shouldDisplay) handMeshRenderer.enabled = shouldDisplay; } public Material SharedHandMaterial => handMeshRenderer != null ? handMeshRenderer.sharedMaterial : null; public virtual void SetHandColor(Color color) { handMeshRenderer.material.color = color; } public virtual void SetHandMaterial(Material material) { handMeshRenderer.sharedMaterial = material; } public void SetHandCommand(HandCommand command) { currentCommand = AnalyseCommand(command); } public virtual HandCommand AnalyseCommand(HandCommand command) { if (command.indexTouchedCommand == 1) { // Index is resting on the button: force a minimal value for trigger command.triggerCommand = 0.5f + command.triggerCommand/2; } if (command.thumbTouchedCommand == 1 && command.triggerCommand >= 0.5f) { // Thumb and index are pressed: should we pinch ? => only if grip is not pressed if (command.gripCommand < maxGripToPinch) { command.pinchCommand = 1f - command.triggerCommand; } } return command; } int pointAnimationLayerIndex = -1; int thumbAnimationLayerIndex = -1; bool layerIndexFound = false; public virtual void ApplyCommand(HandCommand command) { command = AnalyseCommand(command); if (!layerIndexFound) { layerIndexFound = true; pointAnimationLayerIndex = handAnimator.GetLayerIndex(pointAnimationLayer); thumbAnimationLayerIndex = handAnimator.GetLayerIndex(thumbAnimationLayer); } // Apply layers float pointRaisedLayerWeight = 1f - command.triggerCommand; handAnimator.SetLayerWeight(pointAnimationLayerIndex, pointRaisedLayerWeight); float thumbRaisedLayerWeight = 1f - command.thumbTouchedCommand; handAnimator.SetLayerWeight(thumbAnimationLayerIndex, thumbRaisedLayerWeight); // Apply parameters float flexParameterValue = command.gripCommand; handAnimator.SetFloat(flexAnimationParameter, flexParameterValue); float pinchParameterValue = 1f - command.pinchCommand; handAnimator.SetFloat(pinchAnimationParameter, pinchParameterValue); int poseParameterValue = command.poseCommand; handAnimator.SetInteger(poseAnimationParameter, poseParameterValue); } private void Update() { if (!isVisible) return; ApplyCommand(currentCommand); } public bool isVisible { get; set; } = false; private void OnBecameVisible() { isVisible = true; } private void OnBecameInvisible() { isVisible = false; } } }