Files
Fishing2NetTest/Assets/Scripts/Editor/MeshToSkinnedMeshConverter.cs
2026-03-05 18:07:55 +08:00

237 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEditor;
using UnityEngine;
public class MeshToSkinnedMeshConverter : EditorWindow
{
[MenuItem("Tools/Mesh to SkinnedMesh Converter")]
public static void ShowWindow()
{
GetWindow<MeshToSkinnedMeshConverter>("Mesh to SkinnedMesh Converter");
}
private GameObject selectedObject;
private Transform rootBone;
void OnGUI()
{
GUILayout.Label("Convert MeshRenderer to SkinnedMeshRenderer", EditorStyles.boldLabel);
selectedObject = (GameObject)EditorGUILayout.ObjectField("GameObject", selectedObject, typeof(GameObject), true);
rootBone = (Transform)EditorGUILayout.ObjectField("Root Bone", rootBone, typeof(Transform), true);
if (selectedObject != null)
{
MeshRenderer meshRenderer = selectedObject.GetComponent<MeshRenderer>();
if (meshRenderer == null)
{
EditorGUILayout.HelpBox("Selected GameObject does not have a MeshRenderer component.", MessageType.Warning);
}
else
{
if (GUILayout.Button("Convert"))
{
ConvertToSkinnedMeshRenderer();
}
}
}
else
{
EditorGUILayout.HelpBox("Please select a GameObject.", MessageType.Info);
}
}
void ConvertToSkinnedMeshRenderer()
{
if (selectedObject == null) return;
MeshRenderer meshRenderer = selectedObject.GetComponent<MeshRenderer>();
MeshFilter meshFilter = selectedObject.GetComponent<MeshFilter>();
if (meshRenderer != null && meshFilter != null)
{
// 保存原来的网格和材质
Mesh mesh = meshFilter.sharedMesh;
Material[] materials = meshRenderer.sharedMaterials;
// 移除MeshRenderer和MeshFilter组件
DestroyImmediate(meshRenderer);
DestroyImmediate(meshFilter);
// 添加SkinnedMeshRenderer组件
SkinnedMeshRenderer skinnedMeshRenderer = selectedObject.AddComponent<SkinnedMeshRenderer>();
// 设置SkinnedMeshRenderer的网格
skinnedMeshRenderer.sharedMesh = mesh;
// 设置SkinnedMeshRenderer的材质
skinnedMeshRenderer.sharedMaterials = materials;
// 自动查找骨骼
Transform[] bones = FindBones(rootBone);
skinnedMeshRenderer.rootBone = rootBone;
skinnedMeshRenderer.bones = bones;
// 设置绑定姿态
skinnedMeshRenderer.sharedMesh.bindposes = GetBindPoses(bones);
// 设置骨骼权重
skinnedMeshRenderer.sharedMesh.boneWeights = GetBoneWeights(mesh, bones);
Debug.Log("Conversion complete!");
}
else
{
Debug.LogWarning("Selected GameObject does not have a MeshRenderer or MeshFilter component.");
}
}
Transform[] FindBones(Transform root)
{
if (root == null) return new Transform[0];
return root.GetComponentsInChildren<Transform>();
}
Matrix4x4[] GetBindPoses(Transform[] bones)
{
Matrix4x4[] bindPoses = new Matrix4x4[bones.Length];
for (int i = 0; i < bones.Length; i++)
{
bindPoses[i] = bones[i].worldToLocalMatrix * rootBone.localToWorldMatrix;
}
return bindPoses;
}
BoneWeight[] GetBoneWeights(Mesh mesh, Transform[] bones)
{
BoneWeight[] boneWeights = new BoneWeight[mesh.vertexCount];
// 这里假设每个顶点都绑定到第一个骨骼上权重为1
for (int i = 0; i < mesh.vertexCount; i++)
{
boneWeights[i].boneIndex0 = 0;
boneWeights[i].weight0 = 1.0f;
}
// 如果你的模型有复杂的骨骼权重分布,可以在这里实现
// 例如:
// for (int i = 0; i < mesh.vertexCount; i++)
// {
// boneWeights[i].boneIndex0 = ...;
// boneWeights[i].weight0 = ...;
// boneWeights[i].boneIndex1 = ...;
// boneWeights[i].weight1 = ...;
// boneWeights[i].boneIndex2 = ...;
// boneWeights[i].weight2 = ...;
// boneWeights[i].boneIndex3 = ...;
// boneWeights[i].weight3 = ...;
// }
return boneWeights;
}
}
// using System.Collections.Generic;
// using UnityEditor;
// using UnityEngine;
//
// public class MeshToSkinnedMeshConverter : EditorWindow
// {
// [MenuItem("Tools/Mesh to SkinnedMesh Converter")]
// public static void ShowWindow()
// {
// GetWindow<MeshToSkinnedMeshConverter>("Mesh to SkinnedMesh Converter");
// }
//
// private GameObject selectedObject;
// private Transform rootBone;
// private Transform[] bones;
//
// void OnGUI()
// {
// GUILayout.Label("Convert MeshRenderer to SkinnedMeshRenderer", EditorStyles.boldLabel);
//
// selectedObject =
// (GameObject)EditorGUILayout.ObjectField("GameObject", selectedObject, typeof(GameObject), true);
// rootBone = (Transform)EditorGUILayout.ObjectField("Root Bone", rootBone, typeof(Transform), true);
//
// if (selectedObject != null)
// {
// MeshRenderer meshRenderer = selectedObject.GetComponent<MeshRenderer>();
// if (meshRenderer == null)
// {
// EditorGUILayout.HelpBox("Selected GameObject does not have a MeshRenderer component.",
// MessageType.Warning);
// }
// else
// {
// if (GUILayout.Button("Convert"))
// {
// ConvertToSkinnedMeshRenderer();
// }
// }
// }
// else
// {
// EditorGUILayout.HelpBox("Please select a GameObject.", MessageType.Info);
// }
// }
//
// void ConvertToSkinnedMeshRenderer()
// {
// if (selectedObject == null) return;
//
// MeshRenderer meshRenderer = selectedObject.GetComponent<MeshRenderer>();
// MeshFilter meshFilter = selectedObject.GetComponent<MeshFilter>();
//
// if (meshRenderer != null && meshFilter != null)
// {
// // 保存原来的网格和材质
// Mesh mesh = meshFilter.sharedMesh;
// Material[] materials = meshRenderer.sharedMaterials;
//
// // 移除MeshRenderer和MeshFilter组件
// DestroyImmediate(meshRenderer);
// DestroyImmediate(meshFilter);
//
// // 添加SkinnedMeshRenderer组件
// SkinnedMeshRenderer skinnedMeshRenderer = selectedObject.AddComponent<SkinnedMeshRenderer>();
//
// // 设置SkinnedMeshRenderer的网格
// skinnedMeshRenderer.sharedMesh = mesh;
//
// // 设置SkinnedMeshRenderer的材质
// skinnedMeshRenderer.sharedMaterials = materials;
//
// // 自动查找骨骼
// List<Transform> bonesList = new List<Transform>();
// GetRodBones(rootBone.transform, bonesList);
// skinnedMeshRenderer.rootBone = rootBone;
// skinnedMeshRenderer.bones = bonesList.ToArray();
//
// Debug.Log("Conversion complete!");
// }
// else
// {
// Debug.LogWarning("Selected GameObject does not have a MeshRenderer or MeshFilter component.");
// }
// }
//
// private static void GetRodBones(Transform parent, List<Transform> list)
// {
// if (parent.childCount < 1) return;
// foreach (Transform child in parent)
// {
// if (child.name.StartsWith("rod"))
// {
// list.Add(child);
// }
//
// if (child.childCount > 0)
// {
// GetRodBones(child, list);
// }
// }
// }
// }