283 lines
8.2 KiB
C#
283 lines
8.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class CableMiniGame : MonoBehaviour, ITask
|
|
{
|
|
[System.Serializable]
|
|
public class Cable
|
|
{
|
|
public string colorName;
|
|
public Button sourceButton;
|
|
public Button targetButton;
|
|
|
|
[HideInInspector] public bool connected;
|
|
|
|
// Line UI
|
|
[HideInInspector] public GameObject lineObject;
|
|
[HideInInspector] public RectTransform lineRect;
|
|
[HideInInspector] public Image lineImage;
|
|
}
|
|
|
|
public string TaskID { get; set; }
|
|
public TaskType TaskType { get; set; }
|
|
public string TaskName { get; set; }
|
|
public (double, double) TaskLocation { get; set; }
|
|
public bool IsCompleted { get; private set; }
|
|
|
|
private Action<ITask> _onCompleted;
|
|
private Action<ITask> _onExit;
|
|
|
|
[Header("MiniGame Settings")]
|
|
public Cable[] cables;
|
|
public Canvas canvas; // Assign your Canvas here in the inspector
|
|
public string previousSceneName;
|
|
public Color wrongAttemptColor = Color.white;
|
|
public float blinkDuration = 0.2f;
|
|
public float cableWidth = 5f;
|
|
|
|
private string selectedColor = null;
|
|
|
|
// ------------------------------
|
|
// Initialization / ITask Methods
|
|
// ------------------------------
|
|
|
|
public void Initialize(Action<ITask> onCompleted)
|
|
{
|
|
Debug.Log("[Init] Initializing mini game...");
|
|
IsCompleted = false;
|
|
_onCompleted = onCompleted;
|
|
|
|
foreach (var cable in cables)
|
|
{
|
|
cable.connected = false;
|
|
}
|
|
|
|
PrintAllCableStates("After Initialization");
|
|
}
|
|
|
|
public void Complete()
|
|
{
|
|
if (IsCompleted) return;
|
|
|
|
IsCompleted = true;
|
|
Debug.Log("[Complete] Task completed successfully!");
|
|
_onCompleted?.Invoke(this);
|
|
ExitTask(_onExit);
|
|
}
|
|
|
|
public void ExitTask(Action<ITask> onExit)
|
|
{
|
|
Debug.Log("[ExitTask] Exiting task...");
|
|
onExit?.Invoke(this);
|
|
}
|
|
|
|
// ------------------------------
|
|
// Unity Lifecycle
|
|
// ------------------------------
|
|
|
|
void Start()
|
|
{
|
|
if (canvas == null)
|
|
canvas = FindObjectOfType<Canvas>();
|
|
|
|
if (canvas == null)
|
|
Debug.LogError("[CableMiniGame] No Canvas found in scene!");
|
|
|
|
foreach (var cable in cables)
|
|
{
|
|
Cable localCable = cable;
|
|
cable.sourceButton.onClick.AddListener(() => OnSourceClicked(localCable));
|
|
cable.targetButton.onClick.AddListener(() => OnTargetClicked(localCable));
|
|
}
|
|
|
|
PrintAllCableStates("At Start");
|
|
}
|
|
|
|
// ------------------------------
|
|
// Button Handlers
|
|
// ------------------------------
|
|
|
|
void OnSourceClicked(Cable cable)
|
|
{
|
|
Debug.Log($"[SourceClick] Clicked source of cable '{cable.colorName}'");
|
|
if (cable.connected)
|
|
{
|
|
Debug.Log($"[SourceClick] Cable '{cable.colorName}' is already connected, ignoring.");
|
|
return;
|
|
}
|
|
|
|
selectedColor = cable.colorName;
|
|
Debug.Log($"[SourceClick] Selected color set to '{selectedColor}'");
|
|
PrintAllCableStates("After Source Click");
|
|
}
|
|
|
|
void OnTargetClicked(Cable cable)
|
|
{
|
|
Debug.Log($"[TargetClick] Clicked target of cable '{cable.colorName}'");
|
|
|
|
if (selectedColor == null)
|
|
{
|
|
Debug.Log("[TargetClick] No color selected, ignoring click.");
|
|
return;
|
|
}
|
|
|
|
if (cable.connected)
|
|
{
|
|
Debug.Log($"[TargetClick] Cable '{cable.colorName}' already connected, ignoring click.");
|
|
return;
|
|
}
|
|
|
|
if (selectedColor == cable.colorName)
|
|
{
|
|
cable.connected = true;
|
|
Debug.Log($"[TargetClick] Correct connection! '{selectedColor}' connected successfully.");
|
|
|
|
CreateLineUI(cable);
|
|
DrawLine(cable);
|
|
|
|
PrintAllCableStates("After Correct Connection");
|
|
CheckCompletion();
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"[TargetClick] Wrong connection attempt! Selected: '{selectedColor}', Target: '{cable.colorName}'");
|
|
PrintAllCableStates("Before BlinkAndExit");
|
|
StartCoroutine(BlinkAndExit(cable));
|
|
}
|
|
|
|
selectedColor = null;
|
|
Debug.Log("[TargetClick] Reset selected color to null");
|
|
}
|
|
|
|
// ------------------------------
|
|
// Cable Rendering
|
|
// ------------------------------
|
|
|
|
private void CreateLineUI(Cable cable)
|
|
{
|
|
if (cable.lineObject != null) return;
|
|
|
|
GameObject lineGO = new GameObject($"Line_{cable.colorName}");
|
|
lineGO.transform.SetParent(canvas.transform, false);
|
|
lineGO.transform.SetAsLastSibling();
|
|
|
|
Image img = lineGO.AddComponent<Image>();
|
|
img.color = Color.white;
|
|
img.raycastTarget = false;
|
|
|
|
RectTransform rt = lineGO.GetComponent<RectTransform>();
|
|
rt.pivot = new Vector2(0, 0.5f);
|
|
rt.localScale = Vector3.one;
|
|
rt.sizeDelta = new Vector2(0, cableWidth);
|
|
rt.localPosition = Vector3.zero;
|
|
|
|
cable.lineObject = lineGO;
|
|
cable.lineRect = rt;
|
|
cable.lineImage = img;
|
|
|
|
lineGO.SetActive(false);
|
|
}
|
|
|
|
private void DrawLine(Cable cable)
|
|
{
|
|
if (!cable.connected || cable.lineRect == null) return;
|
|
|
|
RectTransform canvasRect = canvas.transform as RectTransform;
|
|
Vector2 startPos, endPos;
|
|
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
|
canvasRect,
|
|
cable.sourceButton.transform.position,
|
|
canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera,
|
|
out startPos
|
|
);
|
|
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
|
canvasRect,
|
|
cable.targetButton.transform.position,
|
|
canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera,
|
|
out endPos
|
|
);
|
|
|
|
Vector2 diff = endPos - startPos;
|
|
float distance = diff.magnitude;
|
|
|
|
cable.lineRect.sizeDelta = new Vector2(distance, cableWidth);
|
|
cable.lineRect.anchoredPosition = startPos;
|
|
cable.lineRect.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg);
|
|
|
|
cable.lineImage.color = GetColorFromName(cable.colorName);
|
|
cable.lineObject.SetActive(true);
|
|
}
|
|
|
|
// ------------------------------
|
|
// Completion Check
|
|
// ------------------------------
|
|
|
|
void CheckCompletion()
|
|
{
|
|
foreach (var cable in cables)
|
|
{
|
|
if (!cable.connected)
|
|
{
|
|
Debug.Log($"[CheckCompletion] Cable '{cable.colorName}' not yet connected.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
Debug.Log("[CheckCompletion] All cables connected!");
|
|
Complete();
|
|
}
|
|
|
|
// ------------------------------
|
|
// Helpers
|
|
// ------------------------------
|
|
|
|
Color GetColorFromName(string name)
|
|
{
|
|
switch (name.ToLower())
|
|
{
|
|
case "red": return Color.red;
|
|
case "blue": return Color.blue;
|
|
case "green": return Color.green;
|
|
case "yellow": return Color.yellow;
|
|
default: return Color.white;
|
|
}
|
|
}
|
|
|
|
IEnumerator BlinkAndExit(Cable cable)
|
|
{
|
|
if (cable.lineObject == null) CreateLineUI(cable);
|
|
if (cable.lineImage == null)
|
|
{
|
|
Debug.LogWarning("[BlinkAndExit] No lineImage, skipping blink.");
|
|
ExitTask(_onExit);
|
|
yield break;
|
|
}
|
|
|
|
Debug.Log("[BlinkAndExit] Wrong attempt, blinking...");
|
|
Color original = cable.lineImage.color;
|
|
cable.lineImage.color = wrongAttemptColor;
|
|
|
|
yield return new WaitForSeconds(blinkDuration);
|
|
|
|
cable.lineImage.color = original;
|
|
Debug.Log("[BlinkAndExit] Restored original color, exiting task.");
|
|
|
|
ExitTask(_onExit);
|
|
// NOTE: no SceneManager.LoadScene here — TaskManager handles unloading
|
|
}
|
|
|
|
void PrintAllCableStates(string context)
|
|
{
|
|
string states = $"[CableStates] {context} => ";
|
|
foreach (var cable in cables)
|
|
{
|
|
states += $"'{cable.colorName}': {(cable.connected ? "Connected" : "Not Connected")}, ";
|
|
}
|
|
Debug.Log(states.TrimEnd(' ', ','));
|
|
}
|
|
} |