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

291 lines
11 KiB
C#
Raw 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",
};
private string[] _batteryAniNames = new string[]
{
"attack01",
"idle",
// "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 != 5)
{
errorInfo = $"prefab命名错误:{prefabName}";
return;
}
bodyName = splits[1];
batteryName = splits[3];
// 检查所有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;
}
}
// 检查所有batteryanims
for (var i = 0; i < _batteryAniNames.Length; ++i)
{
var batteryAnimName = _batteryAniNames[i];
var combinePath = $"Assets/Art/Animations/Battery/{batteryName}/ani_{batteryName}_{batteryAnimName}.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);
_HandlePrefab(loadPrefab, savePath);
var savePrefabPath = $"{savePath}/vehicle_{vehicleConfig.ID}.prefab";
PrefabUtility.SaveAsPrefabAsset(loadPrefab, savePrefabPath);
_AddToAddressables(savePrefabPath);
Debug.Log($"生成载具预制体:{savePrefabPath}");
}
private void _AddToAddressables(string assetPath)
{
#if USE_ADDRESSABLES
// 获取 AddressableAssetSettings
var settings = AddressableAssetSettingsDefaultObject.Settings;
// 获取或创建一个资源组
var group = settings.FindGroup("SplitCharacter");
if (group == null)
{
Debug.LogError("找不到资源组:SplitCharacter");
return;
}
// 创建或移动条目
var guid = AssetDatabase.AssetPathToGUID(assetPath);
settings.CreateOrMoveEntry(guid, group);
#endif
}
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, batteryName);
if (findBattery == null)
{
Debug.LogError($"找不到battery:{batteryName}");
return;
}
// 处理body
_HandleBody(savePath, findBody);
// 处理battery
_HandleBattery(savePath, findBattery);
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);
// 保存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 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);
}
}
}
}