Snapping objects to skeleton in multiplayer game and synching them.
So currently I have a player prefab which includes animations and rigs. Attached to this player at the root node are my networkIdentity, networkTransforms, networkAnimator and then two custom scripts. One being a playerController which amongst many things checks to see if the player hits the "E" key. This then calls a function I have in my second script attached to the root which is an inventory manager, this handles what the current item is and swaps to the next item in the inventory. The swap process takes the current item and calls its stow function which changes the parent and snaps it to a transform. Then it calls equip on the next item which does the same thing. In my case, its snapping in between the spine and the right hand in my skeleton rig. All works fine on single player. When I run it on my networked scenes, the transform change goes through but changing between parents does not work. The item itself is also a prefab and stored in the orignal player prefab on it's spine. Again in the root of the player, I included the networkChildTransform and referenced to the object on the spine. Thanks again in advance
Player controller attached at root:
public class PlayerController : NetworkBehaviour
{
InventoryManager inventory;
// Update is called once per frame
void Update()
{
if (!hasAuthority) { return; }
if (Input.GetButtonDown("Swap"))
{
inventory.SwapItem();
}
}
}
Inventory manager attached at root:
public class InventoryManager : NetworkBehaviour
{
public List<GameObject> inventoryLocations;
public List<GameObject> inventory;
public GameObject currentItem;
int currentIndex = 0;
Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
currentItem = inventory[currentIndex];
anim.SetInteger("equipID", currentItem.GetComponent<ItemController>().equipAnim);
}
[ClientRpc]
void RpcStow()
{
Debug.Log("clientside");
currentItem.GetComponent<ItemController>().SnapToStow(inventoryLocations[currentItem.GetComponent<ItemController>().stowLocation]);
}
[ClientRpc]
void RpcEquip()
{
currentItem.GetComponent<ItemController>().SnapToEquip(inventoryLocations[currentItem.GetComponent<ItemController>().equipLocation]);
}
[Command]
void CmdStow()
{
RpcStow();
}
[Command]
void CmdEquip()
{
RpcEquip();
}
public void SwapItem()
{
if (inventory.Count <= 0)
{
return;
}
currentIndex++;
if (currentIndex >= inventory.Count)
{
currentIndex = 0;
}
currentItem.GetComponent<ItemController>().SnapToStow(inventoryLocations[currentItem.GetComponent<ItemController>().stowLocation]);
CmdStow();
currentItem = inventory[currentIndex];
anim.SetInteger("equipID", currentItem.GetComponent<ItemController>().equipAnim);
currentItem.GetComponent<ItemController>().SnapToEquip(inventoryLocations[currentItem.GetComponent<ItemController>().equipLocation]);
CmdEquip();
}
}
The Item controllers code to snap to locations:
public class ItemController : MonoBehaviour
{
// Start is called before the first frame update
public int equipAnim;
public int useAnim;
public int equipLocation;
public Vector3 equipPosition;
public Vector3 equipRotation;
public Vector3 equipScale;
public int stowLocation;
public Vector3 stowPosition;
public Vector3 stowRotation;
public Vector3 stowScale;
public void SnapToEquip(GameObject parent)
{
transform.SetParent(parent.transform);
transform.localPosition = equipPosition;
transform.localRotation = Quaternion.Euler(equipRotation);
transform.localScale = equipScale;
}
public void SnapToStow(GameObject parent)
{
transform.SetParent(parent.transform);
transform.localPosition = stowPosition;
transform.localRotation = Quaternion.Euler(stowRotation);
transform.localScale = stowScale;
}
}
Answer by pIPLING · Jan 19, 2021 at 04:11 AM
For anyone who stumbles on this and is looking for a solution I ended up solving the problem. I deleted the Rpc and cmd versions of the snap functions. i then made a command function as a wrapper to an rpc version of swapItem(). This ended up syncing both on clients and host.