This commit is contained in:
2026-01-06 17:47:11 +01:00
commit 8423e2b790
1313 changed files with 295355 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
using System.Collections;
using System.Collections.Generic;
namespace UnityEngine.XR.Interaction.Toolkit.Samples.Hands
{
/// <summary>
/// Provides the ability to reset specified objects if they fall below a certain position - designated by this transform's height.
/// </summary>
public class ObjectResetPlane : MonoBehaviour
{
[SerializeField]
[Tooltip("Which objects to reset if falling out of range.")]
List<Transform> m_ObjectsToReset = new List<Transform>();
[SerializeField]
[Tooltip("How often to check if objects should be reset.")]
float m_CheckDuration = 2f;
[SerializeField]
[Tooltip("The object root used to compute local positions relative to. Objects will respawn relative to their position in this transform's hierarchy.")]
Transform m_ObjectRoot = null;
readonly List<Pose> m_OriginalPositions = new List<Pose>();
float m_CheckTimer;
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
protected void Start()
{
foreach (var currentTransform in m_ObjectsToReset)
{
if (currentTransform != null)
{
var position = currentTransform.position;
if (m_ObjectRoot != null)
position = m_ObjectRoot.InverseTransformPoint(currentTransform.position);
m_OriginalPositions.Add(new Pose(position, currentTransform.rotation));
}
else
{
Debug.LogWarning("Objects To Reset contained a null element. Update the reference or delete the array element of the missing object.", this);
m_OriginalPositions.Add(new Pose());
}
}
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
protected void Update()
{
m_CheckTimer -= Time.deltaTime;
if (m_CheckTimer > 0)
return;
m_CheckTimer = m_CheckDuration;
var resetPlane = transform.position.y;
for (var transformIndex = 0; transformIndex < m_ObjectsToReset.Count; transformIndex++)
{
var currentTransform = m_ObjectsToReset[transformIndex];
if (currentTransform == null)
continue;
if (currentTransform.position.y < resetPlane)
{
var originalWorldPosition = m_OriginalPositions[transformIndex].position;
if (m_ObjectRoot != null)
originalWorldPosition = m_ObjectRoot.TransformPoint(originalWorldPosition);
currentTransform.SetPositionAndRotation(originalWorldPosition, m_OriginalPositions[transformIndex].rotation);
var rigidBody = currentTransform.GetComponentInChildren<Rigidbody>();
if (rigidBody != null)
{
StartCoroutine(ResetRigidbodyRoutine(rigidBody));
}
}
}
}
IEnumerator ResetRigidbodyRoutine(Rigidbody body)
{
body.isKinematic = true;
yield return new WaitForFixedUpdate();
body.isKinematic = false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54ce4268a4182384da360e6e2654d3a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
using Unity.XR.CoreUtils.Bindings;
using UnityEngine.XR.Interaction.Toolkit.AffordanceSystem.State;
using UnityEngine.XR.Interaction.Toolkit.Filtering;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
using UnityEngine.XR.Interaction.Toolkit.Utilities.Tweenables.Primitives;
namespace UnityEngine.XR.Interaction.Toolkit.Samples.Hands
{
/// <summary>
/// Animates a blend shape on a SkinnedMeshRenderer based on the interaction strength of a poke.
/// </summary>
public class PokeBlendShapeAnimator : MonoBehaviour
{
[SerializeField]
[Tooltip("The PokeFilter to use to determine the interaction strength.")]
XRPokeFilter m_PokeFilter;
[SerializeField]
[Tooltip("The SkinnedMeshRenderer to animate.")]
SkinnedMeshRenderer m_SkinnedMeshRenderer;
[SerializeField]
[Tooltip("The index of the blend shape to animate.")]
int m_BlendShapeIndex;
[SerializeField]
[Tooltip("The minimum blend shape value.")]
float m_BlendShapeMin;
[SerializeField]
[Tooltip("The maximum blend shape value.")]
float m_BlendShapeMax = 100f;
readonly BindingsGroup m_BindingsGroup = new BindingsGroup();
IXRHoverInteractable m_HoverInteractable;
IXRInteractionStrengthInteractable m_InteractionStrengthInteractable;
#pragma warning disable CS0618 // Type or member is obsolete
readonly FloatTweenableVariable m_TweenableVariable = new FloatTweenableVariable();
#pragma warning restore CS0618 // Type or member is obsolete
float m_TweenTarget;
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void OnEnable()
{
if (m_PokeFilter == null || m_SkinnedMeshRenderer == null)
{
enabled = false;
return;
}
m_HoverInteractable = m_PokeFilter.GetComponent<IXRHoverInteractable>();
m_InteractionStrengthInteractable = m_PokeFilter.GetComponent<IXRInteractionStrengthInteractable>();
m_BindingsGroup.AddBinding(m_PokeFilter.pokeStateData.Subscribe(data =>
{
var blendShapeValue = Mathf.Lerp(m_BlendShapeMin, m_BlendShapeMax, data.interactionStrength);
m_TweenTarget = blendShapeValue;
}));
m_BindingsGroup.AddBinding(m_TweenableVariable.SubscribeAndUpdate(newValue =>
{
m_SkinnedMeshRenderer.SetBlendShapeWeight(m_BlendShapeIndex, newValue);
}));
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void OnDisable()
{
m_BindingsGroup.Clear();
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void Update()
{
m_TweenableVariable.HandleTween(Time.deltaTime * 16f);
if (m_HoverInteractable.interactorsHovering.Count == 0)
return;
var pokeInteractorStrength = 0f;
var largestNonPokeInteractorStrength = 0f;
for (var index = 0; index < m_HoverInteractable.interactorsHovering.Count; ++index)
{
var interactor = m_HoverInteractable.interactorsHovering[index];
var interactionStrength = m_InteractionStrengthInteractable.GetInteractionStrength(interactor);
var isPokeProvider = interactor is IPokeStateDataProvider;
if (isPokeProvider)
{
pokeInteractorStrength = interactionStrength;
}
else
{
largestNonPokeInteractorStrength = Mathf.Max(largestNonPokeInteractorStrength, interactionStrength);
}
}
m_TweenableVariable.target = pokeInteractorStrength > largestNonPokeInteractorStrength ? m_TweenTarget : 0f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 78373ff495dc8234887e0cbdc7140022
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
namespace UnityEngine.XR.Interaction.Toolkit.Samples.Hands
{
/// <summary>
/// Toggles the active state of a GameObject.
/// </summary>
public class ToggleGameObject : MonoBehaviour
{
[SerializeField]
[Tooltip("The GameObject to toggle the active state for.")]
GameObject m_ActivationGameObject;
/// <summary>
/// The GameObject to toggle the active state for.
/// </summary>
public GameObject activationGameObject
{
get => m_ActivationGameObject;
set => m_ActivationGameObject = value;
}
[SerializeField]
[Tooltip("Whether the GameObject is currently active.")]
bool m_CurrentlyActive;
/// <summary>
/// Whether the GameObject is currently active.
/// </summary>
public bool currentlyActive
{
get => m_CurrentlyActive;
set
{
m_CurrentlyActive = value;
activationGameObject.SetActive(m_CurrentlyActive);
}
}
/// <summary>
/// Toggles the active state of the GameObject.
/// </summary>
public void ToggleActiveState()
{
m_CurrentlyActive = !m_CurrentlyActive;
activationGameObject.SetActive(m_CurrentlyActive);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 646ef16ad2fbd1944b40157feffe8574
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
using System;
using UnityEngine.XR.Interaction.Toolkit.Utilities.Tweenables.Primitives;
namespace UnityEngine.XR.Interaction.Toolkit.Samples.Hands
{
/// <summary>
/// Class used to sync the transform of a target game object with this one.
/// </summary>
public class TransformSync : MonoBehaviour
{
[SerializeField]
[Tooltip("Transform to apply this transform's data to.")]
Transform m_TargetTransform;
[SerializeField]
[Range(0f, 30f)]
[Tooltip("Set to 0 for no smoothing. Higher values indicate more smoothing.")]
float m_SmoothFollowSpeed = 8f;
Rigidbody m_Rigidbody;
bool m_HasTransform;
bool m_HasRigidbody;
Transform m_ThisTransform;
#pragma warning disable CS0618 // Type or member is obsolete
readonly Vector3TweenableVariable m_PositionTweenable = new Vector3TweenableVariable();
readonly QuaternionTweenableVariable m_RotationTweenable = new QuaternionTweenableVariable();
#pragma warning restore CS0618 // Type or member is obsolete
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void OnValidate()
{
if (m_TargetTransform != null)
{
transform.localPosition = transform.parent == null
? m_TargetTransform.position
: transform.parent.InverseTransformPoint(m_TargetTransform.position);
}
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void Awake()
{
m_ThisTransform = transform;
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void OnEnable()
{
if (m_TargetTransform == null)
{
enabled = false;
return;
}
m_HasTransform = true;
if (m_TargetTransform.TryGetComponent(out Rigidbody rigidBodyComponent))
{
m_Rigidbody = rigidBodyComponent;
m_HasRigidbody = true;
}
m_PositionTweenable.Value = m_ThisTransform.position;
m_RotationTweenable.Value = m_ThisTransform.rotation;
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void Update()
{
m_PositionTweenable.target = m_ThisTransform.position;
m_RotationTweenable.target = m_ThisTransform.rotation;
var tweenTarget = m_SmoothFollowSpeed > 0f ? m_SmoothFollowSpeed * Time.deltaTime : 1f;
m_PositionTweenable.HandleTween(tweenTarget);
m_RotationTweenable.HandleTween(tweenTarget);
if (!m_HasRigidbody && m_HasTransform)
m_TargetTransform.SetPositionAndRotation(m_PositionTweenable.Value, m_RotationTweenable.Value);
}
/// <summary>
/// See <see cref="MonoBehaviour"/>.
/// </summary>
void FixedUpdate()
{
if (!m_HasRigidbody)
return;
m_Rigidbody.MovePosition(m_PositionTweenable.Value);
m_Rigidbody.MoveRotation(m_RotationTweenable.Value);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f22671673eaaae848b70290eb3a1350c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: