live2D (sdk가 6.5 미지원으로 sprite로 대응)

This commit is contained in:
2026-08-08 22:13:54 +09:00
parent 9ce6930772
commit 8a4a001fe0
4278 changed files with 287426 additions and 18 deletions

View File

@@ -0,0 +1,50 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismHarmonicMotionParameter"/>s.
/// </summary>
[CustomEditor(typeof(CubismDisplayInfoParameterName)), CanEditMultipleObjects]
public class CubismDisplayInfoParameterNameInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
// Fail silently.
if (serializedObject == null)
{
return;
}
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Display name.
var displayName = serializedObject.FindProperty("DisplayName");
EditorGUILayout.PropertyField(displayName);
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4db5977ef551324597933db41e498fc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Core;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismRenderer"/>s.
/// </summary>
[CustomEditor(typeof(CubismDrawable)), CanEditMultipleObjects]
internal sealed class CubismDrawableInspector : UnityEditor.Editor
{
/// <summary>
/// <see cref="CubismPart"/>s cache.
/// </summary>
private CubismPart[] Parts { get; set; }
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
var drawable = target as CubismDrawable;
if (Parts == null)
{
Parts = drawable.FindCubismModel(true).Parts;
}
if (drawable?.ParentPartIndex < 0)
{
return;
}
EditorGUILayout.ObjectField("Parent Part", Parts[drawable.ParentPartIndex], typeof(CubismPart), false);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e36067542c38fa143b9a200405ea4a82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.HarmonicMotion;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismHarmonicMotionParameter"/>s.
/// </summary>
[CustomEditor(typeof(CubismHarmonicMotionParameter)), CanEditMultipleObjects]
public sealed class CubismHarmonicMotionParameterInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
// Fail silently.
if (serializedObject == null)
{
return;
}
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Display channel.
var channel = serializedObject.FindProperty("Channel");
EditorGUILayout.PropertyField(channel);
// Display direction.
var direction = serializedObject.FindProperty("Direction");
EditorGUILayout.PropertyField(direction);
// Display normalized origin.
var normalizedOrigin = serializedObject.FindProperty("NormalizedOrigin");
EditorGUILayout.PropertyField(normalizedOrigin);
// Display normalized range.
var normalizedRange = serializedObject.FindProperty("NormalizedRange");
EditorGUILayout.PropertyField(normalizedRange);
// Display duration.
var duration = serializedObject.FindProperty("Duration");
EditorGUILayout.PropertyField(duration);
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54e6237c5f3fb9f44991acbd20723309
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismHarmonicMotionParameter"/>s.
/// </summary>
[CustomEditor(typeof(CubismHitDrawable)), CanEditMultipleObjects]
public class CubismHitDrawableInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
var hitDrawable = target as CubismHitDrawable;
// Fail silently.
if (hitDrawable == null)
{
return;
}
// Display user data.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var name = EditorGUILayout.TextField("Precision", hitDrawable.Name);
if (!scope.changed)
{
return;
}
// Apply to all selected HitDrawable.
foreach (CubismHitDrawable cubismRaycastable in targets)
{
cubismRaycastable.Name = name;
// Save any changes.
EditorUtility.SetDirty(cubismRaycastable);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69b9ebd6d7ba80e4fb9490411f429de9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.LookAt;
using UnityEditor;
using Object = UnityEngine.Object;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspects <see cref="CubismLookController"/>s.
/// </summary>
[CustomEditor(typeof(CubismLookController))]
internal sealed class CubismLookControllerInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws the inspector.
/// </summary>
public override void OnInspectorGUI()
{
var controller = target as CubismLookController;
// Fail silently.
if (controller == null)
{
return;
}
EditorGUI.BeginChangeCheck();
// Draw default inspector.
base.OnInspectorGUI();
// Draw target.
controller.Target = EditorGUILayout.ObjectField("Target", controller.Target, typeof(Object), true);
// Apply changes.
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(controller);
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27d9d2e24ece36a4ab774f9680eb0a46
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.LookAt;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismLookParameter"/>s.
/// </summary>
[CustomEditor(typeof(CubismLookParameter)), CanEditMultipleObjects]
public class CubismLookParameterInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
// Fail silently.
if (serializedObject == null)
{
return;
}
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Display axis.
var axis = serializedObject.FindProperty("Axis");
EditorGUILayout.PropertyField(axis);
// Display factor.
var factor = serializedObject.FindProperty("Factor");
EditorGUILayout.PropertyField(factor);
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01400995421ea4f46a59b0204dbb29c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,214 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Allows inspecting <see cref="CubismParameter"/>s.
/// </summary>
[CustomEditor(typeof(CubismParametersInspector))]
internal sealed class CubismParametersInspectorInspector : UnityEditor.Editor
{
#region Editor
private struct Element
{
public FloatField field;
public Slider slider;
public Element(FloatField field, Slider slider)
{
this.field = field;
this.slider = slider;
}
}
private VisualElement _visualElement;
private Button _button;
private Element[] _elements;
public override VisualElement CreateInspectorGUI()
{
var target = (CubismParametersInspector)this.target;
target.Refresh();
_visualElement = new VisualElement();
if (target.Model != null)
{
var parameters = target.Model.Parameters;
_elements = new Element[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var displayInfoParameterName = parameter.GetComponent<CubismDisplayInfoParameterName>();
var displayName = displayInfoParameterName != null
? (string.IsNullOrEmpty(displayInfoParameterName.DisplayName)
? displayInfoParameterName.Name
: displayInfoParameterName.DisplayName)
: parameter.Id;
var field = new FloatField() { value = parameter.Value };
field.SetEnabled(!Application.isPlaying);
var slider = new Slider(displayName, parameter.MinimumValue, parameter.MaximumValue)
{
value = parameter.Value,
userData = this
};
slider.RegisterCallback<MouseCaptureEvent, int>(OnMouseCapture, i);
slider.RegisterCallback<MouseCaptureOutEvent, int>(OnMouseCaptureOut, i);
slider.RegisterCallback<ChangeEvent<float>, int>(OnChangeEvent, i);
field.style.flexDirection = new StyleEnum<FlexDirection>(FlexDirection.Row);
field.style.flexBasis = new StyleLength(new Length(10.0f, LengthUnit.Percent));
field.style.maxWidth = new StyleLength(new Length(50.0f, LengthUnit.Pixel));
field.style.minWidth = new StyleLength(new Length(30.0f, LengthUnit.Pixel));
_elements[i] = new Element(field, slider);
slider.Add(field);
_visualElement.Add(slider);
}
_button = new Button(() =>
{
var target = this.target as CubismParametersInspector;
if (target == null)
{
return;
}
for (var i = 0; i < target.Model.Parameters.Length; i++)
{
var parameter = target.Model.Parameters[i];
parameter.OverrideValue(parameter.DefaultValue);
_elements[i].slider.value = parameter.DefaultValue;
_elements[i].field.value = parameter.DefaultValue;
EditorUtility.SetDirty(parameter);
}
Undo.RecordObjects(target.Model.Parameters, "Change Parameter Values");
target.Model.ForceUpdateNow();
})
{ text = "Reset" };
_button.SetEnabled(!Application.isPlaying);
_visualElement.Add(_button);
}
return _visualElement;
}
private void OnEnable()
{
var target = (CubismParametersInspector)this.target;
target.OnChangedValues += UpdateValues;
}
private void OnDisable()
{
var target = (CubismParametersInspector)this.target;
target.OnChangedValues -= UpdateValues;
}
private void UpdateValues(CubismInspectorAbstract sender)
{
if (_elements == null)
{
return;
}
if (sender.Model == null)
{
Debug.LogError("sender model is null.");
return;
}
var flags = sender.OverrideFlags;
var parameters = sender.Model.Parameters;
if (parameters == null)
{
Debug.LogError("parameters is null.");
return;
}
if (_elements.Length != parameters.Length)
{
Debug.LogError("parameters count mismatch.");
return;
}
for (var i = 0; i < _elements.Length; i++)
{
if (!flags[i])
{
var value = parameters[i].Value;
_elements[i].field.value = value;
_elements[i].slider.value = value;
}
}
}
private static void OnMouseCapture(MouseCaptureEvent ev, int index)
{
var slider = ev.currentTarget as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismParametersInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismParametersInspector)data.target;
target.OverrideFlags[index] = true;
}
private static void OnMouseCaptureOut(MouseCaptureOutEvent ev, int index)
{
var slider = ev.currentTarget as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismParametersInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismParametersInspector)data.target;
target.OverrideFlags[index] = false;
}
private static void OnChangeEvent(ChangeEvent<float> ev, int index)
{
var slider = ev.target as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismParametersInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismParametersInspector)data.target;
data._elements[index].field.value = ev.newValue;
target.OverrideValues[index] = ev.newValue;
if (!Application.isPlaying)
{
var parameter = target.Model.Parameters[index];
Undo.RecordObject(parameter, "Change Parameter Value");
parameter.OverrideValue(ev.newValue);
target.Model.ForceUpdateNow();
parameter.OverrideValue(ev.newValue);
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f1de86a7dd68134ebe9e1382a83d4c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using UnityEditor;
using Live2D.Cubism.Rendering;
namespace Live2D.Cubism.Editor.Inspectors
{
[CustomEditor(typeof(CubismPartColorsEditor)), CanEditMultipleObjects]
internal sealed class PortfolioPartBlendColorEditorInspector : UnityEditor.Editor
{
private SerializedProperty childDrawableRenderers;
private SerializedProperty childParts;
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
var blendColorEditor = target as CubismPartColorsEditor;
// Fail silently.
if (blendColorEditor == null)
{
return;
}
// Obtains a property from a component.
if (childDrawableRenderers == null)
{
childDrawableRenderers = serializedObject.FindProperty("_childDrawableRenderers");
}
if (childParts == null)
{
childParts = serializedObject.FindProperty("_childParts");
}
if (childDrawableRenderers != null)
{
// Show renderers.
EditorGUILayout.PropertyField(childDrawableRenderers);
}
if (childParts != null)
{
// Show parts.
EditorGUILayout.PropertyField(childParts);
}
EditorGUI.BeginChangeCheck();
// Display PartMultiplyColorEnabled.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var overrideColorForPartMultiplyColors = EditorGUILayout.Toggle("PartMultiplyColorEnabled", blendColorEditor.PartMultiplyColorEnabled);
if (scope.changed)
{
foreach (CubismPartColorsEditor partBlendColorEditor in targets)
{
partBlendColorEditor.PartMultiplyColorEnabled = overrideColorForPartMultiplyColors;
}
}
}
// Display PartScreenColorEnabled.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var overrideColorForPartScreenColors = EditorGUILayout.Toggle("PartScreenColorEnabled", blendColorEditor.PartScreenColorEnabled);
if (scope.changed)
{
foreach (CubismPartColorsEditor partBlendColorEditor in targets)
{
partBlendColorEditor.PartScreenColorEnabled = overrideColorForPartScreenColors;
}
}
}
// Display multiply color.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var multiplyColor = EditorGUILayout.ColorField("MultiplyColor", blendColorEditor.MultiplyColor);
if (scope.changed)
{
foreach (CubismPartColorsEditor partBlendColorEditor in targets)
{
partBlendColorEditor.MultiplyColor = multiplyColor;
}
}
}
// Display screen color.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var screenColor = EditorGUILayout.ColorField("ScreenColor", blendColorEditor.ScreenColor);
if (scope.changed)
{
foreach (CubismPartColorsEditor partBlendColorEditor in targets)
{
partBlendColorEditor.ScreenColor = screenColor;
}
}
}
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
foreach (CubismPartColorsEditor partBlendColorEditor in targets)
{
EditorUtility.SetDirty(partBlendColorEditor);
foreach (var renderer in partBlendColorEditor.ChildDrawableRenderers)
{
EditorUtility.SetDirty(renderer);
// HACK Get mesh renderer directly.
EditorUtility.SetDirty(renderer.MeshRenderer);
}
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 751aeca09fa653042a1891e178dec9d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,178 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using System;
using Live2D.Cubism.Core;
using Live2D.Cubism.Rendering;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismRenderer"/>s.
/// </summary>
[CustomEditor(typeof(CubismPart)), CanEditMultipleObjects]
internal sealed class CubismPartInspector : UnityEditor.Editor
{
/// <summary>
/// Parent <see cref="CubismPart"/> cache.
/// </summary>
private CubismPart _parent;
/// <summary>
/// Child <see cref="CubismPart"/>s foldout state.
/// </summary>
private static bool ChildPartsFoldout { get; set; } = true;
/// <summary>
/// Child <see cref="CubismPart"/>s ReorderableList.
/// </summary>
private ReorderableList ChildParts { get; set; }
/// <summary>
/// Child <see cref="CubismPart"/>'s child <see cref="CubismDrawable"/>s.
/// </summary>
private InternalTreeInfo ChildPartDrawables { get; set; }
private int DrawablesTotalCount { get; set; }
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
if (!IsInitialized)
{
Initialize();
}
EditorGUILayout.ObjectField("Parent Part", _parent, typeof(CubismPart), false);
{
var rect = EditorGUILayout.GetControlRect();
var foldoutRect = new Rect(rect.x, rect.y, rect.width, rect.height);
var fieldRect = new Rect(rect.x + rect.width - 50f, rect.y, 50f, rect.height);
ChildPartsFoldout = EditorGUI.Foldout(foldoutRect, ChildPartsFoldout, "Child Parts");
EditorGUI.IntField(fieldRect, ChildParts.count);
}
if (ChildPartsFoldout)
{
ChildParts.DoLayoutList();
}
{
var rect = EditorGUILayout.GetControlRect();
var foldoutRect = new Rect(rect.x, rect.y, rect.width, rect.height);
var fieldRect = new Rect(rect.x + rect.width - 50f, rect.y, 50f, rect.height);
ChildPartDrawables.Foldout = EditorGUI.Foldout(foldoutRect, ChildPartDrawables.Foldout, "Child Drawables");
EditorGUI.IntField(fieldRect, DrawablesTotalCount);
}
if (ChildPartDrawables.Foldout)
{
for (var i = 0; i < ChildPartDrawables.Drawables.Length; i++)
{
EditorGUILayout.ObjectField(ChildPartDrawables.Drawables[i], typeof(CubismDrawable), true);
}
EditorGUI.indentLevel++;
for (var i = 0; i < ChildPartDrawables.Children.Length; i++)
{
DrawTree(ChildPartDrawables.Children[i]);
}
EditorGUI.indentLevel--;
}
}
private void DrawTree(InternalTreeInfo item)
{
item.Foldout = EditorGUILayout.Foldout(item.Foldout, item.Part.Id);
if (item.Foldout)
{
for (var i = 0; i < item.Drawables.Length; i++)
{
EditorGUILayout.ObjectField(item.Drawables[i], typeof(CubismDrawable), true);
}
for (var i = 0; i < item.Children.Length; i++)
{
DrawTree(item.Children[i]);
}
}
}
#endregion
/// <summary>
/// Gets whether <see langword="this"/> is initialized.
/// </summary>
private bool IsInitialized
{
get
{
return ChildParts != null && ChildPartDrawables != null;
}
}
/// <summary>
/// Initializes <see langword="this"/>.
/// </summary>
private void Initialize()
{
var part = target as CubismPart;
var model = part.FindCubismModel(true);
var parts = model.Parts;
_parent = part.UnmanagedParentIndex < 0 ? null : parts[part.UnmanagedParentIndex];
var childParts = part.ChildParts;
ChildParts = new ReorderableList(childParts, typeof(CubismPart), false, false, false, false)
{
drawElementCallback = (rect, index, isActive, isFocused) =>
{
rect.height = EditorGUIUtility.singleLineHeight;
var labelRect = new Rect(rect.x, rect.y, rect.width * 0.2f, rect.height);
var objRect = new Rect(rect.x + labelRect.width, rect.y, rect.width * 0.8f, rect.height);
EditorGUI.LabelField(labelRect, $"{index}");
EditorGUI.ObjectField(objRect, childParts[index], typeof(CubismPart), true);
}
};
ChildPartDrawables = new InternalTreeInfo(part);
DrawablesTotalCount = ChildPartDrawables.Drawables.Length;
}
private class InternalTreeInfo
{
public bool Foldout = true;
public readonly CubismPart Part;
public readonly CubismDrawable[] Drawables;
public readonly InternalTreeInfo[] Children;
public InternalTreeInfo(CubismPart part)
{
Part = part;
Drawables = Part.ChildDrawables;
Children = Array.Empty<InternalTreeInfo>();
for (var i = 0; i < Part.ChildParts.Length; i++)
{
Array.Resize(ref Children, Children.Length + 1);
Children[^1] = new InternalTreeInfo(Part.ChildParts[i]);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b71043dbb8a8aac4e95f292093aa6f0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,236 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Core;
using Live2D.Cubism.Framework;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Allows inspecting <see cref="CubismPart"/>s.
/// </summary>
[CustomEditor(typeof(CubismPartsInspector))]
internal sealed class CubismPartsInspectorInspector : UnityEditor.Editor
{
private sealed class PartProxy
{
public CubismPart Part;
public PartProxy[] Children = new PartProxy[0];
public FloatField Field;
public Slider Slider;
}
private PartProxy[] _proxies;
private VisualElement _visualElement;
private void RecursiveCreateInspectorGUI(PartProxy item, VisualElement parent)
{
if (item.Children.Length > 0)
{
item.Slider.style.position = new StyleEnum<Position>(Position.Absolute);
item.Slider.style.left = new StyleLength(new Length(0.0f, LengthUnit.Pixel));
item.Slider.style.right = new StyleLength(new Length(0.0f, LengthUnit.Pixel));
var element = new VisualElement();
var foldout = new Foldout();
foldout.style.marginTop = new StyleLength(new Length(0.0f, LengthUnit.Pixel));
foldout.style.marginBottom = new StyleLength(new Length(0.0f, LengthUnit.Pixel));
foreach (var sub in item.Children)
{
RecursiveCreateInspectorGUI(sub, foldout);
}
element.Add(foldout);
element.Add(item.Slider);
parent.Add(element);
}
else
{
parent.Add(item.Slider);
}
}
public override VisualElement CreateInspectorGUI()
{
var target = (CubismPartsInspector)this.target;
target.Refresh();
_visualElement = new VisualElement();
if (target.Model != null)
{
var parts = target.Model.Parts;
var data = new PartProxy[0];
_proxies = new PartProxy[parts.Length];
for (var i = 0; i < parts.Length; i++)
{
var part = parts[i];
var cdiPartName = part.GetComponent<CubismDisplayInfoPartName>();
var name = cdiPartName != null
? (string.IsNullOrEmpty(cdiPartName.DisplayName) ? cdiPartName.Name : cdiPartName.DisplayName)
: part.name;
var slider = new Slider(name, 0.0f, 1.0f)
{
label = name,
value = part.Opacity,
userData = this
};
var field = new FloatField()
{
value = part.Opacity,
userData = this
};
field.style.width = new StyleLength(new Length(50.0f, LengthUnit.Pixel));
field.style.maxWidth = new StyleLength(new Length(50.0f, LengthUnit.Pixel));
field.style.minWidth = new StyleLength(new Length(30.0f, LengthUnit.Pixel));
slider.Add(field);
slider.RegisterCallback<MouseCaptureEvent, int>(OnMouseCapture, i);
slider.RegisterCallback<MouseCaptureOutEvent, int>(OnMouseCaptureOut, i);
slider.RegisterCallback<ChangeEvent<float>, int>(OnChangeEvent, i);
_proxies[i] = new PartProxy()
{
Part = part,
Field = field,
Slider = slider
};
}
foreach (var item in _proxies)
{
var unmanagedParentIndex = item.Part.UnmanagedParentIndex;
if (unmanagedParentIndex < 0)
{
System.Array.Resize(ref data, data.Length + 1);
data[^1] = item;
}
else
{
var parent = _proxies[unmanagedParentIndex];
System.Array.Resize(ref parent.Children, parent.Children.Length + 1);
parent.Children[^1] = item;
}
}
foreach (var item in data)
{
RecursiveCreateInspectorGUI(item, _visualElement);
}
}
return _visualElement;
}
private void UpdateValues(CubismInspectorAbstract sender)
{
if (_proxies == null)
{
return;
}
if (sender.Model == null)
{
Debug.LogError("sender model is null.");
return;
}
var flags = sender.OverrideFlags;
var parts = sender.Model.Parts;
if (parts == null)
{
Debug.LogError("parts is null.");
return;
}
if (_proxies.Length != parts.Length)
{
Debug.LogError("parts count mismatch.");
return;
}
for (var i = 0; i < _proxies.Length; i++)
{
if (!flags[i])
{
var value = parts[i].Opacity;
_proxies[i].Field.value = value;
_proxies[i].Slider.value = value;
}
}
}
private static void OnMouseCapture(MouseCaptureEvent ev, int index)
{
var slider = ev.currentTarget as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismPartsInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismPartsInspector)data.target;
target.OverrideFlags[index] = true;
}
private static void OnMouseCaptureOut(MouseCaptureOutEvent ev, int index)
{
var slider = ev.currentTarget as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismPartsInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismPartsInspector)data.target;
target.OverrideFlags[index] = false;
}
private static void OnChangeEvent(ChangeEvent<float> ev, int index)
{
var slider = ev.target as Slider;
if (slider == null)
{
return;
}
var data = slider.userData as CubismPartsInspectorInspector;
if (data == null)
{
return;
}
var target = (CubismPartsInspector)data.target;
data._proxies[index].Field.value = ev.newValue;
target.OverrideValues[index] = ev.newValue;
if (!Application.isPlaying)
{
var part = target.Model.Parts[index];
Undo.RecordObject(part, "Change Part Value");
part.Opacity = ev.newValue;
target.Model.ForceUpdateNow();
part.Opacity = ev.newValue;
}
}
private void OnEnable()
{
var target = (CubismPartsInspector)this.target;
target.OnChangedValues += UpdateValues;
}
private void OnDisable()
{
var target = (CubismPartsInspector)this.target;
target.OnChangedValues -= UpdateValues;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b1db70a6a525f774b87e2ee0121da67f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.Pose;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismPosePart"/>s.
/// </summary>
[CustomEditor(typeof(CubismPosePart)), CanEditMultipleObjects]
public class CubismPosePartInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
// Fail silently.
if (serializedObject == null)
{
return;
}
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Display group index.
var groupIndex = serializedObject.FindProperty("GroupIndex");
EditorGUILayout.PropertyField(groupIndex);
// Display part index.
var partIndex = serializedObject.FindProperty("PartIndex");
EditorGUILayout.PropertyField(partIndex);
// Display linked id.
var link = serializedObject.FindProperty("Link");
EditorGUILayout.PropertyField(link);
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a72aa2b362632fe4480c84500a6e481d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.Raycasting;
using UnityEditor;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismRaycastable"/>s.
/// </summary>
[CustomEditor(typeof(CubismRaycastable)), CanEditMultipleObjects]
public class CubismRaycastableInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
// Fail silently.
if (serializedObject == null)
{
return;
}
serializedObject.Update();
EditorGUI.BeginChangeCheck();
// Display precision.
var precision = serializedObject.FindProperty("Precision");
EditorGUILayout.PropertyField(precision);
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1e77a408868088469ad556d52027f3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Rendering;
using System;
using UnityEditor;
using UnityEngine;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="Live2D.Cubism.Rendering.CubismRenderController"/>s.
/// </summary>
[CustomEditor(typeof(CubismRenderController))]
internal sealed class CubismRenderControllerInspector : UnityEditor.Editor
{
private bool ShowSorting { get; set; }
private bool ShowAdvanced { get; set; }
#region Editor
/// <summary>
/// Draws the inspector.
/// </summary>
public override void OnInspectorGUI()
{
var controller = target as CubismRenderController;
// Fail silently.
if (controller == null)
{
return;
}
// Show settings.
EditorGUI.BeginChangeCheck();
controller.Opacity = EditorGUILayout.Slider("Opacity", controller.Opacity, 0f, 1f);
controller.MultiplyColorEnabled = EditorGUILayout.Toggle("MultiplyColorEnabled", controller.MultiplyColorEnabled);
controller.ScreenColorEnabled = EditorGUILayout.Toggle("ScreenColorEnabled", controller.ScreenColorEnabled);
ShowSorting = EditorGUILayout.Foldout(ShowSorting, "Sorting", EditorStyles.boldFont);
if (ShowSorting)
{
controller.GroupedSortingIndex = EditorGUILayout.IntField("Grouped Sorting Index", controller.GroupedSortingIndex);
controller.SortingLayer = EditorGUILayout.TextField("Layer", controller.SortingLayer);
controller.SortingOrder = EditorGUILayout.IntField("Order In Group", controller.SortingOrder);
controller.SortingMode = (CubismSortingMode)EditorGUILayout.EnumPopup("Mode", (Enum)controller.SortingMode);
}
ShowAdvanced = EditorGUILayout.Foldout(ShowAdvanced, "Advanced", EditorStyles.boldFont);
if (ShowAdvanced)
{
controller.CameraToFace = EditorGUILayout.ObjectField("Camera To Face", controller.CameraToFace, typeof(Camera), true) as Camera;
controller.OpacityHandler = EditorGUILayout.ObjectField("Opacity Handler", controller.OpacityHandler, typeof(object), true);
controller.DrawOrderHandler = EditorGUILayout.ObjectField("Draw Order Handler", controller.DrawOrderHandler, typeof(object), true);
controller.MultiplyColorHandler = EditorGUILayout.ObjectField("Multiply Color Handler", controller.MultiplyColorHandler, typeof(object), true);
controller.ScreenColorHandler = EditorGUILayout.ObjectField("Screen Color Handler", controller.ScreenColorHandler, typeof(object), true);
if (controller.SortingMode.SortByDepth())
{
controller.DepthOffset = EditorGUILayout.FloatField("Depth Offset", controller.DepthOffset);
}
}
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(controller);
foreach (var renderer in controller.Renderers)
{
EditorUtility.SetDirty(renderer);
// HACK Get mesh renderer directly.
EditorUtility.SetDirty(renderer.GetComponent<MeshRenderer>());
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a891e515b82c6a846b44008690721a8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,203 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Core;
using Live2D.Cubism.Rendering;
using UnityEditor;
using UnityEngine;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismRenderer"/>s.
/// </summary>
[CustomEditor(typeof(CubismRenderer)), CanEditMultipleObjects]
internal sealed class CubismRendererInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
var renderer = target as CubismRenderer;
// Fail silently.
if (renderer == null)
{
return;
}
if (!renderer.isActiveAndEnabled)
{
var model = renderer.FindCubismModel(true);
var ctrl = model.GetComponent<CubismRenderController>();
if (!ctrl.IsInitialized)
{
ctrl.TryInitialize();
}
}
// Show settings.
EditorGUILayout.ObjectField("Mesh", renderer.Mesh, typeof(Mesh), false);
EditorGUI.BeginChangeCheck();
// Display DrawObjectMultiplyColorEnabled.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var overrideFlagForDrawObjectMultiplyColors = EditorGUILayout.Toggle("DrawObjectMultiplyColorEnabled", renderer.DrawObjectMultiplyColorEnabled);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.DrawObjectMultiplyColorEnabled = overrideFlagForDrawObjectMultiplyColors;
}
}
}
// Display DrawObjectScreenColorEnabled.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var overrideFlagForDrawObjectScreenColors = EditorGUILayout.Toggle("DrawObjectScreenColorEnabled", renderer.DrawObjectScreenColorEnabled);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.DrawObjectScreenColorEnabled = overrideFlagForDrawObjectScreenColors;
}
}
}
// Display color.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var color = EditorGUILayout.ColorField("Color", renderer.Color);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.Color = color;
}
}
}
// Display multiply color.
using (var scope = new EditorGUI.ChangeCheckScope())
{
if (renderer.DrawObjectType == CubismModelTypes.DrawObjectType.Drawable
|| renderer.DrawObjectType == CubismModelTypes.DrawObjectType.Offscreen)
{
var multiplyColor = EditorGUILayout.ColorField("MultiplyColor", renderer.MultiplyColor);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.MultiplyColor = multiplyColor;
}
}
}
}
// Display screen color.
using (var scope = new EditorGUI.ChangeCheckScope())
{
if (renderer.DrawObjectType == CubismModelTypes.DrawObjectType.Drawable
|| renderer.DrawObjectType == CubismModelTypes.DrawObjectType.Offscreen)
{
var screenColor = EditorGUILayout.ColorField("ScreenColor", renderer.ScreenColor);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.ScreenColor = screenColor;
}
}
}
}
// Display material (DrawMaterial is the actual rendering material).
using (var scope = new EditorGUI.ChangeCheckScope())
{
var material = EditorGUILayout.ObjectField("Material", renderer.DrawMaterial, typeof(Material), true) as Material;
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.DrawMaterial = material;
}
}
}
// Display main texture.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var mainTexture = EditorGUILayout.ObjectField("Main Texture", renderer.MainTexture, typeof(Texture2D), true) as Texture2D;
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.MainTexture = mainTexture;
}
}
}
// Display local sorting order.
using (var scope = new EditorGUI.ChangeCheckScope())
{
var localSortingOrder = EditorGUILayout.IntField("Local Order", renderer.LocalSortingOrder);
if (scope.changed)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.LocalSortingOrder = localSortingOrder;
}
}
}
// Save any changes.
if (EditorGUI.EndChangeCheck())
{
foreach (CubismRenderer cubismRenderer in targets)
{
EditorUtility.SetDirty(cubismRenderer);
EditorUtility.SetDirty(cubismRenderer.MeshRenderer);
}
}
// Show backend toggle.
var showBackends = (renderer.MeshRenderer.hideFlags & HideFlags.HideInInspector) != HideFlags.HideInInspector;
var toggle = EditorGUILayout.Toggle("Show Mesh Filter & Renderer", showBackends) != showBackends;
if (toggle)
{
foreach (CubismRenderer cubismRenderer in targets)
{
cubismRenderer.MeshRenderer.hideFlags ^= HideFlags.HideInInspector;
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5a7afc7e26f34a44189821d8b634cd6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
using Live2D.Cubism.Framework.UserData;
using UnityEditor;
using UnityEngine;
namespace Live2D.Cubism.Editor.Inspectors
{
/// <summary>
/// Inspector for <see cref="CubismUserDataTag"/>s.
/// </summary>
[CustomEditor(typeof(CubismUserDataTag)), CanEditMultipleObjects]
internal sealed class CubismUserDataTagInspector : UnityEditor.Editor
{
#region Editor
/// <summary>
/// Draws inspector.
/// </summary>
public override void OnInspectorGUI()
{
var tag = target as CubismUserDataTag;
// Fail silently.
if (tag == null)
{
return;
}
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.BeginHorizontal();
// Display user data.
EditorGUILayout.LabelField("Value", GUILayout.Width(EditorGUIUtility.labelWidth));
var value = EditorGUILayout.TextArea(tag.Value, EditorStyles.textArea, null);
EditorGUILayout.EndHorizontal();
if (!scope.changed)
{
return;
}
// Apply to all selected UserData.
foreach (CubismUserDataTag userDataTag in targets)
{
userDataTag.Value = value;
EditorUtility.SetDirty(userDataTag);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 073c7e3dee03d2a47a34a5e852b12314
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: