update time , score
This commit is contained in:
@@ -1,60 +1,161 @@
|
||||
using UnityEngine;
|
||||
using TMPro; // Dùng UnityEngine.UI nếu bạn xài Text thường
|
||||
using TMPro;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections;
|
||||
|
||||
public class ScoreManager : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI scoreText; // Kéo UI Text điểm số vào đây
|
||||
[Header("UI References")]
|
||||
public TextMeshProUGUI scoreText;
|
||||
public TextMeshProUGUI timerText;
|
||||
public TextMeshProUGUI winStatusText;
|
||||
public GameObject distanceCanvas;
|
||||
public TextMeshProUGUI distanceText;
|
||||
|
||||
[Header("Game Settings")]
|
||||
public float gameDuration = 300f;
|
||||
public int targetScore = 50;
|
||||
|
||||
private int currentScore = 0;
|
||||
private float timeRemaining;
|
||||
private bool isGameOver = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
currentScore = 0;
|
||||
UpdateScoreUI();
|
||||
timeRemaining = gameDuration;
|
||||
isGameOver = false;
|
||||
|
||||
// CHẨN ĐOÁN LỖI:
|
||||
Collider col = GetComponent<Collider>();
|
||||
if (col == null)
|
||||
Debug.LogError("<color=red>LỖI NẶNG: Object này (" + gameObject.name + ") CHƯA CÓ COLLIDER. Hãy add Box Collider ngay!</color>");
|
||||
else if (!col.isTrigger)
|
||||
Debug.LogWarning("<color=yellow>CẢNH BÁO: Collider của rổ chưa tích 'Is Trigger'. Hãy tích vào!</color>");
|
||||
|
||||
Debug.Log("<color=white>Script ScoreManager đang hoạt động trên: " + gameObject.name + "</color>");
|
||||
UpdateScoreUI();
|
||||
if (distanceCanvas != null) distanceCanvas.SetActive(false);
|
||||
if (winStatusText != null) winStatusText.text = "";
|
||||
|
||||
Debug.Log("<color=green>ScoreManager đã khởi tạo thành công!</color>");
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (isGameOver) return;
|
||||
|
||||
if (timeRemaining > 0)
|
||||
{
|
||||
timeRemaining -= Time.deltaTime;
|
||||
UpdateTimerUI();
|
||||
|
||||
if (currentScore >= targetScore)
|
||||
{
|
||||
WinGame();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameOver();
|
||||
}
|
||||
}
|
||||
|
||||
// Bắt va chạm kiểu Trigger (Xuyên qua)
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
GhiDiem(other.gameObject, "TRIGGER");
|
||||
Debug.Log("Va chạm Trigger với: " + other.gameObject.name);
|
||||
ProcessScore(other.gameObject);
|
||||
}
|
||||
|
||||
// Bắt va chạm kiểu Vật lý (Đập vào nhau) - Dự phòng nếu bạn chưa tích Is Trigger
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
GhiDiem(collision.gameObject, "PHYSICS");
|
||||
Debug.Log("Va chạm Vật lý với: " + collision.gameObject.name);
|
||||
ProcessScore(collision.gameObject);
|
||||
}
|
||||
|
||||
void GhiDiem(GameObject obj, string type)
|
||||
void ProcessScore(GameObject obj)
|
||||
{
|
||||
Debug.Log("PHÁT HIỆN VA CHẠM [" + type + "] với: " + obj.name + " | Tag: " + obj.tag);
|
||||
if (isGameOver) return;
|
||||
|
||||
if (obj.CompareTag("Ball") || obj.name.Contains("Sphere") || obj.name.Contains("ball"))
|
||||
// Ưu tiên kiểm tra script BouncyBall
|
||||
BouncyBall ball = obj.GetComponent<BouncyBall>();
|
||||
|
||||
// Nếu không có script, hoặc bóng đã được tính điểm rồi thì bỏ qua
|
||||
if (ball == null || ball.isScored)
|
||||
{
|
||||
currentScore += 2;
|
||||
UpdateScoreUI();
|
||||
Debug.Log("<color=cyan>===> GHI ĐIỂM THÀNH CÔNG! Điểm hiện tại: " + currentScore + "</color>");
|
||||
Destroy(obj, 0.2f);
|
||||
return;
|
||||
}
|
||||
|
||||
// Đánh dấu đã ghi điểm ngay lập tức
|
||||
ball.isScored = true;
|
||||
|
||||
// Tính khoảng cách
|
||||
float distance = Vector3.Distance(ball.shotPosition, transform.position);
|
||||
int points = CalculatePoints(distance);
|
||||
|
||||
currentScore += points;
|
||||
UpdateScoreUI();
|
||||
|
||||
// Hiển thị khoảng cách trên rổ
|
||||
if (distanceCanvas != null)
|
||||
{
|
||||
StopAllCoroutines(); // Dừng các lần hiện trước đó để tránh chồng chéo
|
||||
StartCoroutine(ShowDistanceUI(distance));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("distanceCanvas chưa được gán trong Inspector!");
|
||||
}
|
||||
|
||||
Debug.Log($"<color=cyan>GHI ĐIỂM: {points}pt | Khoảng cách ném: {distance:F2}m | Tổng điểm: {currentScore}</color>");
|
||||
|
||||
// Vô hiệu hóa script hoặc quả bóng để không tính điểm lại
|
||||
ball.enabled = false;
|
||||
Destroy(obj, 0.5f);
|
||||
}
|
||||
|
||||
int CalculatePoints(float distance)
|
||||
{
|
||||
// Điều chỉnh lại logic: Nếu trong AR khoảng cách tính bằng Unity Unit có thể rất nhỏ
|
||||
// Bạn có thể cần nhân distance với một hệ số nếu tỉ lệ scale của bạn khác 1:1 mét
|
||||
if (distance >= 10f) return 3;
|
||||
if (distance >= 5f) return 2;
|
||||
if (distance >= 3f) return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UpdateScoreUI()
|
||||
{
|
||||
if (scoreText != null)
|
||||
if (scoreText != null) scoreText.text = "Score: " + currentScore;
|
||||
}
|
||||
|
||||
void UpdateTimerUI()
|
||||
{
|
||||
if (timerText != null)
|
||||
{
|
||||
scoreText.text = "Score: " + currentScore;
|
||||
int minutes = Mathf.FloorToInt(timeRemaining / 60);
|
||||
int seconds = Mathf.FloorToInt(timeRemaining % 60);
|
||||
timerText.text = string.Format("Time: {0:00}:{1:00}", minutes, seconds);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
IEnumerator ShowDistanceUI(float distance)
|
||||
{
|
||||
if (distanceText != null) distanceText.text = $"{distance:F1}m";
|
||||
distanceCanvas.SetActive(true);
|
||||
yield return new WaitForSeconds(2.5f);
|
||||
distanceCanvas.SetActive(false);
|
||||
}
|
||||
|
||||
void WinGame()
|
||||
{
|
||||
isGameOver = true;
|
||||
if (winStatusText != null)
|
||||
{
|
||||
Debug.LogWarning("ScoreText chưa được kéo vào ScoreManager!");
|
||||
winStatusText.text = "YOU WIN!";
|
||||
winStatusText.color = Color.green;
|
||||
}
|
||||
}
|
||||
|
||||
void GameOver()
|
||||
{
|
||||
isGameOver = true;
|
||||
if (winStatusText != null)
|
||||
{
|
||||
winStatusText.text = "GAME OVER";
|
||||
winStatusText.color = Color.red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user