Files
soccar2d/Assets/Scripts/Puck.cs
T
2026-03-29 02:27:55 +05:30

181 lines
5.4 KiB
C#

using System.Collections;
using Mirror;
using UnityEngine;
using UnityEngine.EventSystems;
public class Puck : NetworkBehaviour
{
[HideInInspector]public Rigidbody2D rb;
[SyncVar]
public bool isSelected;
public LineRenderer lineRenderer;
[SyncVar]
public Team team;
public GameObject redTeamMarker;
public GameObject blueTeamMarker;
public Transform selectedMarker;
public float markerRotateSpeed;
public float markerBounceIntensity;
public float markerBounceSpeed;
Vector3 markerStartScale;
Vector3 startPosition;
float bounceSinA;
void OnValidate()
{
UpdateTeam();
}
void Awake()
{
UpdateTeam();
markerStartScale = selectedMarker.localScale;
rb=GetComponent<Rigidbody2D>();
startPosition = transform.position;
}
void UpdateTeam(){
redTeamMarker.SetActive(team == Team.Red);
blueTeamMarker.SetActive(team == Team.Blue);
}
void Start()
{
GameEvents.OnSelectedPuckChanged += OnSelectedPuckChanged;
GameManager.OnTeamChanged += OnTeamChanged;
GameManager.instance.RegisterPuck(this);
}
void OnDestroy()
{
GameEvents.OnSelectedPuckChanged -= OnSelectedPuckChanged;
GameManager.OnTeamChanged -= OnTeamChanged;
GameManager.instance.DisposePuck(this);
}
public Vector3 lineEnd;
void Update()
{
if (isSelected && lineRenderer != null)
{
Vector3 worldEnd = Camera.main.ScreenToWorldPoint(new Vector3(NetPlayer.curPosition.x, NetPlayer.curPosition.y, Camera.main.nearClipPlane));
lineEnd = transform.InverseTransformPoint(worldEnd);
float clamp = GameManager.instance.puckDragClampMax;
lineEnd = Vector2.ClampMagnitude(lineEnd, clamp);
if (NetPlayer.localPlayer != null
&& team == NetPlayer.localPlayer.myTeam
&& GameManager.instance.SelectedTeam == team)
{
CameraEffects.instance.SetStretchFactor(lineEnd.magnitude / clamp);
}
// Only two points for the line
lineRenderer.positionCount = 2;
lineRenderer.SetPosition(0, Vector3.zero);
lineRenderer.SetPosition(1, new Vector3(lineEnd.x, lineEnd.y, 0));
}
selectedMarker.gameObject.SetActive(GetMarkerVisibility());
if(GameManager.instance.SelectedTeam == team){
selectedMarker.Rotate(new Vector3(0,0,1), markerRotateSpeed * Time.deltaTime);
bounceSinA += Time.deltaTime * markerBounceSpeed;
float bounce = Mathf.Sin(bounceSinA) * markerBounceIntensity;
selectedMarker.localScale = markerStartScale + (Vector3.one * bounce);
}
}
bool GetMarkerVisibility(){
if(GameManager.instance.m_isMoving){return false;}
if(NetPlayer.localPlayer == null){return false;}
if(NetPlayer.localPlayer.myTeam != team){return false;}
if(GameManager.instance.SelectedTeam == team){
if(GameManager.NoPuckSelected){
return true;
}else{
return isSelected;
}
}
return false;
}
void OnSelectedPuckChanged(Puck puck)
{
isSelected = puck == this;
lineRenderer.enabled = isSelected;
if(NetPlayer.localPlayer == null){return;}
if(team != NetPlayer.localPlayer.myTeam){
lineRenderer.widthMultiplier = 0;
}
}
void OnTeamChanged(Team team){
}
void OnCollisionEnter2D(Collision2D collision)
{
if (!collision.collider.CompareTag("Puck"))
return;
// Both pucks get this callback; play once per contact.
if (gameObject.GetInstanceID() >= collision.gameObject.GetInstanceID())
return;
float otherSpeed = collision.relativeVelocity.magnitude;
Debug.Log("Puck collision speed: " + otherSpeed);
float maxVolSpeed =5f;
float vol = Mathf.Clamp(otherSpeed / maxVolSpeed,0.1f,1);
if (AudioManager.instance != null)
AudioManager.instance.PlayPuckHit(vol);
}
public void Reset(Vector3? position = null, float duration = 0.5f)
{
Vector3 pos = position ?? startPosition;
StartCoroutine(CoroutineReset(pos, duration));
}
Coroutine coroutineScheduleReset;
public void ScheduleReset(Vector3 position, float duration = 0.5f){
coroutineScheduleReset = StartCoroutine(CoroutineScheduleReset(position, duration));
}
public void UnscheduleReset(){
if(coroutineScheduleReset != null){
StopCoroutine(coroutineScheduleReset);
}
}
IEnumerator CoroutineScheduleReset(Vector3 position, float duration){
while(GameManager.isMoving){
yield return null;
}
Debug.Log("Resetting puck", gameObject);
Vector3 dir = position - transform.position;
dir = dir.normalized;
position += dir * 1.25f;
Reset(position, duration);
}
IEnumerator CoroutineReset(Vector3 pos, float duration){
float t=0;
Vector3 pos1 = transform.position;
Quaternion rot1 = transform.rotation;
while(t<duration){
t+=Time.deltaTime;
transform.position = Vector3.Lerp(pos1, pos, t/duration);
transform.rotation = Quaternion.Lerp(rot1, Quaternion.identity, t/duration);
yield return null;
}
}
}
public enum Team{
Red,
Blue
}