Files
BlockSpace-v1.5.0b/Assets/Scripts/Assembly-CSharp/BlockSpace/Voxels/BrowserButton.cs
T
2026-06-01 17:19:55 +02:00

198 lines
4.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BlockSpace.Voxels
{
[DisallowMultipleComponent]
public sealed class BrowserButton : MonoBehaviour
{
private const float ButtonPressCooldown = 0.2f;
private const float ButtonShrinkDuration = 0.08f;
private const float ButtonSettleDuration = 0.12f;
private const float ButtonPressedScale = 0.84f;
private const float ButtonOvershootScale = 1.04f;
private const string ButtonThockResourcePath = "Thock";
[Header("Button")]
[SerializeField]
private Collider buttonCollider;
[SerializeField]
private VRVoxelBrush voxelBrush;
[Header("Browser Login")]
[SerializeField]
private string loginUrl = "https://example.com/login";
[Header("Audio")]
[SerializeField]
private AudioClip buttonThockClip;
private readonly Dictionary<Transform, Vector3> buttonBaseScales = new Dictionary<Transform, Vector3>();
private readonly Dictionary<Transform, Coroutine> buttonAnimationCoroutines = new Dictionary<Transform, Coroutine>();
private bool insidePrevious;
private float nextButtonPressTime;
private void Awake()
{
ResolveReferences();
EnsureButtonAudioAssigned();
}
private void OnDisable()
{
StopAllCoroutines();
ResetAllButtonScales();
}
private void Update()
{
ResolveReferences();
HandleButton();
}
private void ResolveReferences()
{
if (buttonCollider == null)
{
buttonCollider = GetComponent<Collider>();
}
if (voxelBrush == null)
{
voxelBrush = ((VRVoxelBrush.Instance != null) ? VRVoxelBrush.Instance : Object.FindObjectOfType<VRVoxelBrush>());
}
}
private void HandleButton()
{
bool flag = IsHandInside(buttonCollider, (voxelBrush != null) ? voxelBrush.LeftHandAnchor : null) || IsHandInside(buttonCollider, (voxelBrush != null) ? voxelBrush.RightHandAnchor : null);
if (flag && !insidePrevious)
{
PlayButtonEnterAnimation(buttonCollider);
if (Time.unscaledTime >= nextButtonPressTime)
{
nextButtonPressTime = Time.unscaledTime + 0.2f;
PlayButtonClickFeedback(buttonCollider);
OpenLoginUrl();
}
}
insidePrevious = flag;
}
private void OpenLoginUrl()
{
if (string.IsNullOrWhiteSpace(loginUrl))
{
Debug.LogWarning("[BrowserLoginButton] Login URL is empty.");
}
else
{
Application.OpenURL(loginUrl);
}
}
private void PlayButtonEnterAnimation(Collider button)
{
if (!(button == null))
{
Transform transform = button.transform;
if (!buttonBaseScales.TryGetValue(transform, out var value))
{
value = transform.localScale;
buttonBaseScales.Add(transform, value);
}
if (buttonAnimationCoroutines.TryGetValue(transform, out var value2) && value2 != null)
{
StopCoroutine(value2);
}
transform.localScale = value;
buttonAnimationCoroutines[transform] = StartCoroutine(AnimateButtonScale(transform, value));
}
}
private void PlayButtonClickFeedback(Collider button)
{
if (!(buttonThockClip == null) && !(button == null))
{
AudioSource.PlayClipAtPoint(buttonThockClip, button.bounds.center, 1f);
}
}
private IEnumerator AnimateButtonScale(Transform buttonTransform, Vector3 baseScale)
{
Vector3 pressedScale = baseScale * 0.84f;
Vector3 overshootScale = baseScale * 1.04f;
float elapsed = 0f;
while (elapsed < 0.08f)
{
if (buttonTransform == null)
{
yield break;
}
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / 0.08f);
buttonTransform.localScale = Vector3.LerpUnclamped(baseScale, pressedScale, t);
yield return null;
}
elapsed = 0f;
while (elapsed < 0.12f)
{
if (buttonTransform == null)
{
yield break;
}
elapsed += Time.unscaledDeltaTime;
float num = Mathf.Clamp01(elapsed / 0.12f);
float num2 = num * num * (3f - 2f * num);
Vector3 localScale = ((num2 < 0.5f) ? Vector3.LerpUnclamped(pressedScale, overshootScale, num2 / 0.5f) : Vector3.LerpUnclamped(overshootScale, baseScale, (num2 - 0.5f) / 0.5f));
buttonTransform.localScale = localScale;
yield return null;
}
if (buttonTransform != null)
{
buttonTransform.localScale = baseScale;
buttonAnimationCoroutines[buttonTransform] = null;
}
}
private void ResetAllButtonScales()
{
foreach (KeyValuePair<Transform, Vector3> buttonBaseScale in buttonBaseScales)
{
if (buttonBaseScale.Key != null)
{
buttonBaseScale.Key.localScale = buttonBaseScale.Value;
}
}
buttonAnimationCoroutines.Clear();
}
private void EnsureButtonAudioAssigned()
{
if (buttonThockClip == null)
{
buttonThockClip = Resources.Load<AudioClip>("Thock");
}
}
private static bool IsHandInside(Collider button, Transform handAnchor)
{
if (button == null || handAnchor == null)
{
return false;
}
Vector3 position = handAnchor.position;
return (button.ClosestPoint(position) - position).sqrMagnitude <= 1E-06f;
}
}
}