diff --git a/Assets/GameAssets/Data/Scriptables.meta b/Assets/GameAssets/Data/Scriptables.meta new file mode 100644 index 0000000..187f458 --- /dev/null +++ b/Assets/GameAssets/Data/Scriptables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 00f79bc89dd9aee4ab52b8956685c852 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameAssets/Scripts/Characters/Character.cs b/Assets/GameAssets/Scripts/Characters/Character.cs new file mode 100644 index 0000000..1e7ef3b --- /dev/null +++ b/Assets/GameAssets/Scripts/Characters/Character.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +[CreateAssetMenu(menuName = "GameData/Character", fileName = "Character")] +public class Character : ScriptableObject +{ + public enum GenderType + { + Female, + Male, + Other + } + + [SerializeField] private string idName; + [SerializeField] private string visibleName; + [SerializeField] private GameObject prefab; + [SerializeField] private GenderType gender; + + public string IDName => idName; + public string VisibleName => visibleName; + public GameObject Prefab => prefab; + public GenderType Gender => gender; + +} diff --git a/Assets/GameAssets/Scripts/Characters/Character.cs.meta b/Assets/GameAssets/Scripts/Characters/Character.cs.meta new file mode 100644 index 0000000..5cee253 --- /dev/null +++ b/Assets/GameAssets/Scripts/Characters/Character.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 739353dedc097344ebe38e83a26d4fe7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameAssets/Scripts/Characters/CharactersList.cs b/Assets/GameAssets/Scripts/Characters/CharactersList.cs new file mode 100644 index 0000000..78505e2 --- /dev/null +++ b/Assets/GameAssets/Scripts/Characters/CharactersList.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using UnityEngine; + +[CreateAssetMenu(menuName = "GameData/CharactersList", fileName = "CharactersList")] +public class CharactersList : ScriptableObject +{ + public List Characters; + + public Character FindCharacter(string name) + { + if (string.IsNullOrEmpty(name)) return null; + return Characters.Find(x => x.IDName == name); + } +} diff --git a/Assets/GameAssets/Scripts/Characters/CharactersList.cs.meta b/Assets/GameAssets/Scripts/Characters/CharactersList.cs.meta new file mode 100644 index 0000000..17cfccd --- /dev/null +++ b/Assets/GameAssets/Scripts/Characters/CharactersList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbe13270dfc31f84cba7194f4e259277 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GameAssets/Scripts/GameManager.cs b/Assets/GameAssets/Scripts/GameManager.cs index 9737696..4e22b7f 100644 --- a/Assets/GameAssets/Scripts/GameManager.cs +++ b/Assets/GameAssets/Scripts/GameManager.cs @@ -1,6 +1,8 @@ using System.Collections; using System.Collections.Generic; +using Unity.Netcode; using UnityEngine; +using UnityEngine.UI; public class GameManager : MonoBehaviour { @@ -10,14 +12,46 @@ public class GameManager : MonoBehaviour if (Instance == null) Instance = this; } + [Header("Managers")] [SerializeField] private SceneLoader sceneLoader; [SerializeField] private MainScreensManager mainScreensManager; - [Header("GameObjects")] + [Header("References")] [SerializeField] private GameObject loadingScreen; + [SerializeField] private Camera mainCamera; + + [Header("Data")] + [SerializeField] private CharactersList charactersList; + [SerializeField] private EmojiPopupData emojiPopupData; + + + [Header("TestButtons")] + [SerializeField] private Button serverBtn; + [SerializeField] private Button hostBtn; + [SerializeField] private Button clientBtn; + public static CharactersList CharactersList => Instance.charactersList; + public static EmojiPopupData EmojiPopupData => Instance.emojiPopupData; + public static Player LocalPlayer => InteractionManager.LocalPlayer; + public static Camera MainCamera => Instance.mainCamera; + private void Start() + { + serverBtn.onClick.AddListener(() => + { + NetworkManager.Singleton.StartServer(); + }); + hostBtn.onClick.AddListener(() => + { + NetworkManager.Singleton.StartHost(); + }); + clientBtn.onClick.AddListener(() => + { + NetworkManager.Singleton.StartClient(); + }); + } + public void LoadScene(string sceneName) { loadingScreen.SetActive(true); @@ -33,4 +67,29 @@ public class GameManager : MonoBehaviour { } + + public void TestChangeChar(Character character) + { + LocalPlayer.SetCharacter(character); + } + + public void TestAnim(string anim) + { + LocalPlayer.PlayAnimation(anim); + } + + public void Lay() + { + LocalPlayer.Lay(); + } + + public void Sit() + { + LocalPlayer.Sit(); + } + + public void TestEmoji(int emoji) + { + LocalPlayer.SpawnEmoji(emoji); + } } diff --git a/Assets/GameAssets/Scripts/Player.cs b/Assets/GameAssets/Scripts/Player.cs index 9415a20..e57d087 100644 --- a/Assets/GameAssets/Scripts/Player.cs +++ b/Assets/GameAssets/Scripts/Player.cs @@ -1,13 +1,126 @@ using System.Collections; using System.Collections.Generic; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Netcode; using UnityEngine; +using UnityEngine.AI; -public class Player : MonoBehaviour +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; + + private NetworkVariable characterName = new("char_james", NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); public PlayerMovement Movement => movement; + public Animator Animator => animator; + + private void UpdateCharacter(string name) + { + Character character = GameManager.CharactersList.FindCharacter(name); + this.character = character; + + if (character && IsOwner) + { + InstantiateCharacterServerRpc(OwnerClientId); + } + } + + [Rpc(SendTo.Server)] + private void InstantiateCharacterServerRpc(ulong clientId) + { + Debug.Log("[Rpc(SendTo.Server)]"); + + 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()); + }; + + Debug.Log(characterName.Value.ToString()); + UpdateCharacter(characterName.Value.ToString()); + + if (!IsOwner) + { + Destroy(movement); + Destroy(agent); + } + else + { + InteractionManager.Instance.SetLocalPlayer(this); + } + } + + public void SetCharacter(Character character) + { + characterName.Value = character.IDName; + } + + 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 bool IsMine => true; + 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); + } }