NLDClient-yudde/ProjectNLD/Assets/Editor/VehicleBuilder/VehicleBuildData.cs

280 lines
11 KiB
C#
Raw Normal View History

2024-01-11 13:33:30 +08:00
using System.Collections.Generic;
using System.IO;
using cfg.VehicleCfg;
using Framework;
using Gameplay.Utils;
2024-01-11 13:33:30 +08:00
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
namespace VehicleBuilder
{
/// <summary>
/// 所有动作都可以没有
/// body使用的animator Assets/Art/Animations/animator/Vehicle/animator_vehicle.controller
/// body需要的动作 Assets/Art/Animations/Vehicle/C00001/ani_C00001_D_dead.fbx
/// dead
/// idle
/// move
/// restart
/// stop
/// skill
/// battery使用的animator Assets/Art/Animations/animator/Battery/animator_battery.controller
/// battery需要的动作 Assets/Art/Animations/Battery/R00001/ani_R00001_attack01.fbx
/// attack01
/// idle
/// skill
/// </summary>
public class VehicleBuildData
{
public DataVehicle vehicleConfig;
public bool isChecked;
public string bodyName;
public string batteryName;
public string errorInfo;
private string _prefabPath;
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
private string[] _bodyAniNames = new string[]
{
"dead",
"idle",
"move",
"restart",
"stop",
// "skill",
};
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
public void Init()
{
var prefabPath = PathEx.GetVehicleSrcModelPath(vehicleConfig.PrefabPath);
2024-01-11 13:33:30 +08:00
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (prefab == null)
{
errorInfo = $"载具预制体不存在:{prefabPath}";
return;
}
_prefabPath = prefabPath;
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
var prefabName = prefab.name;
var splits = prefabName.Split('_');
if (splits.Length != 3)
2024-01-11 13:33:30 +08:00
{
errorInfo = $"prefab命名错误{prefabName}";
return;
}
bodyName = splits[1];
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
// 检查所有bodyanims
for (var i = 0; i < _bodyAniNames.Length; ++i)
{
var bodyAnimName = _bodyAniNames[i];
var combinePath = $"Assets/Art/Animations/Vehicle/{bodyName}/ani_{bodyName}_D_{bodyAnimName}.fbx";
var loadAnim = AssetDatabase.LoadAssetAtPath<AnimationClip>(combinePath);
if (loadAnim == null)
{
errorInfo = $"不存在需求动作: {combinePath}";
return;
}
}
}
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
public void DoBuild()
{
var savePath = string.Format(Constants.VEHICLE_OUTPUT_PATH, vehicleConfig.ID);
var realPath = savePath.Replace("Assets", Application.dataPath);
if (!Directory.Exists(realPath))
{
Directory.CreateDirectory(realPath);
}
var loadPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(_prefabPath);
2024-09-25 17:29:25 +08:00
if (loadPrefab == null)
{
Debug.LogError($"找不到载具预制体:{_prefabPath}");
return;
}
loadPrefab = Object.Instantiate(loadPrefab);
2024-01-11 13:33:30 +08:00
_HandlePrefab(loadPrefab, savePath);
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
var savePrefabPath = $"{savePath}/vehicle_{vehicleConfig.ID}.prefab";
PrefabUtility.SaveAsPrefabAsset(loadPrefab, savePrefabPath);
2024-09-26 16:47:52 +08:00
2024-09-25 17:29:25 +08:00
// 销毁prefab
Object.DestroyImmediate(loadPrefab);
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
Debug.Log($"生成载具预制体:{savePrefabPath}");
}
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
private void _HandlePrefab(GameObject prefab, string savePath)
{
var allTrans = new List<Transform>();
_DeepSearchTrans(prefab.transform, allTrans);
var findBody = _SearchByName(allTrans, bodyName);
if (findBody == null)
{
Debug.LogError($"找不到body{bodyName}");
return;
}
2024-09-25 17:29:25 +08:00
// 删除炮台
var findBattery = _SearchByName(allTrans, "Battery_point01");
2024-09-26 16:47:52 +08:00
if (findBattery != null && findBattery.childCount > 0)
2024-01-11 13:33:30 +08:00
{
2024-09-25 17:29:25 +08:00
var child = findBattery.GetChild(0);
if (child != null)
{
Object.DestroyImmediate(child.gameObject);
}
2024-01-11 13:33:30 +08:00
}
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
// 处理body
_HandleBody(savePath, findBody);
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
EditorUtility.SetDirty(prefab);
AssetDatabase.SaveAssets();
}
private void _HandleBattery(string savePath,
Transform findBattery)
{
var srcController = AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/Art/Animations/animator/Battery/animator_battery.controller");
if (srcController == null)
{
Debug.LogError($"找不到animator_battery.controller");
return;
}
// 创建一个overrideController
var overrideController = new AnimatorOverrideController();
overrideController.runtimeAnimatorController = srcController;
// 设置动作
var kvList = new List<KeyValuePair<AnimationClip, AnimationClip>>();
var oldClips = overrideController.animationClips;
for (int i = 0; i < oldClips.Length; i++)
{
var oldClip = oldClips[i];
var oldClipName = oldClip.name;
// ani_R00001_attack01
var splits = oldClipName.Split('_');
var finalName = splits[^1];
var newClipPath = $"Assets/Art/Animations/Battery/{batteryName}/ani_{batteryName}_{finalName}.fbx";
var newClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(newClipPath);
if (newClip == null)
{
Debug.LogError($"找不到动作:{newClipPath}");
continue;
}
kvList.Add(new KeyValuePair<AnimationClip, AnimationClip>(oldClip, newClip));
}
overrideController.ApplyOverrides(kvList);
// 保存controller
var saveControllerPath = $"{savePath}/ov_battery_{vehicleConfig.ID}.controller";
AssetDatabase.CreateAsset(overrideController, saveControllerPath);
AssetDatabase.Refresh();
overrideController = AssetDatabase.LoadAssetAtPath<AnimatorOverrideController>(saveControllerPath);
// 设置battery的animator
var batteryAnimator = findBattery.GetComponent<Animator>();
if (batteryAnimator == null)
{
batteryAnimator = findBattery.gameObject.AddComponent<Animator>();
}
batteryAnimator.runtimeAnimatorController = overrideController;
batteryAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
}
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
private void _HandleBody(string savePath,
Transform findBody)
{
var srcController = AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/Art/Animations/animator/Vehicle/animator_vehicle.controller");
if (srcController == null)
{
Debug.LogError($"找不到animator_vehicle.controller");
return;
}
// 创建一个overrideController
var overrideController = new AnimatorOverrideController();
overrideController.runtimeAnimatorController = srcController;
// 设置动作
var kvList = new List<KeyValuePair<AnimationClip, AnimationClip>>();
var oldClips = overrideController.animationClips;
for (int i = 0; i < oldClips.Length; i++)
{
var oldClip = oldClips[i];
var oldClipName = oldClip.name;
// ani_C00001_D_idle
var splits = oldClipName.Split('_');
var finalName = splits[^1];
var newClipPath = $"Assets/Art/Animations/Vehicle/{bodyName}/ani_{bodyName}_D_{finalName}.fbx";
var newClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(newClipPath);
if (newClip == null)
{
Debug.LogError($"找不到动作:{newClipPath}");
continue;
}
kvList.Add(new KeyValuePair<AnimationClip, AnimationClip>(oldClip, newClip));
}
overrideController.ApplyOverrides(kvList);
2024-11-07 16:41:41 +08:00
_CompressOverrideController(overrideController);
2024-01-11 13:33:30 +08:00
// 保存controller
var saveControllerPath = $"{savePath}/ov_vehicle_{vehicleConfig.ID}.controller";
AssetDatabase.CreateAsset(overrideController, saveControllerPath);
AssetDatabase.Refresh();
overrideController = AssetDatabase.LoadAssetAtPath<AnimatorOverrideController>(saveControllerPath);
// 设置body的animator
var bodyAnimator = findBody.GetComponent<Animator>();
if (bodyAnimator == null)
{
bodyAnimator = findBody.gameObject.AddComponent<Animator>();
}
bodyAnimator.runtimeAnimatorController = overrideController;
bodyAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
}
2024-11-07 16:41:41 +08:00
private void _CompressOverrideController(AnimatorOverrideController overrideController)
{
var overrideClips = new List<KeyValuePair<AnimationClip, AnimationClip>>();
overrideController.GetOverrides(overrideClips);
var newClips = new List<KeyValuePair<AnimationClip, AnimationClip>>();
foreach (var oldKV in overrideClips)
{
var srcClip = oldKV.Key;
var dstClip = oldKV.Value;
if (dstClip == null)
{
dstClip = srcClip;
}
var newClip = LTCompressor.AutoCompress(dstClip);
newClips.Add(new KeyValuePair<AnimationClip, AnimationClip>(srcClip, newClip));
}
overrideController.ApplyOverrides(newClips);
}
2024-01-11 13:33:30 +08:00
private static Transform _SearchByName(List<Transform> searchList, string name)
{
for (int i = 0; i < searchList.Count; i++)
{
var trans = searchList[i];
if (trans.name == name)
{
return trans;
}
}
return null;
}
private static void _DeepSearchTrans(Transform searchTrans, List<Transform> result)
{
result.Add(searchTrans);
for (int i = 0; i < searchTrans.childCount; i++)
{
var child = searchTrans.GetChild(i);
_DeepSearchTrans(child, result);
}
}
2024-09-26 16:47:52 +08:00
2024-01-11 13:33:30 +08:00
}
}