| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using UnityEngine;
- using TMPro;
- using System;
- public class PlayerController : MonoBehaviour
- {
- [Header("References")]
- public PlayerStats stats;
- public PlayerMentality mentality;
- public AIStrategy currentStrategy;
- [Header("UI")]
- public TextMeshPro positionLabel;
- public GameObject circleMesh;
- [Header("Puck Possession")]
- [SerializeField] private GameObject possessionIndicator; // Visual indicator when player has puck
- [SerializeField] private float pickupCooldown = 0.5f;
- private bool hasPuck = false;
- private PuckController controlledPuck;
- private float lastPickupTime = 0f;
- private bool isFrozen = false;
- void Start()
- {
- SetupVisuals();
- }
- void Update()
- {
- UpdatePossessionIndicator();
- }
- void SetupVisuals()
- {
- // Create circle (use a cylinder with flat height)
- if (circleMesh == null)
- {
- circleMesh = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
- circleMesh.transform.SetParent(transform);
- circleMesh.transform.localPosition = Vector3.zero;
- circleMesh.transform.localScale = new Vector3(1f, 0.1f, 1f);
- }
- // Create position label
- if (positionLabel == null)
- {
- GameObject labelObj = new GameObject("PositionLabel");
- labelObj.transform.SetParent(transform);
- labelObj.transform.localPosition = new Vector3(0, 0.5f, 0);
- positionLabel = labelObj.AddComponent<TextMeshPro>();
- positionLabel.alignment = TextAlignmentOptions.Center;
- positionLabel.fontSize = 4;
- }
- positionLabel.text = stats.position.ToString();
- // Create possession indicator (ring around player)
- if (possessionIndicator == null)
- {
- possessionIndicator = GameObject.CreatePrimitive(PrimitiveType.Sphere);
- if (possessionIndicator.GetComponent<MeshFilter>() == null)
- {
- // Fallback: create a thin cylinder ring
- possessionIndicator = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
- }
- possessionIndicator.transform.SetParent(transform);
- possessionIndicator.transform.localPosition = new Vector3(0, 0.2f, 0);
- possessionIndicator.transform.localScale = new Vector3(1.5f, 0.05f, 1.5f);
- // Make it bright and visible
- Renderer renderer = possessionIndicator.GetComponent<Renderer>();
- if (renderer != null)
- {
- renderer.material.color = Color.yellow;
- renderer.material.EnableKeyword("_EMISSION");
- renderer.material.SetColor("_EmissionColor", Color.yellow);
- }
- // Remove collider from indicator
- Collider indicatorCollider = possessionIndicator.GetComponent<Collider>();
- if (indicatorCollider != null)
- {
- Destroy(indicatorCollider);
- }
- possessionIndicator.SetActive(false);
- }
- }
- void UpdatePossessionIndicator()
- {
- if (possessionIndicator != null)
- {
- possessionIndicator.SetActive(hasPuck);
- // Rotate for visual effect
- if (hasPuck)
- {
- possessionIndicator.transform.Rotate(Vector3.up, 180f * Time.deltaTime);
- }
- }
- }
- public void SetFrozen(bool frozen)
- {
- isFrozen = frozen;
- // You can add visual feedback here (e.g., change color, show "frozen" indicator)
- }
- public void GainPuck(PuckController newPuck)
- {
- controlledPuck = newPuck;
- hasPuck = true;
- lastPickupTime = Time.time;
- Debug.Log($"{stats.playerName} gained control of the puck!");
- }
- public void ReleasePuck()
- {
- if (controlledPuck != null)
- {
- controlledPuck = null;
- hasPuck = false;
- }
- }
- public bool CanPickupPuck()
- {
- // Can only pick up if not recently picked up and not frozen
- return !hasPuck && !isFrozen && (Time.time - lastPickupTime) > pickupCooldown;
- }
- public bool HasPuck()
- {
- return hasPuck;
- }
- public void Shoot(Vector3 targetDirection, float powerMultiplier = 1.0f)
- {
- if (!hasPuck || controlledPuck == null) return;
- // Calculate shot accuracy based on stats
- float accuracy = stats.shotAccuracy / 100f;
- float power = stats.shotPower / 100f;
- // Add some inaccuracy based on stats
- Vector3 direction = targetDirection;
- float inaccuracy = (1f - accuracy) * 15f; // Up to 15 degrees off
- direction = Quaternion.Euler(0, UnityEngine.Random.Range(-inaccuracy, inaccuracy), 0) * direction;
- // Apply force to puck
- float shotForce = power * 30f * powerMultiplier; // Base force multiplied by power stat
- controlledPuck.ApplyForce(direction.normalized * shotForce, ForceMode.Impulse);
- Debug.Log($"{stats.playerName} shoots! Accuracy: {accuracy}, Power: {power}");
- }
- public void Pass(PlayerController target)
- {
- if (!hasPuck || controlledPuck == null || target == null) return;
- float accuracy = stats.passAccuracy / 100f;
- // Calculate pass direction and force based on distance
- Vector3 direction = (target.transform.position - transform.position).normalized;
- float distance = Vector3.Distance(transform.position, target.transform.position);
- // Add inaccuracy
- float inaccuracy = (1f - accuracy) * 10f;
- direction = Quaternion.Euler(0, UnityEngine.Random.Range(-inaccuracy, inaccuracy), 0) * direction;
- // Force scales with distance
- float passForce = Mathf.Lerp(10f, 25f, distance / 30f);
- controlledPuck.ApplyForce(direction * passForce, ForceMode.Impulse);
- Debug.Log($"{stats.playerName} passes to {target.stats.playerName}! Accuracy: {accuracy}");
- }
- public void Check(PlayerController target)
- {
- if (target == null) return;
- float checkPower = stats.checking / 100f;
- bool checkSuccess = UnityEngine.Random.value < checkPower;
- if (checkSuccess && target.HasPuck())
- {
- // Successful check - target loses puck
- Debug.Log($"{stats.playerName} checks {target.stats.playerName} successfully!");
- if (target.controlledPuck != null)
- {
- // Knock puck loose
- Vector3 knockDirection = (target.transform.position - transform.position).normalized;
- target.controlledPuck.ApplyForce(knockDirection * 8f, ForceMode.Impulse);
- }
- }
- else
- {
- Debug.Log($"{stats.playerName} checks {target.stats.playerName} but fails to dislodge puck");
- }
- }
- }
|