using Cinemachine; using FishNet.Object; using FishNet.Object.Synchronizing; using Managers; using UnityEngine; using UnityEngine.SceneManagement; using Utils; public class PlayerController : NetworkBehaviour { public Rigidbody2D rb2d; public GameObject faceR; public GameObject faceL; public GameObject faceD; public GameObject faceU; public GameObject faceHurt; public Animator playerAnimations; public GameObject swordDown; public GameObject swordRight; public GameObject swordLeft; public GameObject swordUp; public GameObject bowUp; public GameObject bowLeft; public GameObject bowRight; public GameObject bowDown; public GameObject arrowPrefab; public GameObject gameOverScreen; public GameObject heart1; public GameObject heart2; public GameObject heart3; [SerializeField] private GameObject playerGo; [SerializeField] private PlayerManager playerManager; /*[FormerlySerializedAs("_knockbackDuration")] [SerializeField] private float knockbackDuration = 0.3f;*/ // private readonly Vector2 _knockbackForce = new(3f, 2f); private readonly SyncVar _serverPosition = new(new SyncTypeSettings { WritePermission = WritePermission.ServerOnly, ReadPermission = ReadPermission.Observers }); private readonly SyncVar _serverVelocity = new(new SyncTypeSettings { WritePermission = WritePermission.ServerOnly, ReadPermission = ReadPermission.Observers }); private void Awake() { _serverPosition.OnChange += OnPositionChange; } private void Start() { if (IsServerInitialized) _serverPosition.Value = transform.position; if (playerManager == null) playerManager = GetComponent(); /*_player = playerManager.GetPlayerData();*/ } // Update is called once per frame private void Update() { if (!IsOwner) return; var isInMenu = playerManager.GetInMenuState(); if (isInMenu.Equals(true)) return; var moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); moveInput.Normalize(); // Prevents diagonal movement if (Mathf.Abs(moveInput.x) > Mathf.Abs(moveInput.y)) moveInput.y = 0; else moveInput.x = 0; MovePlayerServerRpc(moveInput); // Set direction based on movement input if (moveInput.x > 0) SetDirectionServerRpc("right"); else if (moveInput.x < 0) SetDirectionServerRpc("left"); else if (moveInput.y < 0) SetDirectionServerRpc("down"); else if (moveInput.y > 0) SetDirectionServerRpc("up"); // idle else if (moveInput.y == 0 && moveInput.x == 0) playerAnimations.Play("playerIdle"); } // private void FixedUpdate() // { // if (IsServerInitialized) // { // rb2d.velocity = _serverVelocity.Value; // _serverPosition.Value = rb2d.position; // } // else if (!IsOwner) // { // // interpolate movement on non-owner clients // transform.position = Vector3.Lerp(transform.position, _serverPosition.Value, Time.fixedDeltaTime * 10f); // } // } /* if (!IsOwner) return; // checkHealth(); if (!player.isKnockedBack && !player.attacking && !player.hurting && !player.justHurt) { if (Input.GetKey(KeyCode.Alpha1)) player.weaponInUse = 0; if (Input.GetKey(KeyCode.Alpha2)) player.weaponInUse = 1; refreshWeapons(); if (player.justHurt && player.hurtingCoolDownTime > 0) player.hurtingCoolDownTime -= Time.deltaTime; if (player.attacking == false && player.hurting == false && player.justHurt == false) { player.moveInput.x = Input.GetAxisRaw("Horizontal"); player.moveInput.y = Input.GetAxisRaw("Vertical"); // GameLogger.Log("Move?"); player.moveInput.Normalize(); // Prevents diagonal movement if (Mathf.Abs(player.moveInput.x) > Mathf.Abs(player.moveInput.y)) player.moveInput.y = 0; else player.moveInput.x = 0; // MovePlayerServerRpc(player.moveInput); if (player.moveInput.x > 0) SetDirectionServerRpc("right"); else if (player.moveInput.x < 0) SetDirectionServerRpc("left"); else if (player.moveInput.y < 0) SetDirectionServerRpc("down"); else if (player.moveInput.y > 0) SetDirectionServerRpc("up"); // idle else if (player.moveInput.y == 0 && player.moveInput.x == 0) playerAnimations.Play("playerIdle"); // Used to determine time since attack to prevent attacking a lot. if (player.justAttacked && player.attackCoolDownTime > 0) player.attackCoolDownTime -= Time.deltaTime; } if (Input.GetKey(KeyCode.Space) && player.attackCoolDownTime <= 0 && player.hurtingCoolDownTime <= 0 && player.hurting == false) { if (player.movingUp) playerAnimations.Play("attackU"); else if (player.movingDown) playerAnimations.Play("attackD"); else if (player.movingRight) playerAnimations.Play("attackR"); else if (player.movingLeft) playerAnimations.Play("attackL"); if (player.weaponInUse == 1) { if (player.movingUp) Instantiate(arrowPrefab, transform.position, Quaternion.Euler(new Vector3(0, 0, 90))); else if (player.movingDown) Instantiate(arrowPrefab, transform.position, Quaternion.Euler(new Vector3(0, 0, 270))); else if (player.movingRight) Instantiate(arrowPrefab, transform.position, Quaternion.Euler(new Vector3(0, 0, 0))); else if (player.movingLeft) Instantiate(arrowPrefab, transform.position, Quaternion.Euler(new Vector3(0, 0, 180))); player.moveInput.y = 0; player.moveInput.x = 0; player.attackCoolDownTime = 0.25f; player.justAttacked = true; } } MovePlayerServerRpc(player.moveInput); } if (player.isKnockedBack && !player.hurting && !player.justHurt) StartCoroutine(KnockbackCoroutine()); */ /*if (hurting && hurtingCoolDownTime <= 0) { faceHurt.SetActive(false); faceD.SetActive(true); hurting = false; /*if (movingRight) playerAnimations.Play("walkR");#1# playerAnimations.Play("playerIdle"); }*/ private void OnCollisionEnter2D(Collision2D collision) { var player = playerManager.GetPlayerData(); if (collision.gameObject.CompareTag("Enemy") && !player.IsKnockedBack) { // healthCount--; // Calculate the knockback direction player.KnockbackDirection = (transform.position - collision.transform.position).normalized; // Set the knockback flag player.IsKnockedBack = true; } } [ServerRpc] private void MovePlayerServerRpc(Vector2 moveInput) { // _serverVelocity.Value = moveInput * moveSpeed; // rb2d.velocity = moveInput * _player.MoveSpeed; // _serverPosition.Value = rb2d.position + rb2d.velocity * Time.deltaTime; // transform.position = rb2d.position + rb2d.velocity * Time.deltaTime; SyncMovementObserversRpc(moveInput); } private void OnPositionChange(Vector3 prev, Vector3 next, bool asServer) { GameLogger.Log("Position changed"); if (!asServer && !IsOwner) transform.position = next; } [ServerRpc] private void SetDirectionServerRpc(string activeDir) { SetDirectionObserversRpc(activeDir); } [ObserversRpc] private void SetDirectionObserversRpc(string activeDir) { var player = playerManager.GetPlayerData(); if (player == null) return; faceR.SetActive(false); faceL.SetActive(false); faceD.SetActive(false); faceU.SetActive(false); player.MovingDown = false; player.MovingLeft = false; player.MovingRight = false; player.MovingUp = false; switch (activeDir) { case "right": player.MovingRight = true; faceR.SetActive(true); playerAnimations.Play("walkR"); break; case "down": player.MovingDown = true; faceD.SetActive(true); playerAnimations.Play("walkD"); break; case "up": player.MovingUp = true; faceU.SetActive(true); playerAnimations.Play("walkU"); break; case "left": player.MovingLeft = true; faceL.SetActive(true); playerAnimations.Play("walkL"); break; } } private void OnSceneLoadEnd(Scene scene, LoadSceneMode mode) { GameLogger.Log("Scene loaded: " + scene.name); GameLogger.Log("Scene mode: " + mode); GameLogger.Log("Connecting camera to player..."); // Get the cinemachine camera component from the scene and set the player as the follow target var cinemachineVirtualCamera = scene.GetRootGameObjects()[0].GetComponent() .GetComponentInChildren(); cinemachineVirtualCamera.Follow = transform; } // private IEnumerator KnockbackCoroutine() // { // player.hurting = true; // player.justHurt = true; // faceHurt.SetActive(true); // faceD.SetActive(false); // faceU.SetActive(false); // faceR.SetActive(false); // faceL.SetActive(false); // playerAnimations.Play("playerHurt"); // // // Apply the knockback force // rb2d.AddForce(player.knockbackDirection * _knockbackForce, ForceMode2D.Impulse); // // yield return new WaitForSeconds(_knockbackDuration); // // player.isKnockedBack = false; // faceHurt.SetActive(false); // faceD.SetActive(true); // player.hurting = false; // player.justHurt = false; // playerAnimations.Play("playerIdle"); // } // private void checkHealth() // { // /*if (player.healthCount > 0) // { // if (healthCount == 3) // { // heart1.SetActive(true); // heart2.SetActive(true); // heart3.SetActive(true); // } // else if (healthCount == 2) // { // heart1.SetActive(true); // heart2.SetActive(true); // heart3.SetActive(false); // } // else if (healthCount == 1) // { // heart1.SetActive(true); // heart2.SetActive(false); // heart3.SetActive(false); // } // } // else // { // gameOverScreen.SetActive(true); // heart1.SetActive(false); // heart2.SetActive(false); // heart3.SetActive(false); // }*/ // } /*private void refreshWeapons() { swordDown.SetActive(false); swordLeft.SetActive(false); swordRight.SetActive(false); swordUp.SetActive(false); bowDown.SetActive(false); bowLeft.SetActive(false); bowRight.SetActive(false); bowUp.SetActive(false); if (player.weaponInUse == 0) { swordDown.SetActive(true); swordLeft.SetActive(true); swordRight.SetActive(true); swordUp.SetActive(true); } else if (player.weaponInUse == 1) { bowDown.SetActive(true); bowLeft.SetActive(true); bowRight.SetActive(true); bowUp.SetActive(true); } }*/ /*[ServerRpc] //client will ask the server to run this and validate it. public void TakeDamageServerRpc(int damage) { playerData.health -= damage; if (playerData.health <= 0) GameManager.Instance.EndGameServerRpc(); }*/ /* [ServerRpc] public void HealServerRpc(int amount) { playerData.health += amount; if (playerData.health > playerData.maxHealth) playerData.health = playerData.maxHealth; } [ServerRpc] public void AddExperienceServerRpc(int amount) { playerData.experience += amount; if (playerData.experience >= 100) { playerData.level++; playerData.experience = 0; } } [ServerRpc] public void AddGoldServerRpc(int amount) { playerData.gold += amount; } [ServerRpc] public void RemoveGoldServerRpc(int amount) { playerData.gold -= amount; } [ServerRpc] public void AddItemToInventoryServerRpc(GameItem item) { // inventoryManager.AddItemToOpenSlot(item); } [ServerRpc] public void AddItemToToolbarServerRpc(GameItem item) { // toolbarManager.AddItemToOpenSlot(item); } [ServerRpc] public void AddItemToInventorySlotServerRpc(GameItem item, int slotId) { // inventoryManager.AddItemToSlot(item, slotId); } [ServerRpc] public void AddItemToInventorySlotServerRpc(GameItem item) { // inventoryManager.AddItemToOpenSlot(item); } [ServerRpc] public void AddItemToToolbarSlotServerRpc(GameItem item, int slotId) { toolbarManager.AddItemToSlot(item, slotId); } [ServerRpc] public void AddItemToEquipmentSlotServerRpc(GameItem item, int slotId) { equipmentManager.AddItemToSlot(item, slotId); } */ /*[ServerRpc] public void SwapItems(IItemManager manager1, int slotId1, IItemManager manager2, int slotId2) { var item1 = manager1.GetItemFromSlot(slotId1); var item2 = manager2.GetItemFromSlot(slotId2); manager1.RemoveItemFromSlot(slotId1); manager2.RemoveItemFromSlot(slotId2); var syncItem1 = new SyncGameItem(); syncItem1.GameItem = item1; var syncItem2 = new SyncGameItem(); syncItem2.GameItem = item2; if (item1 != null) manager2.AddItemToSlot(syncItem1, slotId2); if (item2 != null) manager1.AddItemToSlot(syncItem2, slotId1); }*/ //swap items by slot type and slot id /*public void SwapItems(Slot.SlotType slotType1, int slotId1, Slot.SlotType slotType2, int slotId2) { var manager1 = GetManagerBySlotType(slotType1); var manager2 = GetManagerBySlotType(slotType2); if (manager1 == null || manager2 == null) return; SwapItems(manager1, slotId1, manager2, slotId2); }*/ /* public PlayerData GetPlayerData() { return playerData; } */ // // [ServerRpc] // private void MovePlayerServerRpc(Vector2 moveInput) // { // if (!IsServerInitialized) // { // GameLogger.Log("Server Not initialized"); // return; // } // // GameLogger.Log("Moving player..."); // GameLogger.Log(moveInput); // player.moveInput = moveInput; // // rb2d.velocity = player.moveInput * player.moveSpeed; // SyncMovementObserversRpc(player.moveInput); // } [ObserversRpc] private void SyncMovementObserversRpc(Vector2 moveInput) { // if (IsOwner) return; if (playerManager == null) return; var player = playerManager.GetPlayerData(); // GameLogger.Log("Syncing movement..."); // Updates non-owned clients if (player != null) rb2d.velocity = moveInput * player.MoveSpeed; // else // GameLogger.LogWarning("Player not found"); // transform.position += (Vector3)(moveInput * (_player.MoveSpeed * Time.deltaTime)); } /*[ServerRpc] private void SetDirectionServerRpc(string activeDir) { SetDirectionClientRpc(activeDir); }*/ } // // [ObserversRpc] // private void SetDirectionClientRpc(string activeDir) // { // faceR.SetActive(false); // faceL.SetActive(false); // faceD.SetActive(false); // faceU.SetActive(false); // player.movingDown = false; // player.movingLeft = false; // player.movingRight = false; // player.movingUp = false; // // switch (activeDir) // { // case "right": // player.movingRight = true; // faceR.SetActive(true); // playerAnimations.Play("walkR"); // break; // case "down": // player.movingDown = true; // faceD.SetActive(true); // playerAnimations.Play("walkD"); // break; // case "up": // player.movingUp = true; // faceU.SetActive(true); // playerAnimations.Play("walkU"); // break; // case "left": // player.movingLeft = true; // faceL.SetActive(true); // playerAnimations.Play("walkL"); // break; // } // } // }