Hra kabely
This commit is contained in:
278
Assets/Scripts/kabely/kabely.cs
Normal file
278
Assets/Scripts/kabely/kabely.cs
Normal file
@@ -0,0 +1,278 @@
|
||||
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.lineImage == null) CreateLineUI(cable);
|
||||
|
||||
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);
|
||||
if (!string.IsNullOrEmpty(previousSceneName))
|
||||
SceneManager.LoadScene(previousSceneName);
|
||||
}
|
||||
|
||||
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(' ', ','));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user