Files
soccar2d/Assets/Scripts/Puck.cs
T

257 lines
7.6 KiB
C#

using System.Collections;
using Mirror;
using UnityEngine;
using UnityEngine.EventSystems;
public class Puck : NetworkBehaviour
{
[HideInInspector]public Rigidbody2D rb;
Collider2D col;
[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>();
col = GetComponent<Collider2D>();
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;
RestoreAfterReset();
if (GameManager.instance != null)
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)
{
float baseStretch = lineEnd.magnitude / clamp;
float distanceMultiplier = GameManager.instance.GetCameraStretchDistanceMultiplier(transform.position);
CameraEffects.instance.SetStretchFactor(baseStretch * distanceMultiplier);
}
// 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);
if(isServer){
ReplayRecorder.RecordHit("puck_puck", vol, this);
RpcPuckHitAudio(vol);
}
}
}
[ClientRpc]
void RpcPuckHitAudio(float vol){
AudioManager.instance.PlayPuckHit(vol);
}
Coroutine coroutineReset;
bool holdingCollisionLock;
public void Reset(Vector3? position = null, float duration = 0.5f)
{
Vector3 pos = position ?? startPosition;
if (coroutineReset != null)
{
StopCoroutine(coroutineReset);
RestoreAfterReset();
}
coroutineReset = StartCoroutine(CoroutineReset(pos, duration));
}
public void SetCollisionsEnabled(bool enabled)
{
if (col != null)
col.enabled = enabled;
if (rb != null && !enabled)
{
rb.linearVelocity = Vector2.zero;
rb.angularVelocity = 0f;
}
}
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;
Vector3 centerDir = Vector3.zero - transform.position;
dir = dir.normalized;
centerDir = centerDir.normalized;
// Clamp direction to within 30 degrees of centerDir if needed
float maxAngle = 30f;
float angle = Vector3.Angle(dir, centerDir);
if (angle > maxAngle)
{
dir = Vector3.Slerp(centerDir, dir, maxAngle / angle).normalized;
}
position += dir * 1.25f;
Reset(position, duration);
}
IEnumerator CoroutineReset(Vector3 pos, float duration){
if (GameManager.instance != null)
{
GameManager.instance.PushResetCollisionLock();
holdingCollisionLock = true;
}
rb.linearVelocity = Vector2.zero;
rb.angularVelocity = 0f;
float t=0;
Vector3 pos1 = transform.position;
Quaternion rot1 = transform.rotation;
while(t<duration){
t+=Time.deltaTime;
float u = Mathf.Clamp01(t/duration);
transform.position = Vector3.Lerp(pos1, pos, u);
transform.rotation = Quaternion.Lerp(rot1, Quaternion.identity, u);
yield return null;
}
transform.position = pos;
transform.rotation = Quaternion.identity;
RestoreAfterReset();
}
void RestoreAfterReset()
{
if (rb != null)
{
rb.linearVelocity = Vector2.zero;
rb.angularVelocity = 0f;
}
if (holdingCollisionLock && GameManager.instance != null)
{
GameManager.instance.PopResetCollisionLock();
holdingCollisionLock = false;
}
coroutineReset = null;
}
}
public enum Team{
Red,
Blue
}