using UdonSharp; using UnityEngine; using VRC.SDK3.Components; using VRC.SDK3.Data; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class FloorMapMarker : UdonSharpBehaviour { [UdonSynced, FieldChangeCallback(nameof(IsGrabbed))] private bool _IsGrabbed = false; [SerializeField] private GameManagerRound3 _GameManager; [SerializeField] private AudioManager _AudioManager; private DataList _CollidingLocations = new DataList(); private int _CollisionCheckCounter = 0; private const int MAX_REPEAT_COLLISION_CHECKS = 3; private const float TIME_BETWEEN_REPEAT_COLLISION_CHECKS = 0.15f; public void OnTriggerEnter(Collider OtherCollider) { FloorMapLocation Location = OtherCollider.GetComponent(); if (Location != null) { Debug.LogError("Found " + Location.City + ", " + Location.Country); _CollidingLocations.Add(Location); _CollisionCheckCounter = 0; if (!IsGrabbed) CheckCollisions(); } } public override void OnPickup() { IsGrabbed = true; _CollidingLocations.Clear(); base.OnPickup(); } public override void OnDrop() { IsGrabbed = false; CheckCollisions(); base.OnDrop(); } public void CheckCollisions() { if (_CollidingLocations.Count > 0 && IsUpright() && !IsGrabbed) { for (int i = 0; i < _CollidingLocations.Count; i++) { FloorMapLocation Location = (FloorMapLocation)_CollidingLocations[i].Reference; if (Location != null) { bool FoundCorrectResponse = ConfirmChoice(Location.Country, Location.City); if (FoundCorrectResponse) { _AudioManager.PlaySFX(SFXEventType.MapCorrect); VRCPickup Pickup; if (Pickup = GetComponent()) { Pickup.pickupable = false; } transform.position = Location.transform.position; return; } } } // We should make sure to only reach here if we don't get a correct // response from the previous loop. if (_CollisionCheckCounter < MAX_REPEAT_COLLISION_CHECKS) { SendCustomEventDelayedSeconds(nameof(CheckCollisions), TIME_BETWEEN_REPEAT_COLLISION_CHECKS); } else { _AudioManager.PlaySFX(SFXEventType.MapIncorrect); _CollisionCheckCounter = 0; transform.eulerAngles = new Vector3(-90.0f, 0.0f, 0.0f); _CollidingLocations.Clear(); } _CollisionCheckCounter++; } else { // If the marker isn't sitting mostly upright and is not grabbed, // don't check collisions until later, in case it becomes upright. SendCustomEventDelayedSeconds(nameof(CheckCollisions), TIME_BETWEEN_REPEAT_COLLISION_CHECKS); } } public bool ConfirmChoice(string Country, string City) { if (Country == _GameManager.GetCurrentCountry() && City == _GameManager.GetCurrentCity()) { return true; } return false; } private bool IsUpright() { return (Vector3.Dot(transform.forward, Vector3.up) >= 0.85f); } //public bool Enabled //{ // set // { // _Enabled = value; // } // get => _Enabled; //} public bool IsGrabbed { set { _IsGrabbed = value; } get => _IsGrabbed; } }