feat: add override target to MaterialSetter

This commit is contained in:
nekobako 2024-08-18 17:04:55 +09:00
parent 39abed67e3
commit 625dbb95c7
6 changed files with 57 additions and 34 deletions

View File

@ -3,6 +3,7 @@
<ui:VisualElement name="root-box">
<ui:VisualElement name="group-box">
<ed:PropertyField binding-path="m_inverted" label="reactive_object.inverse" class="ndmf-tr"/>
<ed:PropertyField binding-path="m_targetRenderer" label="reactive_object.shape-changer.target-renderer" name="TargetRenderer" class="ndmf-tr"/>
<ui:VisualElement name="ListViewContainer">
<ui:ListView virtualization-method="DynamicHeight"

View File

@ -31,6 +31,7 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
root.Bind(serializedObject);
var listView = root.Q<ListView>("Shapes");
root.Q<PropertyField>("TargetRenderer").RegisterValueChangeCallback(_ => listView.RefreshItems());
listView.showBoundCollectionSize = false;
listView.virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight;

View File

@ -85,34 +85,33 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
void UpdateVisualTarget()
{
var targetObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object"));
Renderer targetRenderer;
var setter = property.serializedObject.targetObject as ModularAvatarMaterialSetter;
var renderer = GetTargetRenderer(AvatarObjectReference.Get(property.FindPropertyRelative("Object")));
var overrideRenderer = GetTargetRenderer(setter?.targetRenderer.Get(setter));
try
f_object.SetEnabled(overrideRenderer == null);
f_object.SetValueWithoutNotify(overrideRenderer ?? renderer);
Renderer GetTargetRenderer(GameObject obj)
{
targetRenderer = targetObject?.GetComponent<Renderer>();
try
{
return obj?.GetComponent<Renderer>();
}
catch (MissingComponentException e)
{
return null;
}
}
catch (MissingComponentException e)
{
targetRenderer = null;
}
f_object.SetValueWithoutNotify(targetRenderer);
}
void UpdateMaterialDropdown()
{
var toggledObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object"));
Material[] sharedMaterials;
try
{
sharedMaterials = toggledObject?.GetComponent<Renderer>()?.sharedMaterials;
}
catch (MissingComponentException e)
{
sharedMaterials = null;
}
var setter = property.serializedObject.targetObject as ModularAvatarMaterialSetter;
var sharedMaterials = GetSharedMaterials(AvatarObjectReference.Get(property.FindPropertyRelative("Object")));
var overrideSharedMaterials = GetSharedMaterials(setter?.targetRenderer.Get(setter));
sharedMaterials = overrideSharedMaterials ?? sharedMaterials;
if (sharedMaterials != null)
{
var matCount = sharedMaterials.Length;
@ -156,6 +155,18 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
f_material_index.formatListItemCallback = _ => "<Missing Renderer>";
f_material_index.formatSelectedValueCallback = f_material_index.formatListItemCallback;
}
Material[] GetSharedMaterials(GameObject obj)
{
try
{
return obj?.GetComponent<Renderer>()?.sharedMaterials;
}
catch (MissingComponentException e)
{
return null;
}
}
}
}
}

View File

@ -91,11 +91,11 @@ namespace nadena.dev.modular_avatar.core.editor
{
if (setter.Objects == null) continue;
var overrideRenderer = setter.targetRenderer.Get(setter)?.GetComponent<Renderer>();
foreach (var obj in setter.Objects)
{
var target = obj.Object.Get(setter);
if (target == null) continue;
var renderer = target.GetComponent<Renderer>();
var renderer = overrideRenderer ?? obj.Object.Get(setter)?.GetComponent<Renderer>();
if (renderer == null || renderer.sharedMaterials.Length < obj.MaterialIndex) continue;
var key = new TargetProp

View File

@ -39,14 +39,14 @@ namespace nadena.dev.modular_avatar.core.editor
bool active = context.ActiveAndEnabled(setter) && (mami == null || menuItemPreview.IsEnabledForPreview(mami));
if (active == context.Observe(setter, t => t.Inverted)) continue;
var overrideTarget = context.Observe(setter, c => c.targetRenderer.Get(setter));
var overrideRenderer = context.GetComponent<Renderer>(overrideTarget);
var objs = context.Observe(setter, s => s.Objects.Select(o => (o.Object.Get(s), o.Material, o.MaterialIndex)).ToList(), (x, y) => x.SequenceEqual(y));
if (setter.Objects == null) continue;
foreach (var (obj, mat, index) in objs)
{
if (obj == null) continue;
var renderer = context.GetComponent<Renderer>(obj);
var renderer = overrideRenderer ?? context.GetComponent<Renderer>(obj);
if (renderer == null) continue;
var matCount = context.Observe(renderer, r => r.sharedMaterials.Length);
@ -114,14 +114,16 @@ namespace nadena.dev.modular_avatar.core.editor
foreach (var setter in _setters)
{
var objects = context.Observe(setter, s => s.Objects
.Where(obj => obj.Object.Get(s) == original.gameObject)
.Select(obj => (obj.Material, obj.MaterialIndex)),
(x, y) => x.SequenceEqual(y)
);
foreach (var (mat, index) in objects)
var overrideTarget = context.Observe(setter, c => c.targetRenderer.Get(setter));
var overrideRenderer = context.GetComponent<Renderer>(overrideTarget);
var objs = context.Observe(setter, s => s.Objects.Select(o => (o.Object.Get(s), o.Material, o.MaterialIndex)).ToList(), (x, y) => x.SequenceEqual(y));
foreach (var (obj, mat, index) in objs)
{
var renderer = overrideRenderer ?? context.GetComponent<Renderer>(obj);
if (renderer != original) continue;
if (index <= mats.Length)
{
mats[index] = mat;

View File

@ -32,6 +32,14 @@ namespace nadena.dev.modular_avatar.core
public class ModularAvatarMaterialSetter : ReactiveComponent
{
[SerializeField] private AvatarObjectReference m_targetRenderer;
public AvatarObjectReference targetRenderer
{
get => m_targetRenderer;
set => m_targetRenderer = value;
}
[SerializeField] private List<MaterialSwitchObject> m_objects = new();
public List<MaterialSwitchObject> Objects