You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity编辑器中更换玩家子物体角色模型

解决方案

我们可以通过编写编辑器扩展脚本,给Player GameObject添加自定义Inspector面板,实现拖放预制体一键替换角色模型,并自动配置Animator和动画控制器。

步骤1:编写角色替换编辑器脚本

创建新的C#脚本,必须放在项目的Editor文件夹下,代码如下:

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(PlayerController))]
public class PlayerCharacterReplacer : Editor
{
    private GameObject newCharacterPrefab;

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        PlayerController player = (PlayerController)target;

        // 预制体拖放区域
        newCharacterPrefab = (GameObject)EditorGUILayout.ObjectField("替换角色预制体", newCharacterPrefab, typeof(GameObject), false);

        if (GUILayout.Button("替换角色模型"))
        {
            if (newCharacterPrefab == null)
            {
                EditorUtility.DisplayDialog("提示", "请先拖入角色预制体", "确定");
                return;
            }

            // 销毁旧角色模型(通过标签识别)
            foreach (Transform child in player.transform)
            {
                if (child.CompareTag("CharacterModel"))
                {
                    DestroyImmediate(child.gameObject);
                }
            }

            // 实例化新角色预制体
            GameObject newCharacter = Instantiate(newCharacterPrefab, player.transform);
            newCharacter.tag = "CharacterModel";
            newCharacter.transform.localPosition = Vector3.zero;
            newCharacter.transform.localRotation = Quaternion.identity;
            newCharacter.transform.localScale = Vector3.one;

            // 配置Animator与动画控制器
            Animator animator = newCharacter.GetComponent<Animator>();
            animator = animator ?? newCharacter.AddComponent<Animator>();
            
            RuntimeAnimatorController animController = (RuntimeAnimatorController)Resources.Load("Animations/PlayerAnimation");
            if (animController != null)
            {
                animator.runtimeAnimatorController = animController;
            }
            else
            {
                EditorUtility.DisplayDialog("提示", "未找到PlayerAnimation动画控制器", "确定");
            }

            // 自动给PlayerAnimations脚本绑定Animator
            PlayerAnimations playerAnim = player.GetComponent<PlayerAnimations>();
            if (playerAnim != null)
            {
                playerAnim.animator = animator;
            }
        }
    }
}

步骤2:修改原创建脚本,添加标签识别

修改你现有的CreatePlayer脚本,给生成的角色模型添加专属标签,方便后续识别销毁:

using UnityEditor;
using UnityEngine;

public class CreatePlayer : MonoBehaviour
{
    [MenuItem("GameObject/Create Player", false, 10)]
    static void Create()
    {
        GameObject player = new GameObject("Hero");
        player.tag = "Player";

        // 自动创建CharacterModel标签(如果不存在)
        if (!TagExists("CharacterModel"))
        {
            AddTag("CharacterModel");
        }

        GameObject character = Instantiate((GameObject)Resources.Load("SampleCharacter"));
        character.tag = "CharacterModel";
        character.transform.parent = player.transform;
        character.transform.localPosition = Vector3.zero;
        character.transform.localRotation = Quaternion.identity;

        // 原有配置代码保留
        CharacterController cc = player.AddComponent<CharacterController>();
        cc.center = new Vector3(0f, 0.9f, 0f);
        cc.radius = 0.2f;
        cc.height = 1.9f;
        player.AddComponent<PlayerMovement>();
        Animator animator = character.AddComponent<Animator>();
        animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load("Animations/PlayerAnimation");
        player.AddComponent<PlayerAnimations>();
        player.AddComponent<PlayerHealth>();

        // 添加PlayerController组件(作为编辑器扩展的绑定载体)
        if (!player.TryGetComponent(out PlayerController _))
        {
            player.AddComponent<PlayerController>();
        }

        Camera.main.gameObject.AddComponent<CameraController>();
        Camera.main.GetComponent<CameraController>().followTarget = player.transform;
    }

    // 工具方法:检查标签是否存在
    private static bool TagExists(string tagName)
    {
        foreach (var tag in UnityEditorInternal.InternalEditorUtility.tags)
        {
            if (tag == tagName) return true;
        }
        return false;
    }

    // 工具方法:添加标签
    private static void AddTag(string tagName)
    {
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        SerializedProperty tagsProp = tagManager.FindProperty("tags");

        for (int i = 0; i < tagsProp.arraySize; i++)
        {
            if (tagsProp.GetArrayElementAtIndex(i).stringValue == tagName) return;
        }

        tagsProp.InsertArrayElementAtIndex(tagsProp.arraySize);
        tagsProp.GetArrayElementAtIndex(tagsProp.arraySize - 1).stringValue = tagName;
        tagManager.ApplyModifiedProperties();
    }
}

步骤3:创建PlayerController空脚本

创建一个空的C#脚本,作为编辑器扩展的绑定载体:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // 可在此添加玩家核心控制逻辑,或留空作为编辑器扩展的绑定目标
}

使用方法

  1. 通过顶部菜单GameObject/Create Player生成玩家对象
  2. 选中Player对象,在Inspector面板找到PlayerController组件区域
  3. 将目标角色预制体拖入「替换角色预制体」字段
  4. 点击「替换角色模型」按钮,自动完成模型替换、Animator配置及动画控制器绑定

如果需要适配不同角色的动画逻辑,可将RuntimeAnimatorController改为public字段放在PlayerController中,直接在Inspector拖入对应动画控制器即可。

内容的提问来源于stack exchange,提问作者prkash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:31:35