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

280 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Collections.Generic;
using System.IO;
using cfg.VehicleCfg;
using Framework;
using Gameplay.Utils;
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;
private string[] _bodyAniNames = new string[]
{
"dead",
"idle",
"move",
"restart",
"stop",
// "skill",
};
public void Init()
{
var prefabPath = PathEx.GetVehicleSrcModelPath(vehicleConfig.PrefabPath);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (prefab == null)
{
errorInfo = $"载具预制体不存在:{prefabPath}";
return;
}
_prefabPath = prefabPath;
var prefabName = prefab.name;
var splits = prefabName.Split('_');
if (splits.Length != 3)
{
errorInfo = $"prefab命名错误{prefabName}";
return;
}
bodyName = splits[1];
// 检查所有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;
}
}
}
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);
if (loadPrefab == null)
{
Debug.LogError($"找不到载具预制体:{_prefabPath}");
return;
}
loadPrefab = Object.Instantiate(loadPrefab);
_HandlePrefab(loadPrefab, savePath);
var savePrefabPath = $"{savePath}/vehicle_{vehicleConfig.ID}.prefab";
PrefabUtility.SaveAsPrefabAsset(loadPrefab, savePrefabPath);
// 销毁prefab
Object.DestroyImmediate(loadPrefab);
Debug.Log($"生成载具预制体:{savePrefabPath}");
}
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;
}
// 删除炮台
var findBattery = _SearchByName(allTrans, "Battery_point01");
if (findBattery != null && findBattery.childCount > 0)
{
var child = findBattery.GetChild(0);
if (child != null)
{
Object.DestroyImmediate(child.gameObject);
}
}
// 处理body
_HandleBody(savePath, findBody);
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;
}
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);
_CompressOverrideController(overrideController);
// 保存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;
}
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);
}
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);
}
}
}
}