Initialer Upload neues Unity-Projekt

This commit is contained in:
Daniel Ocks
2025-07-21 09:11:14 +02:00
commit eeca72985b
14558 changed files with 1508140 additions and 0 deletions

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Oculus.Interaction.Input;
using System.Collections.Generic;
using UnityEngine;
namespace Oculus.Interaction.Samples.PalmMenu
{
/// <summary>
/// Filters to one set of GameObjects or the other, depending on which hand is the user's dominant hand.
/// </summary>
public class DominantHandGameObjectFilter : MonoBehaviour, IGameObjectFilter
{
[SerializeField, Interface(typeof(IHand))]
private Object _leftHand;
[SerializeField]
private GameObject[] _leftHandedGameObjects;
[SerializeField]
private GameObject[] _rightHandedGameObjects;
private IHand LeftHand { get; set; }
private readonly HashSet<GameObject> _leftHandedGameObjectSet =
new HashSet<GameObject>();
private readonly HashSet<GameObject> _rightHandedGameObjectSet =
new HashSet<GameObject>();
protected virtual void Start()
{
foreach (var go in _leftHandedGameObjects)
{
_leftHandedGameObjectSet.Add(go);
}
foreach (var go in _rightHandedGameObjects)
{
_rightHandedGameObjectSet.Add(go);
}
LeftHand = _leftHand as IHand;
}
public bool Filter(GameObject go)
{
if (LeftHand.IsDominantHand)
{
return _leftHandedGameObjectSet.Contains(go);
}
else
{
return _rightHandedGameObjectSet.Contains(go);
}
}
}
}

View File

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

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Oculus.Interaction.Input;
using UnityEngine;
namespace Oculus.Interaction.Samples.PalmMenu
{
/// <summary>
/// Matches the position and rotation of the user's dominant hand in world space. Normally this
/// sort of behavior is done using the transform hierarchy, but in this case doing it via a script
/// is cleaner as it (1) allows us to avoid nesting elements under the hand prefab itself and (2)
/// allows the behavior to easily swap between hands depending on which hand is dominant. This
/// also provides a convenient location for the rotation math that keeps the menu aligned "y-up"
/// while still facing the "aim point" and located at the "anchor point." The default anchor- and
/// aim-point values roughly center the menu just above the palms, facing away from the hands.
/// </summary>
public class MatchNonDominantPalmWorldSpaceTransform : MonoBehaviour
{
[SerializeField, Interface(typeof(IHand))]
private Object _leftHand;
[SerializeField, Interface(typeof(IHand))]
private Object _rightHand;
[SerializeField]
private Vector3 _leftAnchorPoint = new Vector3(-0.0608603321f, 0.00953984447f, 0.000258127693f);
[SerializeField]
private Vector3 _leftAimPoint = new Vector3(-0.0749258399f, 0.0893092677f, 0.000258127693f);
[SerializeField]
private Vector3 _rightAnchorPoint = new Vector3(0.0652603358f, -0.011439844f, -0.00455812784f);
[SerializeField]
private Vector3 _rightAimPoint = new Vector3(0.0793258473f, -0.0912092775f, -0.00455812784f);
private IHand LeftHand { get; set; }
private IHand RightHand { get; set; }
protected virtual void Awake()
{
LeftHand = _leftHand as IHand;
RightHand = _rightHand as IHand;
}
private void Update()
{
var anchor = LeftHand.IsDominantHand ? _rightAnchorPoint : _leftAnchorPoint;
var aim = LeftHand.IsDominantHand ? _rightAimPoint : _leftAimPoint;
var hand = LeftHand.IsDominantHand ? RightHand : LeftHand;
Pose wristPose;
if (hand.GetJointPose(HandJointId.HandWristRoot, out wristPose))
{
var anchorPose = new Pose(anchor, Quaternion.identity).GetTransformedBy(wristPose);
var aimPose = new Pose(aim, Quaternion.identity).GetTransformedBy(wristPose);
this.transform.SetPositionAndRotation(anchorPose.position, Quaternion.LookRotation((aimPose.position - anchorPose.position).normalized));
}
}
}
}

