Files
soccar2d/Assets/Scripts/GameManager.cs
2026-01-30 21:22:59 +05:30

238 lines
6.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using TMPro;
public class GameManager : MonoBehaviour
{
public static Action<Puck> OnSelectedPuckChanged;
public static Action<Team> OnTeamChanged;
public static bool isMoving{
get{
return instance.IsMoving();
}
}
public bool m_isMoving =false;
public static Team SelectedTeam = Team.Red;
public static bool NoPuckSelected {
get{
return instance.selectedPuck == null;
}
}
public EventTrigger gameInputPanel;
public Rigidbody2D ball;
public float puckForce = 20f;
[Range(0f,1f)]
public float puckForceMaxPoint = 0.75f;
public float ballMoveTime = 3f;
public float puckDragClamp = 5f;
public int redScore,blueScore=0;
[Header("UI")]
public TMP_Text redScoreText;
public TMP_Text blueScoreText;
public GameObject gameOverPanel;
public GameObject blueWon,redWon;
[Header("Misc")]
public List<Puck> pucks = new List<Puck>();
public static GameManager instance;
void Awake()
{
instance = this;
}
void Start()
{
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerDown;
entry.callback.AddListener(OnPointerDown);
gameInputPanel.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerUp;
entry.callback.AddListener(OnPointerUp);
gameInputPanel.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Drag;
entry.callback.AddListener(OnDrag);
gameInputPanel.triggers.Add(entry);
OnSelectedPuckChanged?.Invoke(null);
Application.targetFrameRate = 100;
}
public void RegisterPuck(Puck puck){
pucks.Add(puck);
}
public void DisposePuck(Puck puck){
pucks.Remove(puck);
}
public Vector2 startPosition;
public Vector2 curPosition;
Puck selectedPuck;
void OnPointerDown(BaseEventData eventData)
{
if(IsMoving()){return;} //Do not do anything if shits moving
PointerEventData pointerEventData = eventData as PointerEventData;
startPosition = pointerEventData.position;
curPosition = startPosition;
// Convert screen position to world position
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(pointerEventData.position.x, pointerEventData.position.y, Camera.main.nearClipPlane));
// Find all pucks in the scene
Puck[] pucks = FindObjectsOfType<Puck>();
float minDistance = float.MaxValue;
Puck closestPuck = null;
foreach (Puck puck in pucks)
{
if(puck.team != SelectedTeam){continue;}
float dist = Vector2.Distance(worldPosition, puck.transform.position);
if (dist < minDistance)
{
minDistance = dist;
closestPuck = puck;
}
}
selectedPuck = closestPuck;
OnSelectedPuckChanged?.Invoke(selectedPuck);
}
Coroutine coroutinePostLaunch;
void OnPointerUp(BaseEventData eventData)
{
Debug.Log("Pointer up");
PointerEventData pointerEventData = eventData as PointerEventData;
Vector2 endPosition = pointerEventData.position;
// Vector2 direction = endPosition - startPosition;
Vector2 direction = selectedPuck.lineEnd;
if(coroutinePostLaunch != null){
StopCoroutine(coroutinePostLaunch);
}
coroutinePostLaunch = StartCoroutine(CoroutinePostLaunch());
float force = puckForce * Time.deltaTime;
Debug.Log($"launching puck at {direction}");
selectedPuck.GetComponent<Rigidbody2D>().AddForce(-direction * force, ForceMode2D.Impulse);
startPosition = Vector2.zero;
selectedPuck = null;
OnSelectedPuckChanged?.Invoke(null);
SelectedTeam = SelectedTeam == Team.Red ? Team.Blue : Team.Red;
OnTeamChanged?.Invoke(SelectedTeam);
}
void OnDrag(BaseEventData eventData)
{
PointerEventData pointerEventData = eventData as PointerEventData;
curPosition = pointerEventData.position;
}
IEnumerator CoroutinePostLaunch(){
float t = 0;
while ( t < 1){
t += Time.deltaTime / ballMoveTime;
ball.linearDamping = Mathf.Lerp(0, 10, t);
yield return null;
}
}
bool IsMoving(){
if(freezeInput){return true;}
float minMagnitude = 0.01f;
foreach(Puck puck in pucks){
if(puck.rb.linearVelocity.magnitude > minMagnitude){
return true;
}
}
if(ball.linearVelocity.magnitude > minMagnitude){
return true;
}
return false;
}
void Update()
{
m_isMoving=IsMoving();
}
public void OnGoal(Team team){
freezeInput=true;
if(team == Team.Blue){
blueScore++;
blueScoreText.text = blueScore.ToString();
}else{
redScore++;
redScoreText.text = redScore.ToString();
}
if(blueScore >= 3){
gameOverPanel.SetActive(true);
blueWon.SetActive(true);
redWon.SetActive(false);
}else if(redScore >= 3){
gameOverPanel.SetActive(true);
blueWon.SetActive(false);
redWon.SetActive(true);
}else{
StartCoroutine(CoroutineOnGoal(team));
}
}
bool freezeInput = false;
IEnumerator CoroutineOnGoal(Team team){
if(coroutinePostLaunch!=null){
StopCoroutine(coroutinePostLaunch);
}
float t=0;
while(t < 1){
t +=Time.deltaTime * 2f;
ball.linearDamping = Mathf.Lerp(0, 100, t);
yield return null;
}
yield return new WaitForSeconds(2f);
Reset();
}
public void Reset()
{
StartCoroutine(CoroutineReset());
}
IEnumerator CoroutineReset(){
float resetDuration = 0.5f;
foreach(Puck puck in pucks){
puck.Reset(resetDuration);
}
ball.GetComponent<Ball>().Reset(resetDuration);
yield return new WaitForSeconds(resetDuration);
freezeInput=false;
}
}