using System.Collections.Generic;
using System.IO;
using cfg.VehicleCfg;
using Framework;
using Gameplay.Utils;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
namespace VehicleBuilder
{
///
/// 所有动作都可以没有
/// 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
///
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(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(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(_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();
_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("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>();
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(newClipPath);
if (newClip == null)
{
Debug.LogError($"找不到动作:{newClipPath}");
continue;
}
kvList.Add(new KeyValuePair(oldClip, newClip));
}
overrideController.ApplyOverrides(kvList);
// 保存controller
var saveControllerPath = $"{savePath}/ov_battery_{vehicleConfig.ID}.controller";
AssetDatabase.CreateAsset(overrideController, saveControllerPath);
AssetDatabase.Refresh();
overrideController = AssetDatabase.LoadAssetAtPath(saveControllerPath);
// 设置battery的animator
var batteryAnimator = findBattery.GetComponent();
if (batteryAnimator == null)
{
batteryAnimator = findBattery.gameObject.AddComponent();
}
batteryAnimator.runtimeAnimatorController = overrideController;
batteryAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
}
private void _HandleBody(string savePath,
Transform findBody)
{
var srcController = AssetDatabase.LoadAssetAtPath("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>();
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(newClipPath);
if (newClip == null)
{
Debug.LogError($"找不到动作:{newClipPath}");
continue;
}
kvList.Add(new KeyValuePair(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(saveControllerPath);
// 设置body的animator
var bodyAnimator = findBody.GetComponent();
if (bodyAnimator == null)
{
bodyAnimator = findBody.gameObject.AddComponent();
}
bodyAnimator.runtimeAnimatorController = overrideController;
bodyAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
}
private void _CompressOverrideController(AnimatorOverrideController overrideController)
{
var overrideClips = new List>();
overrideController.GetOverrides(overrideClips);
var newClips = new List>();
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(srcClip, newClip));
}
overrideController.ApplyOverrides(newClips);
}
private static Transform _SearchByName(List 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 result)
{
result.Add(searchTrans);
for (int i = 0; i < searchTrans.childCount; i++)
{
var child = searchTrans.GetChild(i);
_DeepSearchTrans(child, result);
}
}
}
}