112 lines
3.4 KiB
C#
112 lines
3.4 KiB
C#
using UnityEngine;
|
|
|
|
[DefaultExecutionOrder(-50)]
|
|
public class RingCourseTracker : MonoBehaviour
|
|
{
|
|
[Tooltip("Drag each Ring object here in the order they must be flown through.")]
|
|
[SerializeField] private Transform[] ringsInOrder;
|
|
|
|
[SerializeField] private string landInstructionMessage =
|
|
"All rings complete! Land the plane at the runway.";
|
|
|
|
private RingCheckpoint[] checkpoints;
|
|
private int nextRingIndex;
|
|
private int ringsPassed;
|
|
private bool courseComplete;
|
|
|
|
public int RingsPassed => ringsPassed;
|
|
public int TotalRings => checkpoints != null ? checkpoints.Length : 0;
|
|
public bool CourseComplete => courseComplete;
|
|
|
|
private void Awake()
|
|
{
|
|
BindRings();
|
|
}
|
|
|
|
private void BindRings()
|
|
{
|
|
if (ringsInOrder == null || ringsInOrder.Length == 0)
|
|
{
|
|
Debug.LogWarning($"[RingCourse] No rings assigned on {name}.", this);
|
|
checkpoints = System.Array.Empty<RingCheckpoint>();
|
|
return;
|
|
}
|
|
|
|
checkpoints = new RingCheckpoint[ringsInOrder.Length];
|
|
|
|
for (int i = 0; i < ringsInOrder.Length; i++)
|
|
{
|
|
Transform ringTransform = ringsInOrder[i];
|
|
if (ringTransform == null)
|
|
{
|
|
Debug.LogWarning($"[RingCourse] Ring slot {i + 1} is empty on {name}.", this);
|
|
continue;
|
|
}
|
|
|
|
if (!ringTransform.TryGetComponent(out RingCheckpoint checkpoint))
|
|
checkpoint = ringTransform.gameObject.AddComponent<RingCheckpoint>();
|
|
|
|
checkpoint.Configure(this, i);
|
|
checkpoint.ResetCheckpoint();
|
|
checkpoints[i] = checkpoint;
|
|
}
|
|
|
|
nextRingIndex = 0;
|
|
ringsPassed = 0;
|
|
courseComplete = false;
|
|
|
|
if (TotalRings > 0 && checkpoints[0] != null)
|
|
Debug.Log($"[RingCourse] Course started. Fly through ring 1: {checkpoints[0].name}");
|
|
}
|
|
|
|
public void RegisterRingPass(RingCheckpoint ring)
|
|
{
|
|
if (courseComplete || ring == null || checkpoints == null)
|
|
return;
|
|
|
|
int ringIndex = System.Array.IndexOf(checkpoints, ring);
|
|
if (ringIndex < 0)
|
|
return;
|
|
|
|
if (ring.Passed)
|
|
return;
|
|
|
|
if (ringIndex != nextRingIndex)
|
|
{
|
|
RingCheckpoint expected = checkpoints[nextRingIndex];
|
|
string expectedName = expected != null ? expected.name : $"ring {nextRingIndex + 1}";
|
|
Debug.LogWarning(
|
|
$"[RingCourse] Wrong order. Pass {expectedName} next ({nextRingIndex + 1}/{TotalRings}).");
|
|
return;
|
|
}
|
|
|
|
ring.MarkPassed();
|
|
ringsPassed++;
|
|
nextRingIndex++;
|
|
|
|
Debug.Log($"[RingCourse] Ring {ringsPassed}/{TotalRings} passed: {ring.name}");
|
|
|
|
if (ringsPassed >= TotalRings)
|
|
{
|
|
courseComplete = true;
|
|
Debug.Log($"[RingCourse] {landInstructionMessage}");
|
|
return;
|
|
}
|
|
|
|
RingCheckpoint nextRing = checkpoints[nextRingIndex];
|
|
if (nextRing != null)
|
|
Debug.Log($"[RingCourse] Next ring ({nextRingIndex + 1}/{TotalRings}): {nextRing.name}");
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
[ContextMenu("Fill Rings From Children (scene order)")]
|
|
private void FillRingsFromChildren()
|
|
{
|
|
ringsInOrder = new Transform[transform.childCount];
|
|
for (int i = 0; i < transform.childCount; i++)
|
|
ringsInOrder[i] = transform.GetChild(i);
|
|
UnityEditor.EditorUtility.SetDirty(this);
|
|
}
|
|
#endif
|
|
}
|