using System; using System.Collections; using System.Collections.Generic; using System.Linq; using BITFALL.Cosmetic; using BITKit; using BITKit.Entities; using Cysharp.Threading.Tasks; using UnityEngine; namespace BITFALL.Entities.Cosmetic { public class CosmeticModelBehaviour : EntityBehavior { [Inject(true)] private ICosmeticService _cosmeticService; [SerializeField] private Transform current; [SerializeField] private Transform meshRoot; [SerializeField] private Animator animator; public override void OnAwake() { if (_cosmeticService is null) return; _cosmeticService.OnCosmeticsChange += OnCosmeticsChange; _cosmeticService.OnCosmeticsChanged += OnCosmeticsChanged; destroyCancellationToken.Register(() => { _cosmeticService.OnCosmeticsChange -= OnCosmeticsChange; _cosmeticService.OnCosmeticsChanged -= OnCosmeticsChanged; }); } private void OnCosmeticsChanged() { animator.Rebind(); } public override void OnStart() { base.OnStart(); if(current.TryGetComponent(out var newAnimator)) { Destroy(newAnimator); } OnCosmeticsChange(); OnCosmeticsChanged(); } private void OnCosmeticsChange() { foreach (var cosmetic in _cosmeticService.Modified.Values.OfType()) { foreach (var content in cosmetic.Contents.OfType()) { var instance = Instantiate(content.Model,meshRoot); instance.transform.localPosition = Vector3.zero; instance.transform.localRotation = Quaternion.identity; if (instance.TryGetComponent(out var newAnimator)) { animator.avatar = newAnimator.avatar; Destroy(newAnimator); } Destroy(current.gameObject); current = instance.transform; } } } 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; } } public static Transform GetRootBoneByName(Component parentTransform, string name) { return parentTransform.GetComponentsInChildren().FirstOrDefault(transformChild => transformChild.name == name); } } }