using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using TMPro; public class GameManager : MonoBehaviour { public static Action OnSelectedPuckChanged; public static Action 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 pucks = new List(); 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(); 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().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().Reset(resetDuration); yield return new WaitForSeconds(resetDuration); freezeInput=false; } }