您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
271 行
8.3 KiB
271 行
8.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using VrmLib;
|
|
|
|
namespace UniVRM10
|
|
{
|
|
[Serializable]
|
|
public sealed class VRM10ObjectExpression
|
|
{
|
|
#region Preset
|
|
[SerializeField, Header("Emotion")]
|
|
public VRM10Expression Happy;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Angry;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Sad;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Relaxed;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Surprised;
|
|
|
|
[SerializeField, Header("LipSync")]
|
|
public VRM10Expression Aa;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Ih;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Ou;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Ee;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression Oh;
|
|
|
|
[SerializeField, Header("Blink")]
|
|
public VRM10Expression Blink;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression BlinkLeft;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression BlinkRight;
|
|
|
|
[SerializeField, Header("LookAt")]
|
|
public VRM10Expression LookUp;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression LookDown;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression LookLeft;
|
|
|
|
[SerializeField]
|
|
public VRM10Expression LookRight;
|
|
|
|
[SerializeField, Header("Other")]
|
|
public VRM10Expression Neutral;
|
|
#endregion
|
|
|
|
[SerializeField]
|
|
public List<VRM10Expression> CustomClips = new List<VRM10Expression>();
|
|
|
|
public IEnumerable<(ExpressionPreset Preset, VRM10Expression Clip)> Clips
|
|
{
|
|
get
|
|
{
|
|
if (Happy != null) yield return (ExpressionPreset.happy, Happy);
|
|
if (Angry != null) yield return (ExpressionPreset.angry, Angry);
|
|
if (Sad != null) yield return (ExpressionPreset.sad, Sad);
|
|
if (Relaxed != null) yield return (ExpressionPreset.relaxed, Relaxed);
|
|
if (Surprised != null) yield return (ExpressionPreset.surprised, Surprised);
|
|
if (Aa != null) yield return (ExpressionPreset.aa, Aa);
|
|
if (Ih != null) yield return (ExpressionPreset.ih, Ih);
|
|
if (Ou != null) yield return (ExpressionPreset.ou, Ou);
|
|
if (Ee != null) yield return (ExpressionPreset.ee, Ee);
|
|
if (Oh != null) yield return (ExpressionPreset.oh, Oh);
|
|
if (Blink != null) yield return (ExpressionPreset.blink, Blink);
|
|
if (BlinkLeft != null) yield return (ExpressionPreset.blinkLeft, BlinkLeft);
|
|
if (BlinkRight != null) yield return (ExpressionPreset.blinkRight, BlinkRight);
|
|
if (LookUp != null) yield return (ExpressionPreset.lookUp, LookUp);
|
|
if (LookDown != null) yield return (ExpressionPreset.lookDown, LookDown);
|
|
if (LookLeft != null) yield return (ExpressionPreset.lookLeft, LookLeft);
|
|
if (LookRight != null) yield return (ExpressionPreset.lookRight, LookRight);
|
|
if (Neutral != null) yield return (ExpressionPreset.neutral, Neutral);
|
|
foreach (var clip in CustomClips)
|
|
{
|
|
if (clip != null)
|
|
{
|
|
yield return (ExpressionPreset.custom, clip);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ExpressionKey CreateKey(VRM10Expression clip)
|
|
{
|
|
foreach (var (preset, c) in Clips)
|
|
{
|
|
if (c == clip)
|
|
{
|
|
return new ExpressionKey(preset, clip.name);
|
|
}
|
|
}
|
|
|
|
// not found
|
|
// return default(ExpressionKey);
|
|
throw new KeyNotFoundException();
|
|
}
|
|
|
|
public void AddClip(ExpressionPreset preset, VRM10Expression clip)
|
|
{
|
|
switch (preset)
|
|
{
|
|
case ExpressionPreset.happy: Happy = clip; break;
|
|
case ExpressionPreset.angry: Angry = clip; break;
|
|
case ExpressionPreset.sad: Sad = clip; break;
|
|
case ExpressionPreset.relaxed: Relaxed = clip; break;
|
|
case ExpressionPreset.surprised: Surprised = clip; break;
|
|
case ExpressionPreset.aa: Aa = clip; break;
|
|
case ExpressionPreset.ih: Ih = clip; break;
|
|
case ExpressionPreset.ou: Ou = clip; break;
|
|
case ExpressionPreset.ee: Ee = clip; break;
|
|
case ExpressionPreset.oh: Oh = clip; break;
|
|
case ExpressionPreset.blink: Blink = clip; break;
|
|
case ExpressionPreset.blinkLeft: BlinkLeft = clip; break;
|
|
case ExpressionPreset.blinkRight: BlinkRight = clip; break;
|
|
case ExpressionPreset.lookUp: LookUp = clip; break;
|
|
case ExpressionPreset.lookDown: LookDown = clip; break;
|
|
case ExpressionPreset.lookLeft: LookLeft = clip; break;
|
|
case ExpressionPreset.lookRight: LookRight = clip; break;
|
|
case ExpressionPreset.neutral: Neutral = clip; break;
|
|
default: CustomClips.Add(clip); break;
|
|
}
|
|
}
|
|
|
|
public void Replace(IDictionary<VRM10Expression, VRM10Expression> map)
|
|
{
|
|
foreach (var (k, v) in map.Select(kv => (kv.Key, kv.Value)))
|
|
{
|
|
Replace(k, v);
|
|
}
|
|
}
|
|
|
|
void Replace(VRM10Expression src, VRM10Expression dst)
|
|
{
|
|
if (Happy == src)
|
|
{
|
|
Happy = dst; return;
|
|
}
|
|
if (Angry == src)
|
|
{
|
|
Angry = dst; return;
|
|
}
|
|
if (Sad == src)
|
|
{
|
|
Sad = dst; return;
|
|
}
|
|
if (Relaxed == src)
|
|
{
|
|
Relaxed = dst; return;
|
|
}
|
|
if (Surprised == src)
|
|
{
|
|
Surprised = dst; return;
|
|
}
|
|
if (Aa == src)
|
|
{
|
|
Aa = dst; return;
|
|
}
|
|
if (Ih == src)
|
|
{
|
|
Ih = dst; return;
|
|
}
|
|
if (Ou == src)
|
|
{
|
|
Ou = dst; return;
|
|
}
|
|
if (Ee == src)
|
|
{
|
|
Ee = dst; return;
|
|
}
|
|
if (Oh == src)
|
|
{
|
|
Oh = dst; return;
|
|
}
|
|
if (Blink == src)
|
|
{
|
|
Blink = dst; return;
|
|
}
|
|
if (BlinkLeft == src)
|
|
{
|
|
BlinkLeft = dst; return;
|
|
}
|
|
if (BlinkRight == src)
|
|
{
|
|
BlinkRight = dst; return;
|
|
}
|
|
if (LookUp == src)
|
|
{
|
|
LookUp = dst; return;
|
|
}
|
|
if (LookDown == src)
|
|
{
|
|
LookDown = dst; return;
|
|
}
|
|
if (LookLeft == src)
|
|
{
|
|
LookLeft = dst; return;
|
|
}
|
|
if (LookRight == src)
|
|
{
|
|
LookRight = dst; return;
|
|
}
|
|
if (Neutral == src)
|
|
{
|
|
Neutral = dst; return;
|
|
}
|
|
|
|
for (int i = 0; i < CustomClips.Count; ++i)
|
|
{
|
|
if (CustomClips[i] == src)
|
|
{
|
|
CustomClips[i] = dst;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// NullのClipを削除して詰める
|
|
/// </summary>
|
|
public void RemoveNullClip()
|
|
{
|
|
if (CustomClips == null)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = CustomClips.Count - 1; i >= 0; --i)
|
|
{
|
|
if (CustomClips[i] == null)
|
|
{
|
|
CustomClips.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
// /// <summary>
|
|
// /// Unknown以外で存在しないものを全て作る
|
|
// /// </summary>
|
|
// public void CreateDefaultPreset()
|
|
// {
|
|
// foreach (var preset in ((ExpressionPreset[])Enum.GetValues(typeof(ExpressionPreset)))
|
|
// .Where(x => x != ExpressionPreset.custom)
|
|
// )
|
|
// {
|
|
// CreateDefaultPreset(preset);
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
}
|
|
}
|