View File

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

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using UnityEngine;
namespace Oculus.Interaction.Samples.PalmMenu
{
/// <summary>
/// Example of a bespoke behavior created to control a particular palm menu. This menu primarily controls the swiping behavior,
/// showing and hiding various options and controlling the pagination dots depending on the state of the menu. Note that, for
/// buttons with several possible icons, the states of those buttons are controlled by the PalmMenuExampleButtonHandlers script,
/// which manages the state of the various handlers.
/// </summary>
public class PalmMenuExample : MonoBehaviour
{
[SerializeField]
private PokeInteractable _menuInteractable;
[SerializeField]
private GameObject _menuParent;
[SerializeField]
private RectTransform _menuPanel;
[SerializeField]
private RectTransform[] _buttons;
[SerializeField]
private RectTransform[] _paginationDots;
[SerializeField]
private RectTransform _selectionIndicatorDot;
[SerializeField]
private AnimationCurve _paginationButtonScaleCurve;
[SerializeField]
private float _defaultButtonDistance = 50f;
[SerializeField]
private AudioSource _paginationSwipeAudio;
[SerializeField]
private AudioSource _showMenuAudio;
[SerializeField]
private AudioSource _hideMenuAudio;
private int _currentSelectedButtonIdx;
private void Start()
{
_currentSelectedButtonIdx = CalculateNearestButtonIdx();
_selectionIndicatorDot.position = _paginationDots[_currentSelectedButtonIdx].position;
_menuParent.SetActive(false);
}
private void Update()
{
var nearestButtonIdx = CalculateNearestButtonIdx();
if (nearestButtonIdx != _currentSelectedButtonIdx)
{
_currentSelectedButtonIdx = nearestButtonIdx;
_paginationSwipeAudio.Play();
_selectionIndicatorDot.position = _paginationDots[_currentSelectedButtonIdx].position;
}
if (_menuInteractable.State != InteractableState.Select)
{
LerpToButton();
}
}
private int CalculateNearestButtonIdx()
{
var nearestButtonIdx = 0;
var nearestDistance = float.PositiveInfinity;
for (int idx = 0; idx < _buttons.Length; ++idx)
{
var deltaX = _buttons[idx].localPosition.x + _menuPanel.anchoredPosition.x;
var adjacentIdx = deltaX < 0f ? idx + 1 : idx - 1;
var distanceX = Mathf.Abs(deltaX);
if (distanceX < nearestDistance)
{
nearestButtonIdx = idx;
nearestDistance = distanceX;
}
var normalizingDistance = _defaultButtonDistance;
if (adjacentIdx >= 0 && adjacentIdx < _buttons.Length)
{
normalizingDistance = Mathf.Abs(_buttons[adjacentIdx].localPosition.x - _buttons[idx].localPosition.x);
}
var scale = _paginationButtonScaleCurve.Evaluate(distanceX / normalizingDistance);
_buttons[idx].localScale = scale * Vector3.one;
}
return nearestButtonIdx;
}
private void LerpToButton()
{
var nearestX = _buttons[0].localPosition.x;
var nearestDistance = Mathf.Abs(nearestX + _menuPanel.anchoredPosition.x);
for (int idx = 1; idx < _buttons.Length; ++idx)
{
var x = _buttons[idx].localPosition.x;
var distance = Mathf.Abs(x + _menuPanel.anchoredPosition.x);
if (distance < nearestDistance)
{
nearestX = x;
nearestDistance = distance;
}
}
const float t = 0.2f;
_menuPanel.anchoredPosition = Vector2.Lerp(_menuPanel.anchoredPosition, new Vector2(-nearestX, 0f), t);
}
/// <summary>
/// Show/hide the menu.
/// </summary>
public void ToggleMenu()
{
if (_menuParent.activeSelf)
{
_hideMenuAudio.Play();
_menuParent.SetActive(false);
}
else
{
_showMenuAudio.Play();
_menuParent.SetActive(true);
}
}
}
}

