using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace FiradzoAssets
{
public class EquipmentAttachmentHelper : MonoBehaviour
{
[SerializeField, Tooltip("SkinnedMeshRenderer reference from source asset. Required to read bones structure")]
private SkinnedMeshRenderer skinnedMeshSource;
[SerializeField, Tooltip("SkinnedMeshRenderer component on the object that need to be binded")]
private SkinnedMeshRenderer thisSkinnedMesh;
[Space(10f)]
[SerializeField]
private bool forceRebind;
[SerializeField, HideInInspector]
private bool isBinded;
[SerializeField, HideInInspector]
private string lastBindedMeshName;
private void Awake()
{
BindItemToBones();
}
public void SetSkinnedMeshSource(SkinnedMeshRenderer skinnedMeshSource)
{
this.skinnedMeshSource = skinnedMeshSource;
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
private void BindItemToBones()
{
if (isBinded || skinnedMeshSource == null || thisSkinnedMesh == null)
{
return;
}
var bones = new Transform[skinnedMeshSource.bones.Length];
var root = transform.parent;
for (int i = 0; i < skinnedMeshSource.bones.Length; i++)
{
var bone = FindTransfomInChildRecursive(root, skinnedMeshSource.bones[i].name);
if (bone == null)
{
Debug.LogErrorFormat("Can't find bone with name {0}", skinnedMeshSource.bones[i].name);
return;
}
bones[i] = bone;
}
thisSkinnedMesh.rootBone = bones[0];
thisSkinnedMesh.bones = bones;
isBinded = true;
lastBindedMeshName = thisSkinnedMesh.sharedMesh.name;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
EditorUtility.SetDirty(this);
EditorUtility.SetDirty(thisSkinnedMesh);
}
#endif
}
private Transform FindTransfomInChildRecursive(Transform transform, string transformName)
{
if (transform.name == transformName)
{
return transform;
}
var childCount = transform.childCount;
if (transform.childCount > 0)
{
Transform result;
for (int i = 0; i < childCount; i++)
{
result = FindTransfomInChildRecursive(transform.GetChild(i), transformName);
if (result != null)
{
return result;
}
}
}
return null;
}
#if UNITY_EDITOR
private void OnValidate()
{
if (forceRebind)
{
forceRebind = false;
isBinded = false;
}
if (thisSkinnedMesh == null)
{
isBinded = false;
thisSkinnedMesh = GetComponent();
TryLoadSourceSkinnedMeshRenderer();
}
if (isBinded && thisSkinnedMesh != null)
{
if (string.IsNullOrEmpty(lastBindedMeshName) || thisSkinnedMesh.sharedMesh.name != lastBindedMeshName)
{
TryLoadSourceSkinnedMeshRenderer();
isBinded = false;
}
}
BindItemToBones();
}
private void TryLoadSourceSkinnedMeshRenderer()
{
if (thisSkinnedMesh != null && thisSkinnedMesh.sharedMesh != null && skinnedMeshSource == null)
{
var assetPath = AssetDatabase.GetAssetPath(thisSkinnedMesh.sharedMesh);
var sourceFBX = AssetDatabase.LoadAssetAtPath(assetPath);
var sourceAsset = sourceFBX.transform.Find(thisSkinnedMesh.sharedMesh.name);
if (sourceAsset != null)
{
skinnedMeshSource = sourceAsset.GetComponent();
if (!Application.isPlaying)
{
EditorUtility.SetDirty(this);
}
}
}
}
#endif
}
}