如何在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 { // 可在此添加玩家核心控制逻辑,或留空作为编辑器扩展的绑定目标 }
使用方法
- 通过顶部菜单
GameObject/Create Player生成玩家对象 - 选中Player对象,在Inspector面板找到
PlayerController组件区域 - 将目标角色预制体拖入「替换角色预制体」字段
- 点击「替换角色模型」按钮,自动完成模型替换、Animator配置及动画控制器绑定
如果需要适配不同角色的动画逻辑,可将RuntimeAnimatorController改为public字段放在PlayerController中,直接在Inspector拖入对应动画控制器即可。
内容的提问来源于stack exchange,提问作者prkash
相关产品推荐
相关产品推荐

