diff --git a/Assets/Bundled/Games/FanClub/Sprites/Animations/Arisa/Arisa.controller b/Assets/Bundled/Games/FanClub/Sprites/Animations/Arisa/Arisa.controller
index 0b3ac57f..3b598205 100644
--- a/Assets/Bundled/Games/FanClub/Sprites/Animations/Arisa/Arisa.controller
+++ b/Assets/Bundled/Games/FanClub/Sprites/Animations/Arisa/Arisa.controller
@@ -1219,9 +1219,6 @@ AnimatorStateTransition:
- m_ConditionMode: 6
m_ConditionEvent: Mouth Type
m_EventTreshold: 6
- - m_ConditionMode: 4
- m_ConditionEvent: Mouth Type
- m_EventTreshold: 6
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 4795373212119028058}
m_Solo: 0
@@ -1476,9 +1473,6 @@ AnimatorStateTransition:
- m_ConditionMode: 6
m_ConditionEvent: Mouth Type
m_EventTreshold: 0
- - m_ConditionMode: 3
- m_ConditionEvent: Mouth Type
- m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -4363713536613775826}
m_Solo: 0
diff --git a/Assets/Scripts/Games/FanClub/FanClub.cs b/Assets/Scripts/Games/FanClub/FanClub.cs
index a6a48813..06aa28ae 100644
--- a/Assets/Scripts/Games/FanClub/FanClub.cs
+++ b/Assets/Scripts/Games/FanClub/FanClub.cs
@@ -63,24 +63,32 @@ namespace HeavenStudio.Games.Loaders
},
new GameAction("arisa faceposer", "Idol Face Poser")
{
- function = delegate { var e = eventCaller.currentEntity; FanClub.instance.SetArisaFacePoser(e["poserOn"], e["mouth"], e["mouthEnd"], e["eyeL"], e["eyeR"], e["eyex"], e["eyey"], e["eyeEaseEnable"], e.beat, e.length, e["eyeEase"]); },
+ function = delegate { var e = eventCaller.currentEntity; FanClub.instance.SetArisaFacePoser(e["poserOn"], e["mouthOn"], e["eyeOn"], e["mouth"], e["mouthEnd"], e["eyeL"], e["eyeR"], e["eyex"], e["eyey"], e["eyeEaseEnable"], e.beat, e.length, e["eyeEase"]); },
resizable = true,
defaultLength = 1,
parameters = new List()
{
new Param("poserOn", true, "Enable Face Poser", "Enables Face Poser on Arisa.", new List()
{
- new Param.CollapseParam((x, _) => (bool)x, new string[] { "mouth", "eyeL", "eyeR", "eyex", "eyey" }),
+ new Param.CollapseParam((x, _) => (bool)x, new string[] { "mouthOn", "eyeOn" }),
+ }),
+ new Param("mouthOn", true, "Enable Lip Sync Controls", "Enables Lip Sync controls.", new List()
+ {
+ new Param.CollapseParam((x, e) => (bool)x && (bool)e["poserOn"], new string[] { "mouth", "mouthEnd" }),
}),
new Param("mouth", FanClub.MouthShape.Normal, "Mouth Shape", "Sets mouth shape."),
new Param("mouthEnd", FanClub.MouthShape.Normal, "Last Mouth Shape", "Sets mouth shape at the end of the event."),
+ new Param("eyeOn", true, "Enable Eye Shaping", "Enables Eye Shaping controls.", new List()
+ {
+ new Param.CollapseParam((x, e) => (bool)x && (bool)e["poserOn"], new string[] { "eyeL", "eyeR", "eyex", "eyey", "eyeEaseEnable"}),
+ }),
new Param("eyeL", FanClub.EyeShape.Normal, "Left Eye Shape", "Sets left eye shape."),
new Param("eyeR", FanClub.EyeShape.Normal, "Right Eye Shape", "Sets right eye shape."),
new Param("eyex", new EntityTypes.Float(-1f, 1f, 0f), "Horizontal Eye Movement", "Sets horizontal eye movement."),
new Param("eyey", new EntityTypes.Float(-1f, 1f, 0f), "Vertical Eye Movement", "Sets vertical eye movement."),
new Param("eyeEaseEnable", true, "Ease Eye Movement", "Enable easing for eye movement.", new List()
{
- new Param.CollapseParam((x, _) => (bool)x, new string[] { "eyeEase" }),
+ new Param.CollapseParam((x, e) => (bool)x && (bool)e["poserOn"] && (bool)e["eyeOn"], new string[] { "eyeEase" }),
}),
new Param("eyeEase", Util.EasingFunction.Ease.Instant, "Easing Type", "Set the type of easing for eye movement."),
}
@@ -687,28 +695,37 @@ namespace HeavenStudio.Games
}
System.Threading.CancellationTokenSource mouthCancel = null;
- public void SetArisaFacePoser(bool enable, int mouth, int mouthEnd, int eyeL, int eyeR, float eyeX, float eyeY, bool ease, double beat, float length, int easeType)
+ public void SetArisaFacePoser(bool enable, bool enableMouth, bool enableEye, int mouth, int mouthEnd, int eyeL, int eyeR, float eyeX, float eyeY, bool ease, double beat, float length, int easeType)
{
- if (mouthCancel != null)
- {
- mouthCancel.Cancel();
- mouthCancel = null;
- }
arisaController.ToggleFacePoser(enable);
- arisaController.SetMouthShape(mouth);
- arisaController.SetEyeShape(eyeL, eyeR);
- if (ease)
+ // eye control
+ if (enableEye)
{
- arisaController.SetEyeTargetEase(beat, length, eyeX, eyeY, (Util.EasingFunction.Ease)easeType);
+ arisaController.SetEyeShape(eyeL, eyeR);
+ if (ease)
+ {
+ arisaController.SetEyeTargetEase(beat, length, eyeX, eyeY, (Util.EasingFunction.Ease)easeType);
+ }
+ else
+ {
+ arisaController.SetEyeTarget(eyeX, eyeY);
+ }
}
- else
+
+ // mouth control
+ if (enableMouth)
{
- arisaController.SetEyeTarget(eyeX, eyeY);
+ if (mouthCancel != null)
+ {
+ mouthCancel.Cancel();
+ mouthCancel = null;
+ }
+ arisaController.SetMouthShape(mouth);
+ mouthCancel = BeatAction.New(instance, new List()
+ {
+ new BeatAction.Action(beat + length, delegate { arisaController.SetMouthShape(mouthEnd);}),
+ });
}
- mouthCancel = BeatAction.New(instance, new List()
- {
- new BeatAction.Action(beat + length, delegate { arisaController.SetMouthShape(mouthEnd);}),
- });
}
const float HAIS_LENGTH = 4.5f;
diff --git a/Assets/Scripts/LevelEditor/EventSelector/EventParameterManager.cs b/Assets/Scripts/LevelEditor/EventSelector/EventParameterManager.cs
index 1f7cd05b..25966936 100644
--- a/Assets/Scripts/LevelEditor/EventSelector/EventParameterManager.cs
+++ b/Assets/Scripts/LevelEditor/EventSelector/EventParameterManager.cs
@@ -133,7 +133,7 @@ namespace HeavenStudio.Editor
EventPropertyPrefab input = currentProperties[p.propertyName];
foreach (var c in p.collapseParams)
{
- List collapseables = c.collapseables.Select(x => currentProperties[x].gameObject).ToList();
+ List collapseables = c.collapseables.Select(x => currentProperties[x]).ToList();
input.propertyCollapses.Add(new EventPropertyPrefab.PropertyCollapse(collapseables, c.CollapseOn, entity));
}
input.SetCollapses(p.parameter);
diff --git a/Assets/Scripts/LevelEditor/EventSelector/EventPropertyPrefab.cs b/Assets/Scripts/LevelEditor/EventSelector/EventPropertyPrefab.cs
index f8407f45..aa291a19 100644
--- a/Assets/Scripts/LevelEditor/EventSelector/EventPropertyPrefab.cs
+++ b/Assets/Scripts/LevelEditor/EventSelector/EventPropertyPrefab.cs
@@ -32,25 +32,65 @@ namespace HeavenStudio.Editor
public void UpdateCollapse(object type)
{
+ List recursedCollapse = new() { this };
foreach (var p in propertyCollapses)
{
- if (p.collapseables.Count > 0) { // there could be a better way to do it, but for now this works
- foreach (var c in p.collapseables) {
- if (c != null) c.SetActive(p.collapseOn(type, p.entity) && gameObject.activeSelf);
+ if (p.collapseables.Count > 0)
+ {
+ foreach (var c in p.collapseables)
+ {
+ if (c != null)
+ {
+ c.gameObject.SetActive(p.collapseOn(type, p.entity) && gameObject.activeSelf);
+ c.RecursiveUpdateCollapse(recursedCollapse);
+ }
}
- } else {
+ }
+ else
+ {
_ = p.collapseOn(type, p.entity);
}
}
}
+ public void RecursiveUpdateCollapse(List updated)
+ {
+ if (updated == null)
+ {
+ updated = new();
+ }
+ if (updated.Contains(this))
+ {
+ return;
+ }
+ updated.Add(this);
+ foreach (var p in propertyCollapses)
+ {
+ if (p.collapseables.Count > 0)
+ {
+ foreach (var c in p.collapseables)
+ {
+ if (c != null)
+ {
+ c.gameObject.SetActive(p.collapseOn(entity[propertyName], p.entity) && gameObject.activeSelf);
+ c.RecursiveUpdateCollapse(updated);
+ }
+ }
+ }
+ else
+ {
+ _ = p.collapseOn(entity[propertyName], p.entity);
+ }
+ }
+ }
+
public class PropertyCollapse
{
- public List collapseables;
+ public List collapseables;
public Func