TheStable/Assets/Horseshoes/Scripts/PlayerHorseshoe.cs
Jamie Greunbaum e023f15f48 - Added a score display to horseshoes that enables after they have been thrown.
- Added material colour changes to horseshoes to differentiate players' shoes.
- Simplified collision on stable stools and buckets.
2026-02-25 15:41:08 -05:00

134 lines
3.6 KiB
C#

using TMPro;
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
[UdonBehaviourSyncMode(BehaviourSyncMode.Continuous)]
public class PlayerHorseshoe : UdonSharpBehaviour
{
public Canvas ScoreDisplayCanvas;
public TextMeshProUGUI ScoreDisplayText;
[Space]
[SerializeField] private HorseshoesGameManager _GameManager;
[SerializeField] private Transform[] _ValidStakes;
[Space]
[SerializeField] private Rigidbody _HorseshoeRigidBody;
[SerializeField] private PlayerHorseshoeStakeDetection _RingerDetector;
[SerializeField] private PlayerHorseshoeStakeDetection _LeanDetector;
[SerializeField] private Transform[] _DistanceDetectors;
private bool _CheckMotion = false;
private float _CheckMotionTimer = 0.0f;
void FixedUpdate()
{
if (_CheckMotion)
{
if (_HorseshoeRigidBody.velocity.magnitude < 0.0000000000001f &&
_HorseshoeRigidBody.angularVelocity.sqrMagnitude < 0.0000000000001f)
{
_CheckMotionTimer += Time.fixedDeltaTime;
if (_CheckMotionTimer >= 0.5f)
{
DetermineDistance();
}
}
else
{
_CheckMotionTimer = 0.0f;
}
}
}
private void DetermineDistance()
{
ScoreDisplayText.text = "";
ScoreDisplayCanvas.gameObject.SetActive(true);
if (_RingerDetector.StakeCollision)
{
_GameManager.CalculateRinger(this);
}
//else if (_LeanDetector.StakeCollision)
//{
// Debug.LogError("[PlayerHorseshoe] Leaning on stake.");
//}
else
{
// First, figure out which stake we're closest to
Vector3 ClosestStakePosition = Vector3.zero;
float ClosestStakeDistance = float.MaxValue;
foreach (Transform StakeTransform in _ValidStakes)
{
float DistanceToStake = Vector3.Distance(transform.position, StakeTransform.position);
if (DistanceToStake < ClosestStakeDistance)
{
ClosestStakeDistance = DistanceToStake;
ClosestStakePosition = StakeTransform.position;
}
}
// Then determine which distance detector is closest to this stake
float ClosestShoeDistance = float.MaxValue;
foreach (Transform DistanceDetector in _DistanceDetectors)
{
// Change Y value to 0 for all positions, so we only measure lateral position.
Vector3 DistanceDetectorPositionLateral = DistanceDetector.position;
DistanceDetectorPositionLateral.y = 0.0f;
Vector3 ClosestStakePositionLateral = ClosestStakePosition;
ClosestStakePositionLateral.y = 0.0f;
float DistanceToStake = Vector3.Distance(DistanceDetectorPositionLateral, ClosestStakePositionLateral);
if (DistanceToStake < ClosestShoeDistance)
{
ClosestShoeDistance = DistanceToStake;
}
}
// Subtract half an inch from the measurement, since we measure from the
// centre of the 1" diameter stake
ClosestShoeDistance -= (0.0254f / 2.0f);
_GameManager.CalculatePoints(this, ClosestShoeDistance);
//Debug.Log("[PlayerHorseshoe] Detected distance: " + ClosestShoeDistance);
}
StopCheckingMotion();
}
void LateUpdate()
{
ScoreDisplayCanvas.transform.LookAt(Networking.LocalPlayer.GetBonePosition(HumanBodyBones.Head));
ScoreDisplayCanvas.transform.RotateAround(ScoreDisplayCanvas.transform.position, ScoreDisplayCanvas.transform.up, 180.0f);
}
public override void OnPickup()
{
ScoreDisplayText.text = "";
ScoreDisplayCanvas.gameObject.SetActive(false);
base.OnPickup();
}
public override void OnDrop()
{
SendCustomEventDelayedSeconds(nameof(StartCheckingMotion), 0.05f);
base.OnDrop();
}
public void StartCheckingMotion()
{
_CheckMotion = true;
_CheckMotionTimer = 0.0f;
}
public void StopCheckingMotion()
{
_CheckMotion = false;
_CheckMotionTimer = 0.0f;
}
}