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,487 @@
/**
* 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.MotionFade;
using System.Collections.Generic;
using UnityEngine;
namespace Live2D.Cubism.Framework.Expression
{
/// <summary>
/// Expression controller.
/// </summary>
public class CubismExpressionController : MonoBehaviour, ICubismUpdatable
{
#region variable
/// <summary>
/// Expressions data list.
/// </summary>
[SerializeField]
public CubismExpressionList ExpressionsList;
/// <summary>
/// Use the expression calculation method.
/// </summary>
[SerializeField]
public bool UseLegacyBlendCalculation = false;
/// <summary>
/// CubismModel cache.
/// </summary>
private CubismModel _model = null;
/// <summary>
/// Playing expressions.
/// </summary>
private List<CubismPlayingExpression> _playingExpressions = new List<CubismPlayingExpression>();
/// <summary>
/// Playing expressions index.
/// </summary>
[SerializeField]
public int CurrentExpressionIndex = -1;
/// <summary>
/// Last playing expressions index.
/// </summary>
private int _lastExpressionIndex = -1;
/// <summary>
/// Model has update controller component.
/// </summary>
[HideInInspector]
public bool HasUpdateController { get; set; }
/// <summary>
/// Value of each parameter to be applied to the model.
/// </summary>
private List<CubismExpressionParameterValue> _expressionParameterValues = new List<CubismExpressionParameterValue>();
/// <summary>
/// Default value for applying additive.
/// </summary>
private const float DefaultAdditiveValue = 0.0f;
/// <summary>
/// Initial value of multiply applied.
/// </summary>
private const float DefaultMultiplyValue = 1.0f;
#endregion
/// <summary>
/// Add new expression to playing expressions.
/// </summary>
private void StartExpression()
{
// Fail silently...
if(ExpressionsList == null || ExpressionsList.CubismExpressionObjects == null)
{
return;
}
// Backup expression.
_lastExpressionIndex = CurrentExpressionIndex;
// Set last expression end time
if(_playingExpressions.Count > 0)
{
var playingExpression = _playingExpressions[_playingExpressions.Count - 1];
var newExpressionEndTime = playingExpression.ExpressionUserTime + playingExpression.FadeOutTime;
if (playingExpression.ExpressionEndTime == 0.0f || newExpressionEndTime < playingExpression.ExpressionEndTime)
{
playingExpression.ExpressionEndTime = newExpressionEndTime;
}
_playingExpressions[_playingExpressions.Count - 1] = playingExpression;
}
// Fail silently...
if (CurrentExpressionIndex < 0 || CurrentExpressionIndex >= ExpressionsList.CubismExpressionObjects.Length)
{
return;
}
var palyingExpression = CubismPlayingExpression.Create(_model, ExpressionsList.CubismExpressionObjects[CurrentExpressionIndex]);
if(palyingExpression == null)
{
return;
}
// Add to PlayingExList.
_playingExpressions.Add(palyingExpression);
}
/// <summary>
/// Called by cubism update controller. Order to invoke OnLateUpdate.
/// </summary>
public int ExecutionOrder
{
get { return CubismUpdateExecutionOrder.CubismExpressionController; }
}
/// <summary>
/// Called by cubism update controller. Needs to invoke OnLateUpdate on Editing.
/// </summary>
public bool NeedsUpdateOnEditing
{
get { return false; }
}
/// <summary>
/// Called by cubism update manager.
/// </summary>
public void OnLateUpdate()
{
// Fail silently...
if(!enabled || _model == null)
{
return;
}
// Start expression when current expression changed.
if(CurrentExpressionIndex != _lastExpressionIndex)
{
StartExpression();
}
// Update of expressions.
if (UseLegacyBlendCalculation)
{
UpdateExpressionLegacy();
}
else
{
UpdateExpression();
}
}
/// <summary>
/// Update of expressions. (old method)
/// </summary>
private void UpdateExpressionLegacy()
{
// Update expression
for (var expressionIndex = 0; expressionIndex < _playingExpressions.Count; ++expressionIndex)
{
var playingExpression = _playingExpressions[expressionIndex];
UpdateFadeWeight(playingExpression);
// Apply value.
for (var i = 0; i < playingExpression.Destinations.Length; ++i)
{
// Fail silently...
if (playingExpression.Destinations[i] == null)
{
continue;
}
switch (playingExpression.Blend[i])
{
case CubismParameterBlendMode.Additive:
playingExpression.Destinations[i].AddToValue(playingExpression.Value[i], playingExpression.FadeWeight);
break;
case CubismParameterBlendMode.Multiply:
playingExpression.Destinations[i].MultiplyValueBy(playingExpression.Value[i], playingExpression.FadeWeight);
break;
case CubismParameterBlendMode.Override:
playingExpression.Destinations[i].OverrideValue(playingExpression.Destinations[i].Value * (1 - playingExpression.FadeWeight) + (playingExpression.Value[i] * playingExpression.FadeInWeight));
break;
default:
// When an unspecified value is set, it is already in addition mode.
break;
}
}
// Apply update value
_playingExpressions[expressionIndex] = playingExpression;
}
// Remove expression from playing expressions
for (var expressionIndex = _playingExpressions.Count - 1; expressionIndex >= 0; --expressionIndex)
{
if (_playingExpressions[expressionIndex].FadeWeight > 0.0f)
{
continue;
}
_playingExpressions.RemoveAt(expressionIndex);
}
}
/// <summary>
/// Update of expressions.
/// </summary>
private void UpdateExpression()
{
var expressionWeight = 0.0f;
// Update expression
for (var expressionIndex = 0; expressionIndex < _playingExpressions.Count; ++expressionIndex)
{
var playingExpression = _playingExpressions[expressionIndex];
// List all parameters referenced by the Expression being played.
for (var i = 0; i < playingExpression.Destinations.Length; ++i)
{
var index = -1;
// Search for the presence of a parameter ID in the list.
for (var j = 0; j < _expressionParameterValues.Count; j++)
{
if (_expressionParameterValues[j].Parameter != playingExpression.Destinations[i])
{
continue;
}
index = j;
break;
}
if (index >= 0)
{
continue;
}
// If the parameter does not exist in the list, add a new one.
CubismExpressionParameterValue item = new CubismExpressionParameterValue();
item.Parameter = playingExpression.Destinations[i];
if (item.Parameter != null)
{
item.AdditiveValue = DefaultAdditiveValue;
item.MultiplyValue = DefaultMultiplyValue;
item.OverwriteValue = item.Parameter.Value;
_expressionParameterValues.Add(item);
}
}
// ------ Calculate value ------
CalculateExpressionParameters(expressionIndex, playingExpression);
expressionWeight += playingExpression.FadeInTime == 0.0f
? 1.0f
: CubismFadeMath.GetEasingSine(
(playingExpression.ExpressionUserTime - playingExpression.ExpressionStartTime) /
playingExpression.FadeInTime);
}
// ----- If the latest Expression fade is complete, delete the earlier one. ------
if (_playingExpressions.Count > 1 &&
_playingExpressions[_playingExpressions.Count-1].FadeWeight >= 1.0f)
{
// The last element of the array is not deleted.
for (var i = _playingExpressions.Count - 2; i >= 0; --i)
{
_playingExpressions.RemoveAt(i);
}
}
if (expressionWeight > 1.0f)
{
expressionWeight = 1.0f;
}
// Apply each value to the model.
for (var i = 0; i < _expressionParameterValues.Count; i++)
{
var expressionParameterValue = _expressionParameterValues[i];
expressionParameterValue.Parameter.OverrideValue(
(expressionParameterValue.OverwriteValue + expressionParameterValue.AdditiveValue)
* expressionParameterValue.MultiplyValue,
expressionWeight);
expressionParameterValue.AdditiveValue = DefaultAdditiveValue;
expressionParameterValue.MultiplyValue = DefaultMultiplyValue;
}
}
/// <summary>
/// Update motion weights.
/// </summary>
/// <param name="playingExpression">Expression motion during playback.</param>
private void UpdateFadeWeight(CubismPlayingExpression playingExpression)
{
// Update expression user time.
playingExpression.ExpressionUserTime += Time.deltaTime;
// Update weight
playingExpression.FadeInWeight = (Mathf.Abs(playingExpression.FadeInTime) < float.Epsilon)
? 1.0f
: CubismFadeMath.GetEasingSine(playingExpression.ExpressionUserTime / playingExpression.FadeInTime);
playingExpression.FadeOutWeight = ((Mathf.Abs(playingExpression.ExpressionEndTime) < float.Epsilon) || (playingExpression.ExpressionEndTime < 0.0f))
? 1.0f
: CubismFadeMath.GetEasingSine(
(playingExpression.ExpressionEndTime - playingExpression.ExpressionUserTime) / playingExpression.FadeOutTime);
playingExpression.FadeWeight = playingExpression.Weight * playingExpression.FadeInWeight * playingExpression.FadeOutWeight;
}
/// <summary>
/// Calculate parameters related to the model's facial expressions.
/// </summary>
/// <param name="expressionIndex">Index of currently processed facial expression motion.</param>
/// <param name="playingExpression">Expression motion during playback.</param>
private void CalculateExpressionParameters(int expressionIndex, CubismPlayingExpression playingExpression)
{
UpdateFadeWeight(playingExpression);
for (var i = 0; i < _expressionParameterValues.Count; i++)
{
var expressionParameterValue = _expressionParameterValues[i];
if (expressionParameterValue.Parameter == null)
{
continue;
}
var currentParameterValue = expressionParameterValue.OverwriteValue =
expressionParameterValue.Parameter.Value;
var expressionParameters = playingExpression.Destinations;
var parameterIndex = -1;
for (var j = 0; j < expressionParameters.Length; j++)
{
if (expressionParameterValue.Parameter != expressionParameters[j])
{
continue;
}
parameterIndex = j;
break;
}
// Parameters not referenced by the Expression being played have their initial values applied.
if (parameterIndex < 0)
{
if (expressionIndex == 0)
{
expressionParameterValue.AdditiveValue = DefaultAdditiveValue;
expressionParameterValue.MultiplyValue = DefaultMultiplyValue;
expressionParameterValue.OverwriteValue = currentParameterValue;
}
else
{
expressionParameterValue.AdditiveValue =
CalculateValue(
expressionParameterValue.AdditiveValue,
DefaultAdditiveValue,
playingExpression.FadeWeight);
expressionParameterValue.MultiplyValue =
CalculateValue(
expressionParameterValue.MultiplyValue,
DefaultMultiplyValue,
playingExpression.FadeWeight);
expressionParameterValue.OverwriteValue =
CalculateValue(
expressionParameterValue.OverwriteValue,
currentParameterValue,
playingExpression.FadeWeight);
}
_expressionParameterValues[i] = expressionParameterValue;
continue;
}
// Calculate value.
var value = playingExpression.Value[parameterIndex];
float newAdditiveValue, newMultiplyValue, newSetValue;
switch (playingExpression.Blend[parameterIndex])
{
case CubismParameterBlendMode.Additive:
newAdditiveValue = value;
newMultiplyValue = DefaultMultiplyValue;
newSetValue = currentParameterValue;
break;
case CubismParameterBlendMode.Multiply:
newAdditiveValue = DefaultAdditiveValue;
newMultiplyValue = value;
newSetValue = currentParameterValue;
break;
case CubismParameterBlendMode.Override:
newAdditiveValue = DefaultAdditiveValue;
newMultiplyValue = DefaultMultiplyValue;
newSetValue = value;
break;
default:
return;
}
if (expressionIndex == 0)
{
expressionParameterValue.AdditiveValue = newAdditiveValue;
expressionParameterValue.MultiplyValue = newMultiplyValue;
expressionParameterValue.OverwriteValue = newSetValue;
}
else
{
expressionParameterValue.AdditiveValue =
CalculateValue(
expressionParameterValue.AdditiveValue,
newAdditiveValue,
playingExpression.FadeWeight);
expressionParameterValue.MultiplyValue =
CalculateValue(
expressionParameterValue.MultiplyValue,
newMultiplyValue,
playingExpression.FadeWeight);
expressionParameterValue.OverwriteValue =
CalculateValue(
expressionParameterValue.OverwriteValue,
newSetValue,
playingExpression.FadeWeight);
}
_expressionParameterValues[i] = expressionParameterValue;
}
}
/// <summary>
/// Blend calculation.
/// </summary>
/// <param name="source">Source value.</param>
/// <param name="destination">Destination value.</param>
/// <param name="fadeWeight">Weight value.</param>
/// <returns></returns>
private float CalculateValue(float source, float destination, float fadeWeight)
{
return (source * (1.0f - fadeWeight)) + (destination * fadeWeight);
}
#region Unity Event Handling
/// <summary>
/// Called by Unity.
/// </summary>
private void OnEnable()
{
_model = this.FindCubismModel();
// Get cubism update controller.
HasUpdateController = (GetComponent<CubismUpdateController>() != null);
}
/// <summary>
/// Called by Unity.
/// </summary>
private void LateUpdate()
{
if(!HasUpdateController)
{
OnLateUpdate();
}
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,107 @@
/**
* 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.Json;
using System;
using UnityEngine;
namespace Live2D.Cubism.Framework.Expression
{
public class CubismExpressionData : ScriptableObject
{
/// <summary>
/// Expression type.
/// </summary>
[SerializeField]
public string Type;
/// <summary>
/// Expression fade in time.
/// </summary>
[SerializeField]
public float FadeInTime;
/// <summary>
/// Expression fade out time.
/// </summary>
[SerializeField]
public float FadeOutTime;
/// <summary>
/// Expression Parameters
/// </summary>
[SerializeField]
public SerializableExpressionParameter[] Parameters;
/// <summary>
/// ExpressionParameter
/// </summary>
[Serializable]
public struct SerializableExpressionParameter
{
/// <summary>
/// Expression Parameter Id
/// </summary>
[SerializeField]
public string Id;
/// <summary>
/// Expression Parameter Value
/// </summary>
[SerializeField]
public float Value;
/// <summary>
/// Expression Parameter Blend Mode
/// </summary>
[SerializeField]
public CubismParameterBlendMode Blend;
}
public static CubismExpressionData CreateInstance(CubismExp3Json json)
{
var expressionData = CreateInstance<CubismExpressionData>();
return CreateInstance(expressionData, json);
}
public static CubismExpressionData CreateInstance(CubismExpressionData expressionData, CubismExp3Json json)
{
expressionData.Type = json.Type;
expressionData.FadeInTime = json.FadeInTime;
expressionData.FadeOutTime = json.FadeOutTime;
expressionData.Parameters = new SerializableExpressionParameter[json.Parameters.Length];
for(var i = 0; i < json.Parameters.Length; ++i)
{
expressionData.Parameters[i].Id = json.Parameters[i].Id;
expressionData.Parameters[i].Value = json.Parameters[i].Value;
switch(json.Parameters[i].Blend)
{
case "Add":
expressionData.Parameters[i].Blend = CubismParameterBlendMode.Additive;
break;
case "Multiply":
expressionData.Parameters[i].Blend = CubismParameterBlendMode.Multiply;
break;
case "Overwrite":
expressionData.Parameters[i].Blend = CubismParameterBlendMode.Override;
break;
default:
expressionData.Parameters[i].Blend = CubismParameterBlendMode.Additive;
break;
}
}
return expressionData;
}
}
}

View File

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

View File

@@ -0,0 +1,21 @@
/**
* 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 UnityEngine;
namespace Live2D.Cubism.Framework.Expression
{
public class CubismExpressionList : ScriptableObject
{
/// <summary>
/// Cubism expression objects.
/// </summary>
[SerializeField]
public CubismExpressionData[] CubismExpressionObjects;
}
}

View File

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

View File

@@ -0,0 +1,23 @@
/**
* 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;
namespace Live2D.Cubism.Framework.Expression
{
/**
* @brief Structure that allows parameters to have expression values to be applied.
*/
public struct CubismExpressionParameterValue
{
public CubismParameter Parameter; ///< Parameter id.
public float AdditiveValue; ///< Additive value.
public float MultiplyValue; ///< Multiply value.
public float OverwriteValue; ///< Overwrite value.
}
}

