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 collapseOn; public RiqEntity entity; - public PropertyCollapse(List collapseables, Func collapseOn, RiqEntity entity) + public PropertyCollapse(List collapseables, Func collapseOn, RiqEntity entity) { this.collapseables = collapseables; this.collapseOn = collapseOn;