how to split player objects over network?
I'm working on a multiplayer game in which the player is a sphere which can move within a 3D space and can be split into pieces by pressing the space key. This means the original sphere is split into two pieces which are half the size of the original sphere. If the player presses they space key again the two spheres are again splitted so that there are four elements which are fourth of the original size, and so on. The player and the splitted elements are supposed to move together in a row. The player and its splitted elements are also supposed to be blue on the local client, so that the player can recognize its objects. All other clients on the game are supposed to be red so that to local client recognizes them as other players.
However currently this happens:
- when the host presses the space key, on the host the sphere splits into two pieces of half the size as requested. they also move synchronously and are in blue color. on the client this works as well and the host's elements are red. however, on the client the sphere of the host and its splitted elements have not reduced in their size.
- when the clients splits it is even worse: on the client the sphere and the splitted elements have not reduced in their size. almost all elements are also red instead of blue. on the host, the splitted client and its elements have reduced in their size correctly, however the splitted elements are not able to move with the client. almost all elements of the client are blue instead of red.
this is the code of the PlayerController.cs and the settings on the gui:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Networking;
public class PlayerController : NetworkBehaviour
{
float speed = 5.0f;
float rotationSpeed = 65.0f;
float slerpTime = 0.5f;
float mergeTime = -1.0f;
public GameObject playerSplitPrefab;
List<GameObject> playerSplits = new List<GameObject>();
Rigidbody rb;
System.Random random = new System.Random();
void Start () {
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (!isLocalPlayer)
{
return;
}
if (transform.localScale.x >= 9) {
won();
return;
}
float translation = Input.GetAxis("Vertical");
float rot = Input.GetAxis("Horizontal");
if (translation > 0) //move forwards
{
transform.Translate(0, 0, speed * Time.deltaTime);
translateSplits(0, 0, speed * Time.deltaTime);
}
else if (translation < 0) //move backwards
{
transform.Translate(0, 0, -speed * Time.deltaTime);
translateSplits(0, 0, -speed * Time.deltaTime);
}
if (rot > 0) //turn right
{
transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);
rotateSplits(rotationSpeed);
}
else if (rot < 0) //turn left
{
transform.Rotate(0, -rotationSpeed * Time.deltaTime, 0);
rotateSplits(-rotationSpeed);
}
if(Input.GetKey(KeyCode.Z)) //move upwards
{
transform.Translate(0, speed / 2 * Time.deltaTime, 0);
translateSplits(0, speed / 2 * Time.deltaTime, 0);
}
else if (Input.GetKey(KeyCode.H)) //move downwards
{
transform.Translate(0, -speed / 2 * Time.deltaTime, 0);
translateSplits(0, -speed / 2 * Time.deltaTime, 0);
}
if(Input.GetKeyDown(KeyCode.Space))
{
CmdSplit();
}
CmdCheckIfMerge();
}
private void translateSplits(float x, float y, float z) {
for (int i = 0; i < playerSplits.Count; i++) {
playerSplits[i].transform.Translate(x, y, z);
}
}
private void rotateSplits(float speed) {
var player = GameObject.FindWithTag("Player").transform;
for (int i = 0; i < playerSplits.Count; i++) {
// rotate clone around original player which is the object on the left of the row
playerSplits[i].transform.RotateAround(transform.position, player.up, speed * Time.deltaTime);
}
}
[Command]
void CmdSplit()
{
// scale player
transform.localScale = transform.localScale / 2;
// Scale current splits
for (int i = 0; i < playerSplits.Count; i++) {
playerSplits[i].transform.localScale = playerSplits[i].transform.localScale / 2;
// position current clones
playerSplits[i].transform.Translate(-transform.localScale.x * (i + 1), 0, 0);
}
// save amount of current splits from list
var currentPlayerSplits = playerSplits.Count;
// save current position of player
Vector3 spawnPosition = transform.position;
// total width
var xOffsetNewSplits = (currentPlayerSplits + 1) * transform.localScale.x;
// Instantiate new clones (one per current clone + player)
for (int i = 0; i < currentPlayerSplits + 1; i++) {
// newSplit has initial scale of prefab
GameObject newSplit = Instantiate(playerSplitPrefab, spawnPosition, transform.rotation);
// therefore: assign scale of split to current size of player
newSplit.transform.localScale = transform.localScale;
newSplit.GetComponent<MeshRenderer>().material.color = Color.blue;
// add new split to list
playerSplits.Add(newSplit);
// position new split
newSplit.transform.Translate(xOffsetNewSplits + transform.localScale.x * i, 0, 0);
// Spawn the newSplit on the Clients
NetworkServer.Spawn(newSplit);
}
calculateSpeed();
mergeTime = 5.0f;
}
[Command]
void CmdCheckIfMerge()
{
if(mergeTime<=0.0f && mergeTime>-0.5f){
merge();
} else if(mergeTime!=-1.0f){
mergeTime-=Time.deltaTime;
}
}
void merge(){
for(int i = 0; i < playerSplits.Count; i++){
transform.localScale = transform.localScale + playerSplits[i].transform.localScale;
Destroy(playerSplits[i]);
}
// remove all splits form the list
playerSplits.Clear();
calculateSpeed();
mergeTime=-1.0f;
}
void calculateSpeed(){
if(transform.localScale.x<5){
speed = 7-transform.localScale.x;
}
}
public override void OnStartLocalPlayer()
{
// local player is blue so that client can identify their player object
GetComponent<MeshRenderer>().material.color = Color.blue;
}
}
inspector of network manager:
inspector of player prefab:
the inspector of the player split prefab looks the same as the one of the player prefab, aparth from that it has no controller script like the player (player controller script).,
Your answer
Follow this Question
Related Questions
[UNET] Syncing the position of a non-player object such as a trap (no player authority whatsoever) 3 Answers
Unet - spawning bullets, two issues 1 Answer
Assign Network Manager an Online Scene with Script 0 Answers
UNET NetIDs for Scene Objects Mismatched Between Client and Server 1 Answer
Problem with using Unity Spawnsystem (Unet / Multiplayer) 0 Answers