using System.Collections; using System.Collections.Generic; using Unity.Netcode; using UnityEngine; //this scripts syncs the object movement etc. public class ObjectSync : NetworkBehaviour { [SerializeField] private OBJLoader objLoader; //a struct that can been sent over network containing the data of an object public struct OBJData : INetworkSerializable { public Vector3[] vertices; public int[] triangles; public Vector3 positionVector; public Quaternion rotation; public Vector3 scale; //seriealizer method for network sync public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref vertices); serializer.SerializeValue(ref triangles); serializer.SerializeValue(ref positionVector); serializer.SerializeValue(ref rotation); serializer.SerializeValue(ref scale); } } //a list of the objects spawned on the local client NOT SYNCED! public List spawnedObjects = new List(); //a list of the object data on the server NOT DIRECTLY SYNED! public List objDataList = new List(); //the clientside function to scale an object [ClientRpc] public void syncScaleClientRPC(int i, Vector3 scale) { spawnedObjects[i].transform.localScale = scale; } //the server side function to scale an object [ServerRpc(RequireOwnership = false)] public void syncScaleServerRPC(int i, Vector3 scale) { syncScaleClientRPC(i, scale); //keep track of the scale on the servers list OBJData localCopy = objDataList[i]; localCopy.scale = scale; objDataList[i] = localCopy; } //the client side function to sync the position and rotation of an object [ClientRpc] public void syncLocationClientRPC(int i, Vector3 pos, Quaternion rot) { spawnedObjects[i].transform.position = pos; spawnedObjects[i].transform.rotation = rot; //Debug.Log(NetworkManager.Singleton.LocalClientId); } [ServerRpc(RequireOwnership = false)] public void syncLocationServerRPC(int i, Vector3 pos, Quaternion rot) { syncLocationClientRPC(i, pos, rot); OBJData localCopy = objDataList[i]; localCopy.positionVector = pos; localCopy.rotation = rot; objDataList[i] = localCopy; } //the next 2 functions provide functionality to sync every object from the servers list to the client //for the case that a player joins after some objects are already in the scene [ClientRpc] public void syncListClientRPC(ulong id, OBJData objDat) { //only the client with the correct id (the receiving client) must create the objects (the server got the id from initial clients request) if (id == NetworkManager.Singleton.LocalClientId) { //create a mesh via OBJLoader width the data in objDat GameObject obj = objLoader.CreateMesh(objLoader.buildObjData(objDat.vertices, objDat.triangles), objDat.positionVector); //apply scale and rotation (maybe further parameters) to the object, that the OBJLoader is not capable to load obj.transform.rotation = objDat.rotation; obj.transform.localScale = objDat.scale; } } [ServerRpc(RequireOwnership = false)] public void syncListServerRPC(ulong id) { //send each object in a seperate RPC (network buffer limit only per object, NOT FOR ALL OBJECTS) foreach (OBJData obj in objDataList) { syncListClientRPC(id, obj); } } }