modular-avatar/Editor/ErrorReporting/ComponentValidation.cs

161 lines
5.6 KiB
C#
Raw Permalink Normal View History

2023-01-19 20:32:44 +08:00
using System.Collections.Generic;
using nadena.dev.modular_avatar.core;
using nadena.dev.ndmf;
#if MA_VRCSDK3_AVATARS
using nadena.dev.modular_avatar.core.menu;
#endif
2023-01-19 20:32:44 +08:00
using UnityEngine;
namespace nadena.dev.modular_avatar.editor.ErrorReporting
{
internal static class ComponentValidation
{
/// <summary>
/// Validates the provided tag component.
/// </summary>
/// <param name="tagComponent"></param>
/// <returns>Null if valid, otherwise a list of configuration errors</returns>
internal static void CheckComponent(this AvatarTagComponent tagComponent)
2023-01-19 20:32:44 +08:00
{
ErrorReport.WithContextObject(tagComponent, () =>
2023-01-19 20:32:44 +08:00
{
switch (tagComponent)
{
case ModularAvatarBlendshapeSync bs:
CheckInternal(bs);
break;
case ModularAvatarBoneProxy bp:
CheckInternal(bp);
break;
#if MA_VRCSDK3_AVATARS
case ModularAvatarMenuInstaller mi:
CheckInternal(mi);
break;
case ModularAvatarMergeAnimator obj:
CheckInternal(obj);
break;
#endif
case ModularAvatarMergeArmature obj:
CheckInternal(obj);
break;
default:
return;
}
});
2023-01-19 20:32:44 +08:00
}
internal static void ValidateAll(GameObject root)
2023-01-19 20:32:44 +08:00
{
foreach (var component in root.GetComponentsInChildren<AvatarTagComponent>(true))
{
component.CheckComponent();
2023-01-19 20:32:44 +08:00
}
}
private static void CheckInternal(ModularAvatarBlendshapeSync bs)
{
2023-01-19 20:32:44 +08:00
var localMesh = bs.GetComponent<SkinnedMeshRenderer>();
if (localMesh == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_local_renderer", bs);
2023-01-19 20:32:44 +08:00
}
if (localMesh.sharedMesh == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_local_mesh", bs);
2023-01-19 20:32:44 +08:00
}
if (bs.Bindings == null || bs.Bindings.Count == 0)
{
BuildReport.Log(ErrorSeverity.Information,"validation.blendshape_sync.no_bindings", bs);
2023-01-19 20:32:44 +08:00
}
foreach (var binding in bs.Bindings)
{
var localShape = string.IsNullOrWhiteSpace(binding.LocalBlendshape)
? binding.Blendshape
: binding.LocalBlendshape;
if (localMesh.sharedMesh.GetBlendShapeIndex(localShape) == -1)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.missing_local_shape",
localShape, bs);
2023-01-19 20:32:44 +08:00
}
var targetObj = binding.ReferenceMesh.Get(bs.transform);
if (targetObj == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.no_target", bs);
2023-01-19 20:32:44 +08:00
continue;
}
var targetRenderer = targetObj.GetComponent<SkinnedMeshRenderer>();
if (targetRenderer == null)
{
BuildReport.Log(ErrorSeverity.NonFatal,
"validation.blendshape_sync.missing_target_renderer", bs, targetRenderer);
2023-01-19 20:32:44 +08:00
continue;
}
var targetMesh = targetRenderer.sharedMesh;
if (targetMesh == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.blendshape_sync.missing_target_mesh",
bs, targetRenderer);
2023-01-19 20:32:44 +08:00
continue;
}
if (targetMesh.GetBlendShapeIndex(binding.Blendshape) == -1)
{
BuildReport.Log(ErrorSeverity.NonFatal,
"validation.blendshape_sync.missing_target_shape", binding.Blendshape, bs,
targetRenderer);
2023-01-19 20:32:44 +08:00
}
}
}
private static void CheckInternal(ModularAvatarBoneProxy bp)
2023-01-19 20:32:44 +08:00
{
if (bp.target == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.bone_proxy.no_target", bp);
2023-01-19 20:32:44 +08:00
}
}
#if MA_VRCSDK3_AVATARS
private static void CheckInternal(ModularAvatarMenuInstaller mi)
2023-01-19 20:32:44 +08:00
{
// TODO - check that target menu is in the avatar
if (mi.menuToAppend == null && mi.GetComponent<MenuSource>() == null)
2023-01-19 20:32:44 +08:00
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.menu_installer.no_menu", mi);
2023-01-19 20:32:44 +08:00
}
}
private static void CheckInternal(ModularAvatarMergeAnimator ma)
2023-01-19 20:32:44 +08:00
{
if (ma.animator == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.merge_animator.no_animator", ma);
2023-01-19 20:32:44 +08:00
}
}
#endif
2023-01-19 20:32:44 +08:00
private static void CheckInternal(ModularAvatarMergeArmature ma)
2023-01-19 20:32:44 +08:00
{
if (ma.mergeTargetObject == null)
{
BuildReport.Log(ErrorSeverity.NonFatal, "validation.merge_armature.no_target", ma);
return;
2023-01-19 20:32:44 +08:00
}
if (ma.mergeTargetObject == ma.gameObject || ma.mergeTargetObject.transform.IsChildOf(ma.transform))
{
BuildReport.Log(ErrorSeverity.Error, "error.merge_armature.circular_dependency", ma,
ma.mergeTargetObject);
2023-01-19 20:32:44 +08:00
}
}
}
}