My game isn’t complicated, I tried to learn Unet over a game jam weekend and couldn’t finish, but im too stubborn. I’ve tried just about everything me and my resources could think of now, so fire away questions please!
I’ll provide the code I’m working with, and the code that is working at the bottom.
Sooooo…
I’m trying to spawn a laser object for everyone when a player fires. This is done by a raycast the local player makes, filling up a list of start points and end points for a laser effect to be drawn, in this case its a textured quad.
To boot, I have objects already successfully spawning and destroying. NetworkServer.Destroy(block) and powerup work properly, as well as powerup instantiation and NetworkServer.Spawn(powerup). All players see these objects being created and destroyed, no duplicates.
Now for the laser…
- The Host sees everything properly.
- The Clients own laser scale doesn’t
retain from where it was set before
spawn. - The Clients sees duplicates of the
host laser.
Note: NetworkServer.Spawn(laserseg); is commented out and lasers still spawn for host???
Image: Host left, Client right
[98965-unity-net-prob.jpg*|98965]
Here’s code:
void LateUpdate()
{
if (!isLocalPlayer)
{
return;
}
Fire();
}
void Fire()
{
if (Input.GetButtonDown("Fire") && CanShoot && Energy >= EnergyPerShot)
{
ShootLaserRaycast();//generates list of positions via local raycast
Energy -= EnergyPerShot;
FireRateCoolDown();
for (int i = 1; i < LaserPoints.Count; i++)//getting all positions generated from local raycast
{
SendLaserEffect(LaserPoints[i - 1], LaserPoints*);//send positions pairs*
}
}
}
public void SendLaserEffect(Vector3 pos1, Vector3 pos2)
{
//If we are the server, do the Rpc. If we are a client, do the Command.
if (!isServer)
{
Cmd_Effect(pos1, pos2);
}
else
{
Rpc_Effect(pos1, pos2);
}
}
[Command]
public void Cmd_Effect(Vector3 cmdpos1, Vector3 cmdpos2)
{
CreateEffect(cmdpos1, cmdpos2);
}
[ClientRpc]
public void Rpc_Effect(Vector3 rpcpos1, Vector3 rpcpos2)
{
CreateEffect(rpcpos1, rpcpos2);
}
void CreateEffect(Vector3 effectpos1, Vector3 effectpos12)
{
//create a new segments for the laser, LaserSegment is the stored prefab on this object
GameObject laserseg = Instantiate(LaserSegment, Vector3.zero, Quaternion.identity);
//position between points
Vector3 centerPos = (effectpos1 + effectpos12) / 2f;
laserseg.transform.position = centerPos;
//align effect rotation with points
Vector3 direction = effectpos12 - effectpos1;
direction = Vector3.Normalize(direction);
laserseg.transform.forward = direction;
//using a textured quad in place of a sprite, but the quad is naturally vertical, so I rotate it horizontal
laserseg.transform.eulerAngles = new Vector3(90, laserseg.transform.rotation.eulerAngles.y, laserseg.transform.rotation.eulerAngles.z);
//stretch the quad towards the points
Vector3 scale = new Vector3(1, 1, 1);
scale.y = Vector3.Distance(effectpos1, effectpos12);
laserseg.transform.localScale = scale;
//tell the server to spawn the piece of the laser
//NetworkServer.Spawn(laserseg);
}
Here the code of what is working, this gets called when the local raycast hits a block, it grabs a powerup id from the block, and spawns a powerup from a local list using the id.
[Command]
public void CmdDropPowerUp(GameObject block)
{
int id = block.GetComponent().PowerUpId;
if (id != 0)
{
GameObject powerup = Instantiate(GetComponent().PowerUpDrops[id], block.transform.position, Quaternion.Euler(new Vector3(0f, 180f, 0f)));
NetworkServer.Spawn(powerup);
}
NetworkServer.Destroy(block);
}
[ClientRpc]
public void RpcDropPowerUp(GameObject block)
{
int id = block.GetComponent().PowerUpId;
if (id != 0)
{
GameObject powerup = Instantiate(GetComponent().PowerUpDrops[id], block.transform.position, Quaternion.Euler(new Vector3(0f, 180f, 0f)));
NetworkServer.Spawn(powerup);
}
NetworkServer.Destroy(block);
}
Since this code works and the other doesn’t, i’m at a complete loss for what to do. I’m wondering If both are wrong at this point.
*