View File

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

View File

@@ -0,0 +1,148 @@
/**
* 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 UnityEngine;
namespace Live2D.Cubism.Framework.Expression
{
/// <summary>
/// The cubism expression data.
/// </summary>
[System.Serializable]
public class CubismPlayingExpression
{
#region variable
/// <summary>
/// Expression type.
/// </summary>
[SerializeField]
public string Type;
/// <summary>
/// Expression fade in time.
/// </summary>
[SerializeField]
public float FadeInTime;
/// <summary>
/// Expression fade out time.
/// </summary>
[SerializeField]
public float FadeOutTime;
/// <summary>
/// Expression Weight.
/// </summary>
[SerializeField, Range(0.0f, 1.0f)]
public float Weight;
/// <summary>
/// Expression user time.
/// </summary>
[SerializeField]
public float ExpressionUserTime;
/// <summary>
/// Expression start time.
/// </summary>
[SerializeField]
public float ExpressionStartTime;
/// <summary>
/// Expression end time.
/// </summary>
[SerializeField]
public float ExpressionEndTime;
/// <summary>
/// Expression parameters cache.
/// </summary>
[SerializeField]
public CubismParameter[] Destinations;
/// <summary>
/// Expression parameter value.
/// </summary>
[SerializeField]
public float[] Value;
/// <summary>
/// Expression parameter blend mode.
/// </summary>
[SerializeField]
public CubismParameterBlendMode[] Blend;
/// <summary>
/// Expression fade weight.
/// </summary>
[NonSerialized, HideInInspector]
public float FadeWeight;
/// <summary>
/// Expression fade in weight.
/// </summary>
[NonSerialized, HideInInspector]
public float FadeInWeight;
/// <summary>
/// Expression fade out weight.
/// </summary>
[NonSerialized, HideInInspector]
public float FadeOutWeight;
#endregion
/// <summary>
/// Initialize expression data from <see cref="CubismExpressionData"/>.
/// </summary>
/// <param name="model">model.</param>
/// <param name="expressionData">Source.</param>
public static CubismPlayingExpression Create(CubismModel model, CubismExpressionData expressionData)
{
// Fail silently...
if(model == null || expressionData == null)
{
return null;
}
var ret = new CubismPlayingExpression();
ret.Type = expressionData.Type;
ret.FadeInTime = (expressionData.FadeInTime < 0.0f)
? 1.0f
: expressionData.FadeInTime;
ret.FadeOutTime = (expressionData.FadeOutTime < 0.0f)
? 1.0f
: expressionData.FadeOutTime;
ret.Weight = 1.0f;
ret.ExpressionUserTime = 0.0f;
ret.ExpressionStartTime = 0.0f;
ret.ExpressionEndTime = 0.0f;
var parameterCount = expressionData.Parameters.Length;
ret.Destinations = new CubismParameter[parameterCount];
ret.Value = new float[parameterCount];
ret.Blend = new CubismParameterBlendMode[parameterCount];
for(var i = 0; i < parameterCount; ++i)
{
ret.Destinations[i] = model.Parameters.FindById(expressionData.Parameters[i].Id);
ret.Value[i] = expressionData.Parameters[i].Value;
ret.Blend[i] = expressionData.Parameters[i].Blend;
}
return ret;
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0cea1418493279242ace46ba3dae8f02
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,238 @@
/**
* 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.Expression;
using Live2D.Cubism.Framework.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Live2D.Cubism.Core;
using UnityEditor;
using UnityEngine;
namespace Live2D.Cubism.Editor.Importers
{
public sealed class CubismExpression3JsonImporter : CubismImporterBase
{
/// <summary>
/// <see cref="CubismPose3Json"/> backing field.
/// </summary>
[NonSerialized]
private CubismExp3Json _expressionJson;
private CubismExp3Json ExpressionJson
{
get
{
if(_expressionJson != null)
{
return _expressionJson;
}
if(string.IsNullOrEmpty(AssetPath))
{
return null;
}
var expressionJson = AssetDatabase.LoadAssetAtPath<TextAsset>((AssetPath));
_expressionJson = CubismExp3Json.LoadFrom(expressionJson);
return _expressionJson;
}
}
#region Unity Event Handling
/// <summary>
/// Registers importer.
/// </summary>
[InitializeOnLoadMethod]
// ReSharper disable once UnusedMember.Local
private static void RegisterImporter()
{
CubismImporter.RegisterImporter<CubismExpression3JsonImporter>(".exp3.json");
CubismImporter.OnDidImportModel += OnModelImport;
}
#endregion
#region Cubism Import Event Handling
/// <summary>
/// Imports the corresponding asset.
/// </summary>
public override void Import()
{
var oldExpressionData = AssetDatabase.LoadAssetAtPath<CubismExpressionData>(AssetPath.Replace(".exp3.json", ".exp3.asset"));
// Create expression data.
CubismExpressionData expressionData;
if(oldExpressionData == null)
{
expressionData = CubismExpressionData.CreateInstance(ExpressionJson);
AssetDatabase.CreateAsset(expressionData, AssetPath.Replace(".exp3.json", ".exp3.asset"));
}
else
{
expressionData = CubismExpressionData.CreateInstance(oldExpressionData, ExpressionJson);
EditorUtility.CopySerialized(expressionData, oldExpressionData);
expressionData = oldExpressionData;
}
EditorUtility.SetDirty(expressionData);
// Add expression data to expression list.
var directoryName = Path.GetDirectoryName(AssetPath);
var modelDir = Path.GetDirectoryName(directoryName);
var modelName = Path.GetFileName(modelDir);
var expressionListPath = Path.GetDirectoryName(directoryName).Replace("\\", "/") + "/" + modelName + ".expressionList.asset";
var assetList = CubismCreatedAssetList.GetInstance();
var assetListIndex = assetList.AssetPaths.Contains(expressionListPath)
? assetList.AssetPaths.IndexOf(expressionListPath)
: -1;
var expressionList = GetExpressionList(expressionListPath);
if (expressionList == null)
{
Debug.LogError("CubismExpression3JsonImporter : Can not create CubismExpressionList.");
return;
}
// Rebuild the array if any element is null.
if (expressionList.CubismExpressionObjects.Any(element => element == null))
{
var cubismExpressionObjectsToList = expressionList.CubismExpressionObjects.ToList();
cubismExpressionObjectsToList.RemoveAll(element => element == null);
var expressionEqualityComparer = new ExpressionEqualityComparer();
var expressionDistinctObjectsArray = cubismExpressionObjectsToList.Distinct(expressionEqualityComparer).ToArray();
expressionList.CubismExpressionObjects = new CubismExpressionData[0];
Array.Resize(ref expressionList.CubismExpressionObjects, expressionDistinctObjectsArray.Length);
expressionList.CubismExpressionObjects = expressionDistinctObjectsArray;
}
// Find index.
var expressionName = Path.GetFileName(AssetPath).Replace(".json", "");
var expressionIndex = -1;
for (var i = 0; i < expressionList.CubismExpressionObjects.Length; ++i)
{
var expression = expressionList.CubismExpressionObjects[i];
if (expression.name != expressionName)
{
continue;
}
expressionIndex = i;
break;
}
// Set expression data.
if (expressionIndex != -1)
{
expressionList.CubismExpressionObjects[expressionIndex] = expressionData;
}
else
{
expressionIndex = expressionList.CubismExpressionObjects.Length;
Array.Resize(ref expressionList.CubismExpressionObjects, expressionIndex + 1);
expressionList.CubismExpressionObjects[expressionIndex] = expressionData;
}
EditorUtility.SetDirty(expressionList);
}
/// <summary>
/// Set expression list.
/// </summary>
/// <param name="importer">Event source.</param>
/// <param name="model">Imported model.</param>
private static void OnModelImport(CubismModel3JsonImporter importer, CubismModel model)
{
var expressionController = model.GetComponent<CubismExpressionController>();
if (expressionController == null || importer.Model3Json.FileReferences.Expressions == null)
{
return;
}
var modelDir = Path.GetDirectoryName(importer.AssetPath).Replace("\\","/");
var modelName = Path.GetFileName(modelDir);
var expressionListPath = modelDir + "/" + modelName + ".expressionList.asset";
var expressionList = GetExpressionList(expressionListPath);
if (expressionList == null)
{
return;
}
expressionController.ExpressionsList = expressionList;
}
#endregion
/// <summary>
/// Load the .expressionList.
/// If it does not exist, create a new one.
/// </summary>
/// <param name="expressionListPath">The path of the .expressionList.asset relative to the project.</param>
/// <returns>.expressionList.asset</returns>
private static CubismExpressionList GetExpressionList(string expressionListPath)
{
var assetList = CubismCreatedAssetList.GetInstance();
var assetListIndex = assetList.AssetPaths.Contains(expressionListPath)
? assetList.AssetPaths.IndexOf(expressionListPath)
: -1;
CubismExpressionList expressionList = null;
if (assetListIndex < 0)
{
expressionList = AssetDatabase.LoadAssetAtPath<CubismExpressionList>(expressionListPath);
if (expressionList == null)
{
expressionList = ScriptableObject.CreateInstance<CubismExpressionList>();
expressionList.CubismExpressionObjects = new CubismExpressionData[0];
AssetDatabase.CreateAsset(expressionList, expressionListPath);
}
assetList.Assets.Add(expressionList);
assetList.AssetPaths.Add(expressionListPath);
assetList.IsImporterDirties.Add(true);
}
else
{
expressionList = (CubismExpressionList)assetList.Assets[assetListIndex];
}
return expressionList;
}
private class ExpressionEqualityComparer : IEqualityComparer<CubismExpressionData>
{
public bool Equals(CubismExpressionData x, CubismExpressionData y)
{
return x.name == y.name;
}
public int GetHashCode(CubismExpressionData obj)
{
return obj.GetHashCode();
}
}
}
}

View File

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

View File

@@ -0,0 +1,3 @@
{
"reference": "GUID:e5d337e0b3581c343aafde08e6e1727e"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c577e6f892ebd3c43a2ebf539ca10a09
AssemblyDefinitionReferenceImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: