573 lines
17 KiB
C#
573 lines
17 KiB
C#
using Cinemachine;
|
|
using FishNet.Object;
|
|
using FishNet.Object.Synchronizing;
|
|
using Managers;
|
|
using Types;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
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<Vector3> _serverPosition = new(new SyncTypeSettings
|
|
{
|
|
WritePermission = WritePermission.ServerOnly,
|
|
ReadPermission = ReadPermission.Observers
|
|
});
|
|
|
|
private readonly SyncVar<Vector2> _serverVelocity = new(new SyncTypeSettings
|
|
{
|
|
WritePermission = WritePermission.ServerOnly,
|
|
ReadPermission = ReadPermission.Observers
|
|
});
|
|
|
|
[SerializeField] private GamePlayer _player;
|
|
|
|
private void Awake()
|
|
{
|
|
_serverPosition.OnChange += OnPositionChange;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (IsServerInitialized) _serverPosition.Value = transform.position;
|
|
|
|
if (playerManager == null) playerManager = GetComponent<PlayerManager>();
|
|
_player = playerManager.GetPlayerData();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
private void Update()
|
|
{
|
|
if (!IsOwner) return;
|
|
if (_player == null) _player = playerManager.GetPlayerData();
|
|
if (_player == null) 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");
|
|
|
|
|
|
// Debug.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)
|
|
{
|
|
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)
|
|
{
|
|
Debug.Log("Position changed");
|
|
if (!asServer && !IsOwner) transform.position = next;
|
|
}
|
|
|
|
[ServerRpc]
|
|
private void SetDirectionServerRpc(string activeDir)
|
|
{
|
|
SetDirectionObserversRpc(activeDir);
|
|
}
|
|
|
|
[ObserversRpc]
|
|
private void SetDirectionObserversRpc(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;
|
|
}
|
|
}
|
|
|
|
private void OnSceneLoadEnd(Scene scene, LoadSceneMode mode)
|
|
{
|
|
Debug.Log("Scene loaded: " + scene.name);
|
|
Debug.Log("Scene mode: " + mode);
|
|
Debug.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<Camera>()
|
|
.GetComponentInChildren<CinemachineVirtualCamera>();
|
|
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<Slot> manager1, int slotId1, IItemManager<Slot> 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)
|
|
// {
|
|
// Debug.Log("Server Not initialized");
|
|
// return;
|
|
// }
|
|
//
|
|
// Debug.Log("Moving player...");
|
|
// Debug.Log(moveInput);
|
|
// player.moveInput = moveInput;
|
|
//
|
|
// rb2d.velocity = player.moveInput * player.moveSpeed;
|
|
// SyncMovementObserversRpc(player.moveInput);
|
|
// }
|
|
|
|
[ObserversRpc]
|
|
private void SyncMovementObserversRpc(Vector2 moveInput)
|
|
{
|
|
// Debug.Log("Syncing movement...");
|
|
// if (IsOwner) return;
|
|
// Updates non-owned clients
|
|
if (_player == null)
|
|
{
|
|
_player = playerManager.GetPlayerData();
|
|
return;
|
|
}
|
|
|
|
rb2d.velocity = moveInput * _player.MoveSpeed;
|
|
// 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;
|
|
// }
|
|
// }
|
|
// } |