using System; using System.Collections; using System.Collections.Generic; using System.Linq; using BITFALL.Cosmetic; using BITKit; using BITKit.Entities; using UnityEngine; namespace BITFALL.Entities.Cosmetic { public class CosmeticModelBehaviour : EntityBehavior { [Inject(true)] private ICosmeticService _cosmeticService; [SerializeField] private SkinnedMeshRenderer[] currentRenderers; [SerializeField] private Transform armature; [SerializeField] private Transform meshRoot; public override void OnAwake() { if (_cosmeticService is null) return; _cosmeticService.OnCosmeticsChanged += OnCosmeticsChanged; destroyCancellationToken.Register(() => _cosmeticService.OnCosmeticsChanged -= OnCosmeticsChanged); } private void OnCosmeticsChanged() { foreach (var cosmetic in _cosmeticService.Cosmetics) { foreach (var content in cosmetic.Contents.OfType()) { foreach (var _renderer in currentRenderers) { Destroy(_renderer); } var instance = Instantiate(content.Model, armature); currentRenderers = instance.GetComponentsInChildren(true); TransferSkinnedMeshes(currentRenderers, meshRoot, armature); } } } private static void TransferSkinnedMeshes(SkinnedMeshRenderer[] skinnedMeshRenderersList, Transform newParent, Transform newArmature) { foreach (var t in skinnedMeshRenderersList) { var cachedRootBoneName = t.rootBone.name; var newBones = new Transform[t.bones.Length]; for (var x = 0; x < t.bones.Length; x++) foreach (var newBone in newArmature.GetComponentsInChildren(true)) { try { if (newBone.name == t.bones[x].name) { newBones[x] = newBone; } } catch (Exception e) { BIT4Log.LogException(e); } } var matchingRootBone = GetRootBoneByName(newArmature, cachedRootBoneName); t.rootBone = matchingRootBone != null ? matchingRootBone : newArmature.transform; t.bones = newBones; Transform transform; (transform = t.transform).SetParent(newParent); transform.localPosition = Vector3.zero; } } private static Transform GetRootBoneByName(Component parentTransform, string name) { return parentTransform.GetComponentsInChildren().FirstOrDefault(transformChild => transformChild.name == name); } } }