View File

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

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using TMPro;
using UnityEngine;
namespace Oculus.Interaction.Samples.PalmMenu
{
/// <summary>
/// Example of a bespoke behavior created to react to a particular palm menu. This controls the state
/// of the object that responds to the menu, but also parts of the menu itself, specifically those
/// which depend on the state of the controlled object (swappable icons, various text boxes, etc.).
/// </summary>
public class PalmMenuExampleButtonHandlers : MonoBehaviour
{
[SerializeField]
private GameObject _controlledObject;
[SerializeField]
private Color[] _colors;
[SerializeField]
private GameObject _rotationEnabledIcon;
[SerializeField]
private GameObject _rotationDisabledIcon;
[SerializeField]
private float _rotationLerpSpeed = 1f;
[SerializeField]
private TMP_Text _rotationDirectionText;
[SerializeField]
private string[] _rotationDirectionNames;
[SerializeField]
private GameObject[] _rotationDirectionIcons;
[SerializeField]
private Quaternion[] _rotationDirections;
[SerializeField]
private TMP_Text _elevationText;
[SerializeField]
private float _elevationChangeIncrement;
[SerializeField]
private float _elevationChangeLerpSpeed = 1f;
[SerializeField]
private TMP_Text _shapeNameText;
[SerializeField]
private string[] _shapeNames;
[SerializeField]
private Mesh[] _shapes;
private int _currentColorIdx;
private bool _rotationEnabled;
private int _currentRotationDirectionIdx;
private Vector3 _targetPosition;
private int _currentShapeIdx;
private void Start()
{
_currentColorIdx = _colors.Length;
CycleColor();
_rotationEnabled = false;
ToggleRotationEnabled();
_currentRotationDirectionIdx = _rotationDirections.Length;
CycleRotationDirection();
_targetPosition = _controlledObject.transform.position;
IncrementElevation(true);
IncrementElevation(false);
_currentShapeIdx = _shapes.Length;
CycleShape(true);
}
private void Update()
{
if (_rotationEnabled)
{
var rotation = Quaternion.Slerp(Quaternion.identity, _rotationDirections[_currentRotationDirectionIdx], _rotationLerpSpeed * Time.deltaTime);
_controlledObject.transform.rotation = rotation * _controlledObject.transform.rotation;
}
_controlledObject.transform.position = Vector3.Lerp(_controlledObject.transform.position, _targetPosition, _elevationChangeLerpSpeed * Time.deltaTime);
}
/// <summary>
/// Change the color of the controlled object to the next in the list of allowed colors, looping if the end of the list is reached.
/// </summary>
public void CycleColor()
{
_currentColorIdx += 1;
if (_currentColorIdx >= _colors.Length)
{
_currentColorIdx = 0;
}
_controlledObject.GetComponent<Renderer>().material.SetColor("_Color", _colors[_currentColorIdx]);
}
/// <summary>
/// Toggle whether or not rotation is enabled, and set the icon of the controlling button to display what will happen next time the button is pressed.
/// </summary>
public void ToggleRotationEnabled()
{
_rotationEnabled = !_rotationEnabled;
_rotationEnabledIcon.SetActive(!_rotationEnabled);
_rotationDisabledIcon.SetActive(_rotationEnabled);
}
/// <summary>
/// Change the rotation direction of the controlled object to the next in the list of allowed directions, looping if the end of the list is reached.
/// Set the icon of the controlling button to display what will happen next time the button is pressed.
/// </summary>
public void CycleRotationDirection()
{
Debug.Assert(_rotationDirectionNames.Length == _rotationDirections.Length);
Debug.Assert(_rotationDirectionNames.Length == _rotationDirectionIcons.Length);
_currentRotationDirectionIdx += 1;
if (_currentRotationDirectionIdx >= _rotationDirections.Length)
{
_currentRotationDirectionIdx = 0;
}
int nextRotationDirectionIdx = _currentRotationDirectionIdx + 1;
if (nextRotationDirectionIdx >= _rotationDirections.Length)
{
nextRotationDirectionIdx = 0;
}
_rotationDirectionText.text = _rotationDirectionNames[nextRotationDirectionIdx];
for (int idx = 0; idx < _rotationDirections.Length; ++idx)
{
_rotationDirectionIcons[idx].SetActive(idx == nextRotationDirectionIdx);
}
}
/// <summary>
/// Change the target elevation of the controlled object in the requested direction, within the limits [0.2, 2].
/// Set the text to display the new target elevation.
/// </summary>
public void IncrementElevation(bool up)
{
float increment = _elevationChangeIncrement;
if (!up)
{
increment *= -1f;
}
_targetPosition = new Vector3(_targetPosition.x, Mathf.Clamp(_targetPosition.y + increment, 0.2f, 2f), _targetPosition.z);
_elevationText.text = "Elevation: " + _targetPosition.y.ToString("0.0");
}
/// <summary>
/// Change the shape of the controlled object to the next or previous in the list of allowed shapes, depending on the requested direction, looping beyond the bounds of the list.
/// Set the text to display the name of the current shape.
/// </summary>
public void CycleShape(bool cycleForward)
{
Debug.Assert(_shapeNames.Length == _shapes.Length);
_currentShapeIdx += cycleForward ? 1 : -1;
if (_currentShapeIdx >= _shapes.Length)
{
_currentShapeIdx = 0;
}
else if (_currentShapeIdx < 0)
{
_currentShapeIdx = _shapes.Length - 1;
}
_shapeNameText.text = _shapeNames[_currentShapeIdx];
_controlledObject.GetComponent<MeshFilter>().mesh = _shapes[_currentShapeIdx];
}
}
}

View File

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