Загрузка данных


using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;

#if UNITY_EDITOR
public class AvatarTransfer : MonoBehaviour
{
    [Header("Source → Target")]
    public GameObject source;   // Kipfelv20
    public GameObject target;   // Kipfel

    [ContextMenu("Transfer Everything")]
    public void TransferEverything()
    {
        if (source == null || target == null)
        {
            Debug.LogError("Назначь Source и Target!");
            return;
        }

        Undo.RegisterCompleteObjectUndo(target, "Avatar Transfer");

        // 1. Копируем все дочерние объекты (одежда, волосы, аксессуары и т.д.)
        TransferChildren(source.transform, target.transform);

        // 2. Копируем Animator + Avatar
        TransferAnimator(source, target);

        // 3. Копируем все SkinnedMeshRenderer + BlendShapes
        TransferSkinnedMeshes(source, target);

        // 4. Копируем обычные MeshRenderer
        TransferMeshRenderers(source, target);

        // 5. Копируем PhysBones / Constraints / Colliders и прочие компоненты
        TransferComponents(source, target);

        Debug.Log("<color=lime>Перенос завершён!</color>");
        EditorUtility.SetDirty(target);
    }

    void TransferChildren(Transform srcRoot, Transform dstRoot)
    {
        // Удаляем всё, что уже есть на таргете (кроме арматуры)
        List<Transform> toDestroy = new List<Transform>();
        foreach (Transform child in dstRoot)
        {
            if (child.name != "Armature" && child.name != "armature" && 
                !child.name.ToLower().Contains("body") && 
                !child.name.ToLower().Contains("hips"))
            {
                toDestroy.Add(child);
            }
        }
        foreach (var t in toDestroy) DestroyImmediate(t.gameObject);

        // Копируем все дочерние объекты с сорса
        foreach (Transform child in srcRoot)
        {
            if (child.name.ToLower().Contains("armature") || 
                child.name.ToLower().Contains("body") ||
                child.name.ToLower().Contains("hips") ||
                child.name.ToLower().Contains("spine"))
                continue; // арматуру не трогаем

            GameObject copy = Instantiate(child.gameObject, dstRoot);
            copy.name = child.name;
            copy.transform.localPosition = child.localPosition;
            copy.transform.localRotation = child.localRotation;
            copy.transform.localScale = child.localScale;
        }
    }

    void TransferAnimator(GameObject src, GameObject dst)
    {
        Animator srcAnim = src.GetComponent<Animator>();
        if (srcAnim == null) return;

        Animator dstAnim = dst.GetComponent<Animator>();
        if (dstAnim == null) dstAnim = dst.AddComponent<Animator>();

        dstAnim.runtimeAnimatorController = srcAnim.runtimeAnimatorController;
        dstAnim.avatar = srcAnim.avatar;
        dstAnim.applyRootMotion = srcAnim.applyRootMotion;
        dstAnim.updateMode = srcAnim.updateMode;
        dstAnim.cullingMode = srcAnim.cullingMode;
    }

    void TransferSkinnedMeshes(GameObject src, GameObject dst)
    {
        SkinnedMeshRenderer[] srcMeshes = src.GetComponentsInChildren<SkinnedMeshRenderer>(true);
        
        foreach (var srcMesh in srcMeshes)
        {
            // Ищем такой же объект на таргете по имени
            Transform dstTr = FindChildRecursive(dst.transform, srcMesh.name);
            if (dstTr == null)
            {
                // Если не нашли — создаём
                GameObject go = new GameObject(srcMesh.name);
                go.transform.SetParent(dst.transform);
                go.transform.localPosition = srcMesh.transform.localPosition;
                go.transform.localRotation = srcMesh.transform.localRotation;
                go.transform.localScale = srcMesh.transform.localScale;
                dstTr = go.transform;
            }

            SkinnedMeshRenderer dstMesh = dstTr.GetComponent<SkinnedMeshRenderer>();
            if (dstMesh == null) dstMesh = dstTr.gameObject.AddComponent<SkinnedMeshRenderer>();

            // Копируем всё
            dstMesh.sharedMesh = srcMesh.sharedMesh;
            dstMesh.sharedMaterials = srcMesh.sharedMaterials;
            dstMesh.rootBone = FindBone(dst.transform, srcMesh.rootBone);
            dstMesh.bones = srcMesh.bones.Select(b => FindBone(dst.transform, b)).ToArray();
            dstMesh.updateWhenOffscreen = srcMesh.updateWhenOffscreen;
            dstMesh.quality = srcMesh.quality;
            dstMesh.skinnedMotionVectors = srcMesh.skinnedMotionVectors;

            // BlendShapes
            for (int i = 0; i < srcMesh.sharedMesh.blendShapeCount; i++)
            {
                float weight = srcMesh.GetBlendShapeWeight(i);
                dstMesh.SetBlendShapeWeight(i, weight);
            }
        }
    }

    void TransferMeshRenderers(GameObject src, GameObject dst)
    {
        MeshRenderer[] srcRends = src.GetComponentsInChildren<MeshRenderer>(true);
        foreach (var srcRend in srcRends)
        {
            Transform dstTr = FindChildRecursive(dst.transform, srcRend.name);
            if (dstTr == null) continue;

            MeshRenderer dstRend = dstTr.GetComponent<MeshRenderer>();
            if (dstRend == null) dstRend = dstTr.gameObject.AddComponent<MeshRenderer>();

            MeshFilter srcFilter = srcRend.GetComponent<MeshFilter>();
            MeshFilter dstFilter = dstTr.GetComponent<MeshFilter>();
            if (dstFilter == null) dstFilter = dstTr.gameObject.AddComponent<MeshFilter>();

            if (srcFilter != null) dstFilter.sharedMesh = srcFilter.sharedMesh;
            dstRend.sharedMaterials = srcRend.sharedMaterials;
        }
    }

    void TransferComponents(GameObject src, GameObject dst)
    {
        // Копируем все компоненты с корня
        Component[] components = src.GetComponents<Component>();
        foreach (var comp in components)
        {
            if (comp is Transform || comp is Animator) continue;
            
            // Пробуем скопировать
            System.Type type = comp.GetType();
            Component newComp = dst.GetComponent(type);
            if (newComp == null) newComp = dst.AddComponent(type);

            // Копируем через SerializedObject (самый надёжный способ)
            EditorUtility.CopySerialized(comp, newComp);
        }
    }

    Transform FindChildRecursive(Transform parent, string name)
    {
        if (parent.name == name) return parent;
        foreach (Transform child in parent)
        {
            Transform found = FindChildRecursive(child, name);
            if (found != null) return found;
        }
        return null;
    }

    Transform FindBone(Transform root, Transform originalBone)
    {
        if (originalBone == null) return null;
        return FindChildRecursive(root, originalBone.name);
    }
}
#endif