using System; using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.Serialization; [RequireComponent(typeof(CharacterController))] [RequireComponent(typeof(Animator))] [RequireComponent(typeof(Health))] [RequireComponent(typeof(Statistics))] public class Player : MonoBehaviour, IResettable, ICommandTranslator { #region StateMachine public PlayerStateMachine PlayerStateMachine { get; private set; } #endregion #region Animation private Animator animator; [SerializeField] private AnimationCurve jumpDeltaYCurve; public AnimationCurve JumpDeltaYCurve { get { return jumpDeltaYCurve; } } public PlayerAnimator PlayerAnimator { get; private set; } #endregion #region PlayerComponents [SerializeField] internal PlayerData playerData; public IDamageable PlayerHealth { get; private set; } public Statistics PlayerStatictics { get; private set; } public PlayerData PlayerData { get { return playerData; } } #endregion #region MovementControl [SerializeField] private LaneSystem laneSystem; public LaneSystem LaneSystem { get { return laneSystem; } private set { laneSystem = value; } } public CharacterController CharacterController { get; private set; } public PlayerCollider PlayerCollider { get; private set; } #endregion public bool IsInvincible { get; private set; } public float InvincibilityTime { get; private set; } //PLAYER DATA ScriptableObject [SerializeField] private Boolean isPlayer2; [SerializeField] private Boolean isPlaying1VS1; public bool isDead = false; private void Awake() { GameSession.Instance.AddCommandTranslator(this, isPlayer2); animator = GetComponent(); if (animator) PlayerAnimator = new PlayerAnimator(animator); CharacterController = GetComponent(); PlayerCollider = new PlayerCollider(CharacterController); PlayerHealth = GetComponent(); PlayerStatictics = GetComponent(); PlayerStateMachine = new PlayerStateMachine(this); InvincibilityTime = playerData.InvincibilityTime; playerData.CurrentSpeed = playerData.InitialSpeed; } private void OnEnable() { PlayerHealth.OnOutOfHealth += Die; } private void Start() { PlayerStateMachine.SetState(PlayerStateMachine.PlayerStartingIdleState); } private void Update() { playerData.CurrentSpeed += playerData.SpeedAcceleration / 1000; PlayerStateMachine.Tick(); } private void FixedUpdate() { PlayerStateMachine.FixedTick(); } public float PendingAdditionalOffset { get; private set; } private void OnTriggerEnter(Collider other) { if (other.TryGetComponent(out IDamageDealer damageDealer)) //switch..case { if (IsInvincible) return; int damageAmount = 1; var damageableComponents = GetComponents(); foreach (var component in damageableComponents) { damageDealer.DealDamage(component, damageAmount); } StartCoroutine(GrantInvincibility()); } if (other.TryGetComponent(out IObstacle obstacle)) //switch..case { obstacle.Impact(); } else if (other.TryGetComponent(out ICollectable collectable)) { collectable.Collect(); } } private void Die() { isDead = true; PlayerStateMachine.SetState(PlayerStateMachine.PlayerDeadState); GameSession.Instance.UpdateScoreboard(new ScoreboardEntry(name, PlayerStatictics.Score)); GameSession.Instance.HandlePlayerDeath(this); // Informe GameSession qu'un joueur est mort // PlayerStateMachine.SetState(PlayerStateMachine.PlayerDeadState); // GameSession.Instance.UpdateScoreboard(new ScoreboardEntry(name, PlayerStatictics.Score)); // if (isPlaying1VS1) // { // // SceneManager.LoadScene("DeathScreen1v1"); // SceneManager.LoadScene("Death1VS1"); // // } // else // { // SceneManager.LoadScene("Death1VS1"); // } // } public IEnumerator GrantInvincibility() { IsInvincible = true; yield return new WaitForSeconds(InvincibilityTime); IsInvincible = false; } private void ReloadAnimator() { if (animator) PlayerAnimator = new PlayerAnimator(animator); } public void ResetToDefault() { PlayerStateMachine.SetState(null); PlayerStatictics.ResetToDefault(); LaneSystem.ResetToDefault(); Physics.SyncTransforms(); ReloadAnimator(); playerData.CurrentSpeed = playerData.InitialSpeed; } public void TranslateCommand(ECommand command, PressedState state) { if (state.IsPressed) { switch (command) { case ECommand.RIGHT: case ECommand.RIGHT2: PlayerStateMachine.IncreaseTargetLane(); break; case ECommand.LEFT: case ECommand.LEFT2: PlayerStateMachine.DecreaseTargetLane(); break; case ECommand.UP: case ECommand.UP2: PlayerStateMachine.SetState(PlayerStateMachine.PlayerJumpState); break; case ECommand.DOWN: case ECommand.DOWN2: PlayerStateMachine.SetState(PlayerStateMachine.PlayerSlideState); break; default: break; } } } }