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="root-box">
<ui:VisualElement name="group-box"> <ui:VisualElement name="group-box">
<ed:PropertyField binding-path="m_inverted" label="reactive_object.inverse" class="ndmf-tr"/> <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:VisualElement name="ListViewContainer">
<ui:ListView virtualization-method="DynamicHeight" <ui:ListView virtualization-method="DynamicHeight"

View File

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

View File

@ -85,34 +85,33 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
void UpdateVisualTarget() void UpdateVisualTarget()
{ {
var targetObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object")); var setter = property.serializedObject.targetObject as ModularAvatarMaterialSetter;
Renderer targetRenderer; var renderer = GetTargetRenderer(AvatarObjectReference.Get(property.FindPropertyRelative("Object")));
var overrideRenderer = GetTargetRenderer(setter?.targetRenderer.Get(setter));
f_object.SetEnabled(overrideRenderer == null);
f_object.SetValueWithoutNotify(overrideRenderer ?? renderer);
Renderer GetTargetRenderer(GameObject obj)
{
try try
{ {
targetRenderer = targetObject?.GetComponent<Renderer>(); return obj?.GetComponent<Renderer>();
} }
catch (MissingComponentException e) catch (MissingComponentException e)
{ {
targetRenderer = null; return null;
}
} }
f_object.SetValueWithoutNotify(targetRenderer);
} }
void UpdateMaterialDropdown() void UpdateMaterialDropdown()
{ {
var toggledObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object")); var setter = property.serializedObject.targetObject as ModularAvatarMaterialSetter;
Material[] sharedMaterials; var sharedMaterials = GetSharedMaterials(AvatarObjectReference.Get(property.FindPropertyRelative("Object")));
try var overrideSharedMaterials = GetSharedMaterials(setter?.targetRenderer.Get(setter));
{
sharedMaterials = toggledObject?.GetComponent<Renderer>()?.sharedMaterials;
}
catch (MissingComponentException e)
{
sharedMaterials = null;
}
sharedMaterials = overrideSharedMaterials ?? sharedMaterials;
if (sharedMaterials != null) if (sharedMaterials != null)
{ {
var matCount = sharedMaterials.Length; 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.formatListItemCallback = _ => "<Missing Renderer>";
f_material_index.formatSelectedValueCallback = f_material_index.formatListItemCallback; 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; if (setter.Objects == null) continue;
var overrideRenderer = setter.targetRenderer.Get(setter)?.GetComponent<Renderer>();
foreach (var obj in setter.Objects) foreach (var obj in setter.Objects)
{ {
var target = obj.Object.Get(setter); var renderer = overrideRenderer ?? obj.Object.Get(setter)?.GetComponent<Renderer>();
if (target == null) continue;
var renderer = target.GetComponent<Renderer>();
if (renderer == null || renderer.sharedMaterials.Length < obj.MaterialIndex) continue; if (renderer == null || renderer.sharedMaterials.Length < obj.MaterialIndex) continue;
var key = new TargetProp 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)); bool active = context.ActiveAndEnabled(setter) && (mami == null || menuItemPreview.IsEnabledForPreview(mami));
if (active == context.Observe(setter, t => t.Inverted)) continue; if (active == context.Observe(setter, t => t.Inverted)) continue;
var objs = context.Observe(setter, s => s.Objects.Select(o => (o.Object.Get(s), o.Material, o.MaterialIndex)).ToList(), (x, y) => x.SequenceEqual(y)); var overrideTarget = context.Observe(setter, c => c.targetRenderer.Get(setter));
var overrideRenderer = context.GetComponent<Renderer>(overrideTarget);
if (setter.Objects == null) continue; 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) foreach (var (obj, mat, index) in objs)
{ {
if (obj == null) continue; var renderer = overrideRenderer ?? context.GetComponent<Renderer>(obj);
var renderer = context.GetComponent<Renderer>(obj);
if (renderer == null) continue; if (renderer == null) continue;
var matCount = context.Observe(renderer, r => r.sharedMaterials.Length); 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) foreach (var setter in _setters)
{ {
var objects = context.Observe(setter, s => s.Objects var overrideTarget = context.Observe(setter, c => c.targetRenderer.Get(setter));
.Where(obj => obj.Object.Get(s) == original.gameObject) var overrideRenderer = context.GetComponent<Renderer>(overrideTarget);
.Select(obj => (obj.Material, obj.MaterialIndex)),
(x, y) => x.SequenceEqual(y)
);
foreach (var (mat, index) in objects) 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) if (index <= mats.Length)
{ {
mats[index] = mat; mats[index] = mat;

View File

@ -32,6 +32,14 @@ namespace nadena.dev.modular_avatar.core
public class ModularAvatarMaterialSetter : ReactiveComponent 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(); [SerializeField] private List<MaterialSwitchObject> m_objects = new();
public List<MaterialSwitchObject> Objects public List<MaterialSwitchObject> Objects