using System; using System.Collections.Generic; using System.Linq; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Netcode; using Unity.Services.Lobbies.Models; using UnityEngine; using UnityEngine.AI; using static Player; public class Player : NetworkBehaviour { [Header("Components")] [SerializeField] private NetworkObject network; [SerializeField] private PlayerMovement movement; [SerializeField] private Animator animator; [SerializeField] private NavMeshAgent agent; [Header("Character")] [SerializeField, ReadOnly] private GameObject spawnedCharacter; [SerializeField, ReadOnly] private Character character; public struct PlayerData : INetworkSerializable { public FixedString64Bytes playerName; public ulong playerId; public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref playerName); serializer.SerializeValue(ref playerId); } } private NetworkVariable characterName = new("", NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); private NetworkVariable playerData = new(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); private Color chatColor; public PlayerMovement Movement => movement; public Animator Animator => animator; private void UpdateCharacter(string characterID) { Character character = GameManager.CharactersList.FindCharacter(characterID); UpdateCharacter(character); } private void UpdateCharacter(Character character) { this.character = character; if (character && IsOwner) { InstantiateCharacterServerRpc(OwnerClientId, character.IDName); } } [Rpc(SendTo.Server)] private void InstantiateCharacterServerRpc(ulong clientId, string characterID) { Debug.Log("[Rpc(SendTo.Server)]"); Character character = GameManager.CharactersList.FindCharacter(characterID); if (spawnedCharacter) Destroy(spawnedCharacter); spawnedCharacter = Instantiate(character.Prefab, transform); NetworkObject networkObject = spawnedCharacter.GetComponent(); if (networkObject != null) { networkObject.SpawnWithOwnership(clientId); spawnedCharacter.transform.parent = transform; } InstantiateCharacterEveryoneRpc(networkObject.NetworkObjectId); } [Rpc(SendTo.Everyone)] private void InstantiateCharacterEveryoneRpc(ulong networkObjectId) { Debug.Log("[Rpc(SendTo.Everyone)]"); NetworkObject networkObject = NetworkManager.Singleton.SpawnManager.SpawnedObjects[networkObjectId]; spawnedCharacter = networkObject.gameObject; if (networkObject.OwnerClientId == OwnerClientId) { animator = spawnedCharacter.GetComponent(); animator.SetInteger("Gender", (int)character.Gender); } } public override void OnNetworkSpawn() { characterName.OnValueChanged += (FixedString32Bytes previousValue, FixedString32Bytes newValue) => { UpdateCharacter(newValue.ToString()); }; playerData.OnValueChanged += (PlayerData previousValue, PlayerData newValue) => { ChatManager.Instance.AddUser(newValue.playerName.ToString(), newValue.playerId); }; //UpdateCharacter(characterName.Value.ToString()); Debug.Log("IDCharacter"); if (IsOwner) { chatColor = GetRandomColor(); characterName.Value = string.IsNullOrEmpty(LocalPlayerData.AvatarID) ? "char_james" : LocalPlayerData.AvatarID; playerData.Value = new PlayerData() { playerId = LocalPlayerData.ID, playerName = LocalPlayerData.PlayerName, }; Debug.Log(characterName.Value); GameManager.Instance.SetLocalPlayer(this); FindUsers(); GameManager.Instance.Loading(false); } else { Destroy(movement); Destroy(agent); } } private void FindUsers() { if (!IsOwner) return; List allPlayers = FindObjectsOfType().ToList(); foreach (Player player in allPlayers) { if (LocalPlayerData.ID == player.playerData.Value.playerId) continue; ChatManager.Instance.AddUser(player.playerData.Value.playerName.ToString(), player.playerData.Value.playerId); } } public override void OnNetworkDespawn() { ChatManager.Instance.RemoveUser(OwnerClientId); //if (IsServer && !IsOwner) //{ // GameManager.Instance.HostLeft(); //} } public override void OnDestroy() { } public void SetCharacter(Character character) { characterName.Value = character.IDName; LocalPlayerData.AvatarID = character.IDName; UpdateCharacter(character); } public void PlayAnimation(string anim) { if (!IsOwner) return; movement.StopMovement(); animator.Play(anim); } private void AnimatorSetTrigger(string name) { if (!IsOwner) return; movement.StopMovement(); animator.SetTrigger(name); } public void Sit() => AnimatorSetTrigger("Sit"); public void Lay() => AnimatorSetTrigger("Lay"); public void SpawnEmoji(int index) { SpawnEmojiEveryoneRpc(index); } [Rpc(SendTo.Everyone)] private void SpawnEmojiEveryoneRpc(int index) { EmojiPopup popup = Instantiate(GameManager.EmojiPopupData.Prefab, transform); popup.Initialize(index); } public void SetPosition(Vector3 position) { if (!IsOwner) return; movement.MoveTo(position); transform.position = position; } public void SendMessageLocation(string message) { SendMessageLocationEveryoneRpc(message, chatColor); } public void SendMessagePrivate(string message, ulong uid) { //ChatManager.Instance.CreatePrivateMessage(message, playerData.Value.playerName.ToString(), chatColor, true); SendMessagePrivateRpc(message, chatColor, uid); } [Rpc(SendTo.Everyone)] private void SendMessagePrivateRpc(string message, Color color, ulong uid) { if (IsOwner || LocalPlayerData.ID == uid) { ChatManager.Instance.CreatePrivateMessage(message, playerData.Value.playerName.ToString(), color, IsOwner); } } [Rpc(SendTo.Everyone)] private void SendMessageLocationEveryoneRpc(string message, Color color) { ChatManager.Instance.CreateLocationMessage(message, playerData.Value.playerName.ToString(), color, IsOwner); } public Color GetRandomColor() { float r = UnityEngine.Random.Range(0f, 0.9f); float g = UnityEngine.Random.Range(0f, 0.9f); float b = UnityEngine.Random.Range(0f, 0.9f); return new Color(r, g, b); } }