- Home /
UNET - Syncing prefabs spawned by clients.
When a client fires it spawns a number of prefabs which then kill themselves shortly afterwards. They contain a number of feedback mechanics including sound and particle effects, none of which need to be synced other than when/where the prefab is instantiated.
I've added these prefabs to the spawnable objects list and they work on the client's side, but not on the server. (Or they work on the server but not on the client.)
I've messed around with Network Identities and so forth to no avail; what is the correct way of telling the server a prefab has been spawned, where it has been spawned and which direction it is facing?
(Much of my difficulty has come from building a game in JS and the few networking tutorials all seem to be in C#. My currently functional networking for player movement is all in C# and handled in different scripts. If possible, I would appreciate help understanding how to use UNET correctly in JS, although if anybody has a C# solution to my current problem which can run as a standalone script on the client-instantiated prefab, I will be elated. I have no experience with C#, but a solution is a solution.)
I have no experience with JS yet but maybe I can help you out with a c# solution. Is your problem, that the bullets (etc.) only spawn at the client's or the server's game?
Answer by melwei · Jun 08, 2016 at 12:00 PM
You should use NetworkView.RPC (c#, maybe the same for JS) to use functions on both server and client.
First add a NetworkView component to your object. Then create an RPC function, which Instantiates your Object:
[RPC]
void MyRPCFunction( myArgs ){
//Do Stuff, e.g. Set Player Settings
}
Create an RPC call, whenever you want to call the RPC function:
NetworkView MyNW=gameObject.GetComponent<NetworkView>;
MyNW.RPC("MyRPCFunction",RPCMode.All,myArgs);
Now UNet uses
[ClientRPC]
private void Rpc_function()
{
}
RPC is deprecated
Answer by Whitby93 · Jun 07, 2016 at 11:06 PM
The prefabs only instantiate in the game world of the client that instantiated them.
Answer by EpiFouloux · Jun 08, 2016 at 04:19 PM
Acutally that's how your spawning should work:
private void fire()
{
Vector3 direction = transform.forward;
Cmd_fire(direction)
}
[Command]
private void Cmd_fire(Vector3 direction)
{
GameObject bullet = (GameObject) Instantiate(bullet_prefab, transform.position, Quaternion.identity);
bullet_script = bullet.getComponent<bullet_script>();
bullet_script.direction = direction;
NetworkServer.Spawn(bullet);
}
Your bullet prefab must have a NetworkIdentity component and it script should be like this:
public class bullet_script : NetworkBehaviour
{
[SyncVar] public Vector3 direction;
void Start()
{
// rotate your bullet
}
void Update()
{
// do your stuff
}
}
I'm sorry I don't have a JS solution, but I think it's quite easy to adapt.. hope it helps !
Okay, I've got something and it did something.
Current situation:
Crash-free code, no errors.
Prefabs spawned on the server/client are visible on other clients.
Prefabs spawned on clients are not visible on server.
Prefab rotation is correct in the (host) game instance they are spawned, but their rotation is incorrect (on the clients).
Help requested:
The prefabs do not need to be rotated/updated once they are spawned in. Is this not possible to do in the instantiation script since their location does not need continuously updating?
The Network$$anonymous$$anager on each prefab. Where should the checkbox be? Client? Server? Neither?
Snippet of code from main script instantiating prefabs:
#pragma strict
import UnityEngine.Networking;
var direction : Vector3;
class IAmACannon extends NetworkBehaviour {
function InstantiateFiringPrefab () {
{
direction = transform.forward;
StartCoroutine("Cmd_fire");
}
}
@Command
function Cmd_fire()
{
var cannonEffects = Instantiate(aGunFiring, transform.position + offsetPos, transform.rotation);
var cannonSync = cannonEffects.GetComponent(CannonSync);
// cannonSync.direction = direction;
NetworkServer.Spawn(cannonEffects);
}
}
Code applied to the prefab. Not sure what I'm doing with this...
#pragma strict
import UnityEngine.Networking;
class CannonSync extends NetworkBehaviour {
@SyncVar var direction : Vector3;
@SyncVar var rotation : Vector3;
@SerializeField var myTransform : Transform;
function Start(){
StartCoroutine("TransmitPosition");
}
@Command
function CmdProvidePositionToServer (Vector3){
}
@ClientCallback
function TransmitPosition (){
if (isLocalPlayer) {
CmdProvidePositionToServer (myTransform.position);
// This isn't being called. If it was, it would cause a crash since it's C# in a JS file.
}
}
}
I think you can just put a NetworkTransform component on your prefab, and set the send interval to 0 (so it will be synchronized once)
The NetworkTransform worked perfectly, not sure why I didn't think of that myself.
I still have the issue that the prefabs don't spawn on the server if the client fires though... whereabouts is the problem in my code/what am I missing that is causing this?
Your answer
Follow this Question
Related Questions
Unet NetworkServer.Spawn() not working 5 Answers
Networking already instantiated assets 1 Answer
Unet: Client/Server end up with two different animations 0 Answers
ClientRpc Function not being carried out on all clients in Unity3d c# 0 Answers
Networked Objects not appearing on Client when Client loads scene first 1 Answer