Initial commit

This commit is contained in:
Thorbjoern
2025-05-26 00:46:28 +02:00
commit e5bca03433
3896 changed files with 1434297 additions and 0 deletions
@@ -0,0 +1,202 @@
using System;
using UnityEngine;
namespace Unity.VRTemplate
{
/// <summary>
/// Draws a bezier curve from a starting point transform to an end point transform
/// </summary>
public class BezierCurve : MonoBehaviour
{
/// <summary>
/// If the view scale changes more than this amount, then the line width will be updated causing the line to be rebuilt.
/// </summary>
const float k_ViewerScaleChangeThreshold = 0.1f;
/// <summary>
/// The time within the frame that the curve will be updated.
/// </summary>
/// <seealso cref="UnityEngine.XR.Interaction.Toolkit.XRBaseController.UpdateType"/>
public enum UpdateType
{
/// <summary>
/// Sample at both update and directly before rendering. For smooth tracking,
/// we recommend using this value as it will provide the lowest input latency for the device.
/// </summary>
UpdateAndBeforeRender,
/// <summary>
/// Only sample input during the update phase of the frame.
/// </summary>
Update,
/// <summary>
/// Only sample input directly before rendering.
/// </summary>
BeforeRender,
}
#pragma warning disable 649
[SerializeField, Tooltip("The time within the frame that the curve will be updated. If this Bezier Curve is attached to a transform that is updating before render, then enabling updates in Before Render will keep the line connected without delay.")]
UpdateType m_UpdateTrackingType = UpdateType.Update;
[SerializeField, Tooltip("The transform that determines the position, handle rotation, and handle scale of the start point of the bezier curve.")]
Transform m_StartPoint;
[SerializeField, Tooltip("The transform that determines the position, handle rotation, and handle scale of the end point of the bezier curve.")]
Transform m_EndPoint;
[SerializeField, Tooltip("Controls the scale factor of the curve's start bezier handle.")]
float m_CurveFactorStart = 1.0f;
[SerializeField, Tooltip("Controls the scale factor of the curve's end bezier handle.")]
float m_CurveFactorEnd = 1.0f;
[SerializeField, Tooltip("Controls the number of segments used to draw the curve.")]
int m_SegmentCount = 50;
[SerializeField, Tooltip("When enabled, the line color gradient will be animated so that an opaque part travels along the line.")]
bool m_Animate;
[SerializeField, Tooltip("If animated, this controls the speed that the animation of the line.")]
float m_AnimSpeed = 0.25f;
[SerializeField, Tooltip("If animated, this color will be the main opaque color of the gradient")]
Color m_GradientKeyColor = new Color(0.1254902f, 0.5882353f, 0.9529412f);
[SerializeField, Tooltip("The line renderer that will draw the curve. If not set it will find a line renderer on this GameObject.")]
LineRenderer m_LineRenderer;
#pragma warning restore 649
Vector3[] m_ControlPoints = new Vector3[4];
float m_Time;
float m_LineWidth;
float m_LastViewerScale;
Vector3 m_LastStartPosition;
Vector3 m_LastEndPosition;
//IProvidesViewerScale IFunctionalitySubscriber<IProvidesViewerScale>.provider { get; set; }
void Awake()
{
if (m_LineRenderer == null)
m_LineRenderer = GetComponent<LineRenderer>();
m_LineWidth = m_LineRenderer.startWidth;
}
void OnEnable()
{
DrawCurve();
Application.onBeforeRender += OnBeforeRender;
}
void OnDisable()
{
Application.onBeforeRender -= OnBeforeRender;
}
void OnBeforeRender()
{
if (m_UpdateTrackingType == UpdateType.BeforeRender || m_UpdateTrackingType == UpdateType.UpdateAndBeforeRender)
DrawCurve();
}
void Update()
{
if (m_UpdateTrackingType == UpdateType.Update || m_UpdateTrackingType == UpdateType.UpdateAndBeforeRender)
DrawCurve();
if (m_Animate)
{
AnimateCurve();
}
}
/// <summary>
/// Updates the line points to draw the bezier curve.
/// </summary>
[ContextMenu("Draw")]
public void DrawCurve()
{
var startPointPosition = m_StartPoint.position;
var endPointPosition = m_EndPoint.position;
if (startPointPosition == m_LastStartPosition &&
endPointPosition == m_LastEndPosition)
return; // Return early if the start and end have not changed to avoid recalculating the curve
var dist = Vector3.Distance(startPointPosition, endPointPosition);
m_ControlPoints[0] = startPointPosition;
m_ControlPoints[1] = startPointPosition + (m_StartPoint.right * (dist * m_CurveFactorStart));
m_ControlPoints[2] = endPointPosition - (m_EndPoint.right * (dist * m_CurveFactorEnd));
m_ControlPoints[3] = endPointPosition;
int segmentCount;
const float smallestCurveLength = 0.0125f;
if (Vector3.Distance(startPointPosition, endPointPosition) < (smallestCurveLength * m_LastViewerScale))
{
segmentCount = 2;
}
else
{
segmentCount = m_SegmentCount;
}
m_LineRenderer.positionCount = segmentCount + 1;
m_LineRenderer.SetPosition(0, m_ControlPoints[0]);
for (var i = 1; i <= segmentCount; i++)
{
var t = i / (float)segmentCount;
var pixel = CalculateCubicBezierPoint(t, m_ControlPoints[0], m_ControlPoints[1], m_ControlPoints[2], m_ControlPoints[3]);
m_LineRenderer.SetPosition(i, pixel);
}
m_LastStartPosition = startPointPosition;
m_LastEndPosition = endPointPosition;
}
static Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
var u = 1 - t;
var tt = t * t;
var uu = u * u;
var uuu = uu * u;
var ttt = tt * t;
var p = uuu * p0;
p += 3 * uu * t * p1;
p += 3 * u * tt * p2;
p += ttt * p3;
return p;
}
void AnimateCurve()
{
var newGrad = new Gradient();
var colorKeys = new GradientColorKey[1];
var alphaKeys = new GradientAlphaKey[2];
var colorKey = new GradientColorKey(m_GradientKeyColor, 0f);
colorKeys[0] = colorKey;
var alphaKeyStart = new GradientAlphaKey(.25f, m_Time);
var alphaKeyEnd = new GradientAlphaKey(1f, 1f);
alphaKeys[0] = alphaKeyStart;
alphaKeys[1] = alphaKeyEnd;
newGrad.SetKeys(colorKeys, alphaKeys);
newGrad.mode = GradientMode.Blend;
m_LineRenderer.colorGradient = newGrad;
m_Time += (Time.unscaledDeltaTime * m_AnimSpeed);
if (m_Time >= 1f)
m_Time = 0f;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72fb4b8d89bc26347a49177acaa93913
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,129 @@
using System.Collections;
using UnityEngine;
namespace Unity.VRTemplate
{
/// <summary>
/// Callout used to display information like world and controller tooltips.
/// </summary>
public class Callout : MonoBehaviour
{
[SerializeField, Tooltip("Whether Gaze Callout is used.")]
bool m_UseGazeCallout = true;
[SerializeField]
[Tooltip("The tooltip Transform associated with this Callout.")]
Transform m_LazyTooltip;
[SerializeField]
[Tooltip("The line curve GameObject associated with this Callout.")]
GameObject m_Curve;
[SerializeField]
[Tooltip("The required time to dwell on this callout before the tooltip and curve are enabled.")]
float m_DwellTime = 1f;
[SerializeField]
[Tooltip("Whether the associated tooltip will be unparented on Start.")]
bool m_Unparent = true;
[SerializeField]
[Tooltip("Whether the associated tooltip and curve will be disabled on Start.")]
bool m_TurnOffAtStart = true;
bool m_Gazing = false;
Coroutine m_StartCo;
Coroutine m_EndCo;
void Start()
{
if (!m_UseGazeCallout)
{
DisableCallout();
return;
}
if (m_Unparent)
{
if (m_LazyTooltip != null)
m_LazyTooltip.SetParent(null);
}
if (m_TurnOffAtStart)
{
if (m_LazyTooltip != null)
m_LazyTooltip.gameObject.SetActive(false);
if (m_Curve != null)
m_Curve.SetActive(false);
}
}
public void GazeHoverStart()
{
if (!m_UseGazeCallout)
{
DisableCallout();
return;
}
m_Gazing = true;
if (m_StartCo != null)
StopCoroutine(m_StartCo);
if (m_EndCo != null)
StopCoroutine(m_EndCo);
m_StartCo = StartCoroutine(StartDelay());
}
public void GazeHoverEnd()
{
if (!m_UseGazeCallout)
{
DisableCallout();
return;
}
m_Gazing = false;
m_EndCo = StartCoroutine(EndDelay());
}
IEnumerator StartDelay()
{
yield return new WaitForSeconds(m_DwellTime);
if (m_Gazing)
TurnOnStuff();
}
IEnumerator EndDelay()
{
if (!m_Gazing)
TurnOffStuff();
yield return null;
}
void TurnOnStuff()
{
if (m_LazyTooltip != null)
m_LazyTooltip.gameObject.SetActive(true);
if (m_Curve != null)
m_Curve.SetActive(true);
}
void TurnOffStuff()
{
if (m_LazyTooltip != null)
m_LazyTooltip.gameObject.SetActive(false);
if (m_Curve != null)
m_Curve.SetActive(false);
}
void DisableCallout()
{
if (m_StartCo != null)
StopCoroutine(m_StartCo);
if (m_EndCo != null)
StopCoroutine(m_EndCo);
TurnOffStuff();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16809ed3baa3d2341b75ec4c0aa874d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
using UnityEngine;
namespace Unity.VRTemplate
{
/// <summary>
/// Makes this object face a target smoothly and along specific axes
/// </summary>
public class TurnToFace : MonoBehaviour
{
#pragma warning disable 649
public Transform faceTarget
{
get => m_FaceTarget;
set => m_FaceTarget = value;
}
[SerializeField]
[Tooltip("Target to face towards. If not set, this will default to the main camera")]
Transform m_FaceTarget;
[SerializeField]
[Tooltip("Speed to turn")]
float m_TurnToFaceSpeed = 5f;
[SerializeField]
[Tooltip("Local rotation offset")]
Vector3 m_RotationOffset = Vector3.zero;
[SerializeField]
[Tooltip("If enabled, ignore the x axis when rotating")]
bool m_IgnoreX;
[SerializeField]
[Tooltip("If enabled, ignore the y axis when rotating")]
bool m_IgnoreY;
[SerializeField]
[Tooltip("If enabled, ignore the z axis when rotating")]
bool m_IgnoreZ;
#pragma warning restore 649
void Awake()
{
// Default to main camera
if (m_FaceTarget == null)
if (Camera.main != null)
m_FaceTarget = Camera.main.transform;
}
void Update()
{
if (m_FaceTarget != null)
{
var facePosition = m_FaceTarget.position;
var forward = facePosition - transform.position;
var targetRotation = forward.sqrMagnitude > float.Epsilon ? Quaternion.LookRotation(forward, Vector3.up) : Quaternion.identity;
targetRotation *= Quaternion.Euler(m_RotationOffset);
if (m_IgnoreX || m_IgnoreY || m_IgnoreZ)
{
var targetEuler = targetRotation.eulerAngles;
var currentEuler = transform.rotation.eulerAngles;
targetRotation = Quaternion.Euler
(
m_IgnoreX ? currentEuler.x : targetEuler.x,
m_IgnoreY ? currentEuler.y : targetEuler.y,
m_IgnoreZ ? currentEuler.z : targetEuler.z
);
}
var ease = 1f - Mathf.Exp(-m_TurnToFaceSpeed * Time.unscaledDeltaTime);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, ease);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35c58493ec2a8cb43ba320ce1af1adc6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: