Equip Multiplayer With Photon, Mixamo, and Unity 3D – Full Guide

Equip Multiplayer With Photon, Mixamo, and Unity 3D

In this comprehensive Unity tutorial, you'll learn how to create a full multiplayer equipment system using Photon PUN for real-time synchronization and Mixamo for animated character assets. The provided boneCombinePhoton script dynamically attaches and synchronizes clothing, hair, gloves, and shoes across all players in the same multiplayer session.

🎮 Features

  • Fully synchronized clothing and armor across players using Photon RPCs.
  • Automatic Mixamo bone mapping for animated 3D models.
  • Supports shirts, trousers, hair, gloves, and shoes.
  • Lightweight, optimized code for mobile and PC builds.
  • Real-time visual updates without breaking animations.

🧠 How It Works

The boneCombinePhoton system scans all character bones, then reassigns each piece of clothing to the correct skeleton. When a player changes equipment, the new item is automatically applied to every other player through Photon RPC synchronization. This ensures that all clients see the same clothing and animation state at any time.

💻 Full Script

public class boneCombinePhoton : MonoBehaviour
{
 public readonly Dictionary<int, Transform> _RootBoneDictionary = new Dictionary<int, Transform>();
 [SerializeField] private readonly Transform[] _boneTransforms = new Transform[67];

 public Transform _transform;
 [SerializeField] private Transform Trousers;
 [SerializeField] private Transform shirt;
 [SerializeField] private Transform hair;
 [SerializeField] private Transform shoe;
 [SerializeField] private Transform glove;
 [SerializeField] private SkinnedMeshRenderer meshRenderer;
 [SerializeField] private Transform[] bones;
 Transform EquipmentPosition;
 private PhotonView pv;
 SkinnedMeshRenderer renderers;

 private void Start()
 {
     pv = GetComponent<PhotonView>();
     if (pv.IsMine)
         pv.RPC("TraverseHierarchy", RpcTarget.AllBuffered);
     
     kiemtrado();
 }

 void kiemtrado()
 {
     if (lkhoquanao.instance.dangmac_quan.Length > 0)
         hiendomac_photon(lkhoquanao.instance.dangmac_quan, "Trousers");

     if (lkhoquanao.instance.dangmac_ao.Length > 0)
         hiendomac_photon(lkhoquanao.instance.dangmac_ao, "shirt");

     if (lkhoquanao.instance.dangmac_toc.Length > 0)
         hiendomac_photon(lkhoquanao.instance.dangmac_toc, "hair");

     if (lkhoquanao.instance.dangmac_gangtay.Length > 0)
         hiendomac_photon(lkhoquanao.instance.dangmac_gangtay, "glove");

     if (lkhoquanao.instance.dangmac_giay.Length > 0)
         hiendomac_photon(lkhoquanao.instance.dangmac_giay, "shoe");
 }

 void hiendomac_photon(string EquipmentName, string Type)
 {
     AddLimb(EquipmentName, Type);
 }

 public void AddLimb(string bonedObj, string Type)
 {
     if (pv.IsMine)
     {
         if (Type == "Trousers")
             pv.RPC("ProcessBonedObject", RpcTarget.AllBuffered, bonedObj, "Trousers");

         if (Type == "shirt")
             pv.RPC("ProcessBonedObject", RpcTarget.AllBuffered, bonedObj, "shirt");

         if (Type == "hair")
             pv.RPC("ProcessBonedObject", RpcTarget.AllBuffered, bonedObj, "hair");

         if (Type == "shoe")
             pv.RPC("ProcessBonedObject", RpcTarget.AllBuffered, bonedObj, "shoe");

         if (Type == "glove")
             pv.RPC("ProcessBonedObject", RpcTarget.AllBuffered, bonedObj, "glove");
     }
 }

 void setupgiatri(Transform transform)
 {
     foreach (Transform child in transform)
     {
         _RootBoneDictionary.Add(child.name.GetHashCode(), child);
         setupgiatri(child);
     }
 }

 [PunRPC]
 private void TraverseHierarchy()
 {
     _transform = this.gameObject.transform;
     setupgiatri(_transform);
 }

 [PunRPC]
 private Transform ProcessBonedObject(string EquipmentName, string Type)
 {
     foreach (GameObject bonedObj in lkhoquanao.instance.doituongtranbi)
     {
         if (bonedObj.name.Contains(EquipmentName))
             renderers = bonedObj.GetComponent<SkinnedMeshRenderer>();
     }

     if (Type == "Trousers") EquipmentPosition = Trousers;
     if (Type == "shirt") EquipmentPosition = shirt;
     if (Type == "hair") EquipmentPosition = hair;
     if (Type == "shoe") EquipmentPosition = shoe;
     if (Type == "glove") EquipmentPosition = glove;

     meshRenderer = EquipmentPosition.gameObject.AddComponent<SkinnedMeshRenderer>();
     bones = renderers.bones;

     for (int i = 0; i < bones.Length; i++)
         _boneTransforms[i] = _RootBoneDictionary[bones[i].name.GetHashCode()];

     meshRenderer.bones = _boneTransforms;
     meshRenderer.sharedMesh = renderers.sharedMesh;
     meshRenderer.materials = renderers.sharedMaterials;
     EquipmentPosition.SetParent(_transform);

     return EquipmentPosition;
 }
}
    

🚀 Implementation Steps

  • Attach this script to your player prefab containing a PhotonView component.
  • Assign each clothing type (shirt, trousers, etc.) in the Unity Inspector.
  • Ensure that your character models are rigged with Mixamo-compatible bones.
  • Run in a Photon multiplayer room to test real-time synchronization.

📈 SEO Keywords for Optimization

  • Unity Photon multiplayer equipment
  • Mixamo character customization Unity
  • Photon RPC Unity tutorial
  • Unity skinned mesh renderer tutorial
  • Multiplayer customization script Unity
  • Photon PUN 2 synchronization
  • Unity Mixamo bone mapping
  • Realtime equipment Unity 3D
  • Character clothing system Unity multiplayer
  • Appalo Studio Unity guide

✅ Conclusion

This Photon Mixamo integration system provides a complete foundation for multiplayer character customization. With bone synchronization, lightweight performance, and full Photon RPC support, it ensures smooth, real-time character appearance updates across all clients in your Unity game.