using System.Collections; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; public class ClientGameSticksSceneController : MonoBehaviour { public static ClientGameSticksSceneController Instance; public GameObject introPanel; public GameObject playPanel; public GameObject stopPanel; public GameObject finishPanel; public TMP_Text playCountdownText; public Transform incenseTransform; public Transform incenseHolderTransform; private Image sincerityMeterFill; private float minAngle = 30f; private float maxAngle = 150f; private float dragSensitivity = 0.5f; private bool isDragging = false; private float currentAngle = 90f; private Camera mainCamera; private Coroutine windCoroutine; private bool gameActive = true; public Button finishGoToNextButton; public Button finishBackToMenuButton; private int playCountdownSecVal = 30; private void Awake() { Instance = this; } public void init() { processStep(1); gameActive = false; } IEnumerator StatusCountdown() { yield return new WaitForSeconds(1f); playCountdownSecVal--; playCountdownText.text = "時間倒數 " + playCountdownSecVal.ToString() + "秒"; if (playCountdownSecVal > 0) { StartCoroutine(StatusCountdown()); } else { processStep(3); } } IEnumerator NextStep(int step, int waitSec) { yield return new WaitForSeconds(waitSec); processStep(step); } public void processStep(int step) { if (introPanel) { introPanel.SetActive(step == 1); if (step == 1) { playCountdownSecVal = 30; StartCoroutine(NextStep(2, 3)); } } if (playPanel) { playPanel.SetActive(step == 2); if (step == 2) { StartCoroutine(StatusCountdown()); ResetIncense(); } else { gameActive = false; } } if (stopPanel) { stopPanel.SetActive(step == 3); if (step == 3) { if (ClientMessageHandler.Instance) { ClientMessageHandler.Instance.SendMessageToServer("gameSticksFinish", ""); } StartCoroutine(NextStep(4, 3)); } } if (finishPanel) { finishPanel.SetActive(step == 4); } } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { if (finishGoToNextButton) { finishGoToNextButton.onClick.AddListener(finishGoToNextButton_onClicked); } if (finishBackToMenuButton) { finishBackToMenuButton.onClick.AddListener(finishBackToMenuButton_onClicked); } init(); } private void finishGoToNextButton_onClicked() { if (ClientMessageHandler.Instance) { ClientMessageHandler.Instance.SendMessageToServer("getWords", ""); } StartCoroutine(LoadNextScene("ClientGameBackToRealScene")); } private void finishBackToMenuButton_onClicked() { StartCoroutine(LoadNextScene("ClientGameScene")); } IEnumerator LoadNextScene(string sceneName) { yield return new WaitForSeconds(0f); SceneManager.LoadScene(sceneName); } // Update is called once per frame void Update() { if (gameActive) { HandleInput(); } } void HandleInput() { // 滑鼠/觸控輸入 (使用新輸入系統) if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame) { Vector2 pointerPosition = Mouse.current.position.ReadValue(); if (IsPointerOverIncense(pointerPosition)) { StopGame(); return; } } if (Mouse.current != null && Mouse.current.leftButton.isPressed && isDragging) { Vector2 pointerPosition = Mouse.current.position.ReadValue(); UpdateAngleFromPointer(pointerPosition); } if (Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) { isDragging = false; } // 觸控輸入支援 if (Touchscreen.current != null) { var touches = Touchscreen.current.touches; for (int i = 0; i < touches.Count; i++) { var touch = touches[i]; if (!touch.isInProgress) continue; var phase = touch.phase.ReadValue(); var position = touch.position.ReadValue(); if (phase == UnityEngine.InputSystem.TouchPhase.Began) { if (IsPointerOverIncense(position)) { StopGame(); return; } } else if (phase == UnityEngine.InputSystem.TouchPhase.Moved && isDragging) { UpdateAngleFromPointer(position); } else if (phase == UnityEngine.InputSystem.TouchPhase.Ended || phase == UnityEngine.InputSystem.TouchPhase.Canceled) { isDragging = false; } } } } bool IsPointerOverIncense(Vector2 screenPosition) { Ray ray = mainCamera.ScreenPointToRay(screenPosition); RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction); if (hit.collider != null && hit.collider.transform == incenseTransform) { return true; } return false; } void UpdateAngleFromPointer(Vector2 screenPosition) { // 將螢幕座標轉換為世界座標 Vector3 worldPosition = mainCamera.ScreenToWorldPoint(screenPosition); Vector3 holderPosition = incenseHolderTransform.position; // 計算角度 Vector2 direction = new Vector2(worldPosition.x - holderPosition.x, worldPosition.y - holderPosition.y); float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg; angle = 90f + angle; // 限制角度範圍 angle = Mathf.Clamp(angle, minAngle, maxAngle); UpdateDisplay(angle); } void UpdateDisplay(float angle) { currentAngle = angle; // 更新香的旋轉 (從底部旋轉) float rotationAngle = 90f - angle; incenseTransform.localRotation = Quaternion.Euler(0, 0, rotationAngle); // 更新角度顯示 //if (angleText != null) //{ // angleText.text = $"{Mathf.Round(angle)}°"; //} // 計算誠意指數 float sincerity = Mathf.Clamp01(angle / 90f) * 100f; // 更新誠意條 if (sincerityMeterFill != null) { sincerityMeterFill.fillAmount = sincerity / 100f; } // 更新分數 //if (scoreText != null) //{ // scoreText.text = $"{Mathf.Round(sincerity)}%"; //} // 更新訊息 UpdateMessage(sincerity); } void UpdateMessage(float sincerity) { //if (messageText == null) return; // 如果遊戲已停止,顯示特殊訊息 if (!gameActive) { //messageText.text = "🛑 遊戲已停止!點擊重置按鈕重新開始"; //messageText.color = new Color(1f, 0.5f, 0f); return; } } // 公開方法供按鈕調用 public void ResetIncense() { if (windCoroutine != null) { StopCoroutine(windCoroutine); windCoroutine = null; } gameActive = true; isDragging = false; UpdateDisplay(90f); } public void StopGame() { gameActive = false; isDragging = false; if (windCoroutine != null) { StopCoroutine(windCoroutine); windCoroutine = null; } // 更新訊息顯示 //if (messageText != null) //{ // messageText.text = "🛑 遊戲已停止!點擊重置按鈕重新開始"; // messageText.color = new Color(1f, 0.5f, 0f); //} Debug.Log("遊戲已停止 - 香被觸碰"); } public void RandomChallenge() { if (windCoroutine != null) { StopCoroutine(windCoroutine); windCoroutine = null; } float randomAngle = Random.Range(minAngle, maxAngle); UpdateDisplay(randomAngle); } public void ToggleWindMode() { if (windCoroutine != null) { StopCoroutine(windCoroutine); windCoroutine = null; } else { windCoroutine = StartCoroutine(WindModeCoroutine()); } } IEnumerator WindModeCoroutine() { while (true) { float windForce = Random.Range(-5f, 5f); float newAngle = Mathf.Clamp(currentAngle + windForce, minAngle, maxAngle); UpdateDisplay(newAngle); yield return new WaitForSeconds(0.2f); } } }