2023-03-15 01:28:03 +00:00
using System.Collections ;
using System.Collections.Generic ;
using UnityEngine ;
using HeavenStudio.Util ;
2023-06-10 19:13:29 +00:00
using Jukebox ;
2023-03-15 01:28:03 +00:00
namespace HeavenStudio.Games.Loaders
{
using static Minigames ;
public static class NtrGleeClubLoader
{
public static Minigame AddGame ( EventCaller eventCaller )
{
2023-04-02 02:28:23 +00:00
return new Minigame ( "gleeClub" , "Glee Club" , "cfcecf" , false , false , new List < GameAction > ( )
2023-03-15 01:28:03 +00:00
{
new GameAction ( "intervalStart" , "Start Interval" )
{
defaultLength = 1f ,
resizable = true
} ,
new GameAction ( "sing" , "Sing" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . Sing ( e . beat , e . length , e [ "semiTones" ] , e [ "semiTones1" ] , e [ "semiTonesPlayer" ] ,
e [ "close" ] , e [ "repeat" ] , e [ "semiTonesLeft2" ] , e [ "semiTonesLeft3" ] , e [ "semiTonesMiddle2" ] ) ; } ,
resizable = true ,
parameters = new List < Param > ( )
{
2023-03-15 19:11:31 +00:00
new Param ( "semiTones" , new EntityTypes . Integer ( - 24 , 24 , - 5 ) , "Semitones" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTones1" , new EntityTypes . Integer ( - 24 , 24 , - 1 ) , "Semitones (Next)" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTonesPlayer" , new EntityTypes . Integer ( - 24 , 24 , 2 ) , "Semitones (Player)" , "The number of semitones up or down this note should be pitched" ) ,
2023-03-15 01:28:03 +00:00
new Param ( "close" , GleeClub . MouthOpenClose . Both , "Close/Open Mouth" , "Should the chorus kids close/open their mouth?" ) ,
2023-09-08 14:27:07 +00:00
new Param ( "repeat" , false , "Repeating" , "Should the left and middle chorus kid repeat this singing cue?" , new List < Param . CollapseParam > ( )
{
new Param . CollapseParam ( x = > ( bool ) x , new string [ ] { "semiTonesLeft2" , "semiTonesLeft3" , "semiTonesMiddle2" } )
} ) ,
2023-03-15 01:28:03 +00:00
new Param ( "semiTonesLeft2" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones (Repeat Left First)" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTonesLeft3" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones (Repeat Left Last)" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTonesMiddle2" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones (Repeat Middle)" , "The number of semitones up or down this note should be pitched" ) ,
}
} ,
new GameAction ( "baton" , "Baton" )
{
preFunction = delegate { var e = eventCaller . currentEntity ; GleeClub . PreBaton ( e . beat ) ; } ,
defaultLength = 2f
} ,
new GameAction ( "togetherNow" , "Together Now!" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . TogetherNow ( e . beat , e [ "semiTones" ] , e [ "semiTones1" ] , e [ "semiTonesPlayer" ] , e [ "pitch" ] ) ; } ,
defaultLength = 4f ,
parameters = new List < Param > ( )
{
2023-03-15 19:11:31 +00:00
new Param ( "semiTones" , new EntityTypes . Integer ( - 24 , 24 , - 1 ) , "Semitones" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTones1" , new EntityTypes . Integer ( - 24 , 24 , 4 ) , "Semitones (Next)" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTonesPlayer" , new EntityTypes . Integer ( - 24 , 24 , 10 ) , "Semitones (Player)" , "The number of semitones up or down this note should be pitched" ) ,
2023-03-15 01:28:03 +00:00
new Param ( "pitch" , new EntityTypes . Float ( 0f , 5f , 1f ) , "Conductor Voice Pitch" , "Which pitch should the conductor's voice be at? (1 is normal pitch)" )
}
} ,
new GameAction ( "forceSing" , "Force Sing" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . ForceSing ( e [ "semiTones" ] , e [ "semiTones1" ] , e [ "semiTonesPlayer" ] ) ; } ,
defaultLength = 0.5f ,
parameters = new List < Param > ( )
{
new Param ( "semiTones" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTones1" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones (Next)" , "The number of semitones up or down this note should be pitched" ) ,
new Param ( "semiTonesPlayer" , new EntityTypes . Integer ( - 24 , 24 , 0 ) , "Semitones (Player)" , "The number of semitones up or down this note should be pitched" ) ,
}
} ,
new GameAction ( "presence" , "Toggle Chorus Kids Presence" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . ToggleKidsPresence ( ! e [ "left" ] , ! e [ "middle" ] , ! e [ "player" ] ) ; } ,
defaultLength = 0.5f ,
parameters = new List < Param > ( )
{
new Param ( "left" , false , "Left Kid Present" , "Should this chorus kid be present?" ) ,
new Param ( "middle" , false , "Middle Kid Present" , "Should this chorus kid be present?" ) ,
new Param ( "player" , false , "Player Kid Present" , "Should this chorus kid be present?" ) ,
}
} ,
new GameAction ( "fadeOutTime" , "Set Sing Game-Switch Fade Out Time" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . SetGameSwitchFadeOutTime ( e [ "fade" ] , e [ "fade1" ] , e [ "fadeP" ] ) ; } ,
defaultLength = 0.5f ,
parameters = new List < Param > ( )
{
new Param ( "fade" , new EntityTypes . Float ( 0 , 20f , 0f ) , "Left Chorus Kid" , "For how much time in seconds should this chorus kid's singing fade out?" ) ,
new Param ( "fade1" , new EntityTypes . Float ( 0 , 20f , 0f ) , "Middle Chorus Kid" , "For how much time in seconds should this chorus kid's singing fade out?" ) ,
new Param ( "fadeP" , new EntityTypes . Float ( 0 , 20f , 0f ) , "Player Chorus Kid" , "For how much time in seconds should this chorus kid's singing fade out?" ) ,
}
} ,
new GameAction ( "passTurn" , "Pass Turn" )
{
function = delegate { var e = eventCaller . currentEntity ; GleeClub . instance . PassTurn ( e . beat , e . length ) ; } ,
resizable = true ,
defaultLength = 0.5f ,
hidden = true
} ,
2023-05-28 17:34:44 +00:00
} ,
new List < string > ( ) { "ntr" , "repeat" } ,
"ntrchorus" , "en" ,
new List < string > ( ) { "en" }
) ;
2023-03-15 01:28:03 +00:00
}
}
}
namespace HeavenStudio.Games
{
using Scripts_GleeClub ;
public class GleeClub : Minigame
{
public enum MouthOpenClose
{
Both ,
OnlyOpen ,
OnlyClose
}
public struct QueuedSinging
{
2023-06-10 19:13:29 +00:00
public double startBeat ;
2023-03-15 01:28:03 +00:00
public float length ;
public int semiTones ;
public int semiTonesPlayer ;
public int closeMouth ;
public bool repeating ;
public int semiTonesLeft2 ;
public int semiTonesLeft3 ;
public int semiTonesMiddle2 ;
}
[Header("Prefabs")]
[SerializeField] GleeClubSingInput singInputPrefab ;
[Header("Components")]
[SerializeField] Animator heartAnim ;
[SerializeField] Animator condAnim ;
public ChorusKid leftChorusKid ;
public ChorusKid middleChorusKid ;
public ChorusKid playerChorusKid ;
[Header("Variables")]
static List < QueuedSinging > queuedSingings = new List < QueuedSinging > ( ) ;
2023-06-10 19:13:29 +00:00
static List < double > queuedBatons = new ( ) ;
2023-03-15 01:28:03 +00:00
bool intervalStarted ;
2023-06-10 19:13:29 +00:00
double intervalStartBeat ;
2023-03-15 01:28:03 +00:00
float beatInterval = 4f ;
public bool missed ;
public static GleeClub instance ;
float currentYellPitch = 1f ;
2023-03-15 19:11:31 +00:00
int startIntervalIndex ;
2023-06-10 19:13:29 +00:00
private List < RiqEntity > allIntervalEvents = new List < RiqEntity > ( ) ;
2023-03-15 19:11:31 +00:00
2023-03-15 01:28:03 +00:00
void Awake ( )
{
instance = this ;
2023-03-15 19:11:31 +00:00
var camEvents = EventCaller . GetAllInGameManagerList ( "gleeClub" , new string [ ] { "intervalStart" } ) ;
2023-06-10 19:13:29 +00:00
List < RiqEntity > tempEvents = new List < RiqEntity > ( ) ;
2023-03-15 19:11:31 +00:00
for ( int i = 0 ; i < camEvents . Count ; i + + )
{
2023-06-10 19:13:29 +00:00
if ( camEvents [ i ] . beat + camEvents [ i ] . beat > = Conductor . instance . songPositionInBeatsAsDouble )
2023-03-15 19:11:31 +00:00
{
tempEvents . Add ( camEvents [ i ] ) ;
}
}
allIntervalEvents = tempEvents ;
2023-03-15 01:28:03 +00:00
}
void Start ( )
{
if ( ! PlayerInput . Pressing ( ) & & Conductor . instance . isPlaying & & ! GameManager . instance . autoplay )
{
playerChorusKid . StartSinging ( ) ;
leftChorusKid . MissPose ( ) ;
middleChorusKid . MissPose ( ) ;
}
}
void OnDestroy ( )
{
if ( ! Conductor . instance . isPlaying | | Conductor . instance . isPaused )
{
if ( queuedSingings . Count > 0 ) queuedSingings . Clear ( ) ;
if ( queuedBatons . Count > 0 ) queuedBatons . Clear ( ) ;
}
2023-06-03 23:30:17 +00:00
foreach ( var evt in scheduledInputs )
{
evt . Disable ( ) ;
}
2023-03-15 01:28:03 +00:00
}
void Update ( )
{
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared )
2023-03-15 01:28:03 +00:00
{
2023-03-15 19:11:31 +00:00
if ( PlayerInput . Pressed ( ) & & ! IsExpectingInputNow ( InputType . STANDARD_DOWN ) )
{
playerChorusKid . StopSinging ( ) ;
leftChorusKid . MissPose ( ) ;
middleChorusKid . MissPose ( ) ;
ScoreMiss ( ) ;
}
if ( PlayerInput . PressedUp ( ) & & ! IsExpectingInputNow ( InputType . STANDARD_UP ) )
{
playerChorusKid . StartSinging ( ) ;
leftChorusKid . MissPose ( ) ;
middleChorusKid . MissPose ( ) ;
ScoreMiss ( ) ;
}
2023-03-15 01:28:03 +00:00
}
2023-03-15 19:11:31 +00:00
2023-03-15 01:28:03 +00:00
if ( Conductor . instance . isPlaying & & ! Conductor . instance . isPaused )
{
if ( queuedBatons . Count > 0 )
{
foreach ( var baton in queuedBatons )
{
Baton ( baton ) ;
}
queuedBatons . Clear ( ) ;
}
float normalizedBeat = Conductor . instance . GetPositionFromBeat ( intervalStartBeat , beatInterval ) ;
if ( normalizedBeat > = 1f & & intervalStarted )
{
PassTurn ( intervalStartBeat + beatInterval , 0f ) ;
}
2023-03-15 19:11:31 +00:00
if ( allIntervalEvents . Count > 0 )
{
if ( startIntervalIndex < allIntervalEvents . Count & & startIntervalIndex > = 0 )
{
2023-06-10 19:13:29 +00:00
if ( Conductor . instance . songPositionInBeatsAsDouble > = allIntervalEvents [ startIntervalIndex ] . beat )
2023-03-15 19:11:31 +00:00
{
2023-06-10 19:13:29 +00:00
StartInterval ( ( float ) allIntervalEvents [ startIntervalIndex ] . beat , allIntervalEvents [ startIntervalIndex ] . length ) ;
2023-03-15 19:11:31 +00:00
startIntervalIndex + + ;
}
}
}
2023-03-15 01:28:03 +00:00
}
if ( ! Conductor . instance . isPlaying | | Conductor . instance . isPaused )
{
if ( queuedSingings . Count > 0 ) queuedSingings . Clear ( ) ;
if ( queuedBatons . Count > 0 ) queuedBatons . Clear ( ) ;
}
}
public void ToggleKidsPresence ( bool left , bool middle , bool player )
{
leftChorusKid . TogglePresence ( left ) ;
middleChorusKid . TogglePresence ( middle ) ;
playerChorusKid . TogglePresence ( player ) ;
}
public void SetGameSwitchFadeOutTime ( float fadeOut , float fadeOut1 , float fadeOutPlayer )
{
leftChorusKid . gameSwitchFadeOutTime = fadeOut ;
middleChorusKid . gameSwitchFadeOutTime = fadeOut1 ;
playerChorusKid . gameSwitchFadeOutTime = fadeOutPlayer ;
}
public void ForceSing ( int semiTones , int semiTones1 , int semiTonesPlayer )
{
2023-06-10 19:13:29 +00:00
leftChorusKid . currentPitch = SoundByte . GetPitchFromSemiTones ( semiTones , true ) ;
middleChorusKid . currentPitch = SoundByte . GetPitchFromSemiTones ( semiTones1 , true ) ;
playerChorusKid . currentPitch = SoundByte . GetPitchFromSemiTones ( semiTonesPlayer , true ) ;
2023-03-15 01:28:03 +00:00
leftChorusKid . StartSinging ( true ) ;
middleChorusKid . StartSinging ( true ) ;
if ( ! PlayerInput . Pressing ( ) | | GameManager . instance . autoplay ) playerChorusKid . StartSinging ( true ) ;
else missed = true ;
}
2023-06-10 19:13:29 +00:00
public void TogetherNow ( double beat , int semiTones , int semiTones1 , int semiTonesPlayer , float conductorPitch )
2023-03-15 01:28:03 +00:00
{
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared ) ScheduleInput ( beat , 2.5f , InputType . STANDARD_UP , JustTogetherNow , Out , Out ) ;
if ( ! playerChorusKid . disappeared ) ScheduleInput ( beat , 3.5f , InputType . STANDARD_DOWN , JustTogetherNowClose , MissBaton , Out ) ;
2023-06-10 19:13:29 +00:00
float pitch = SoundByte . GetPitchFromSemiTones ( semiTones , true ) ;
float pitch1 = SoundByte . GetPitchFromSemiTones ( semiTones1 , true ) ;
currentYellPitch = SoundByte . GetPitchFromSemiTones ( semiTonesPlayer , true ) ;
2023-03-15 01:28:03 +00:00
MultiSound . Play ( new MultiSound . Sound [ ]
{
new MultiSound . Sound ( "gleeClub/togetherEN-01" , beat + 0.5f , conductorPitch ) ,
new MultiSound . Sound ( "gleeClub/togetherEN-02" , beat + 1f , conductorPitch ) ,
new MultiSound . Sound ( "gleeClub/togetherEN-03" , beat + 1.5f , conductorPitch ) ,
new MultiSound . Sound ( "gleeClub/togetherEN-04" , beat + 2f , conductorPitch , 1 , false , 0.02f ) ,
} ) ;
BeatAction . New ( instance . gameObject , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat + 1.5f , delegate
{
leftChorusKid . StartCrouch ( ) ;
middleChorusKid . StartCrouch ( ) ;
playerChorusKid . StartCrouch ( ) ;
} ) ,
new BeatAction . Action ( beat + 2.5f , delegate
{
leftChorusKid . currentPitch = pitch ;
middleChorusKid . currentPitch = pitch1 ;
leftChorusKid . StartYell ( ) ;
middleChorusKid . StartYell ( ) ;
} ) ,
new BeatAction . Action ( beat + 3.5f , delegate
{
leftChorusKid . StopSinging ( true ) ;
middleChorusKid . StopSinging ( true ) ;
} ) ,
new BeatAction . Action ( beat + 6f , delegate
{
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared ) ShowHeart ( beat + 6f ) ;
2023-03-15 01:28:03 +00:00
} )
} ) ;
}
void JustTogetherNow ( PlayerActionEvent caller , float state )
{
playerChorusKid . currentPitch = currentYellPitch ;
playerChorusKid . StartYell ( ) ;
}
void JustTogetherNowClose ( PlayerActionEvent caller , float state )
{
playerChorusKid . StopSinging ( true ) ;
}
2023-06-10 19:13:29 +00:00
public void StartInterval ( double beat , float length )
2023-03-15 01:28:03 +00:00
{
intervalStartBeat = beat ;
beatInterval = length ;
intervalStarted = true ;
}
2023-06-10 19:13:29 +00:00
public void Sing ( double beat , float length , int semiTones , int semiTones1 , int semiTonesPlayer , int closeMouth , bool repeating , int semiTonesLeft2 , int semiTonesLeft3 , int semiTonesMiddle2 )
2023-03-15 01:28:03 +00:00
{
2023-06-10 19:13:29 +00:00
float pitch = SoundByte . GetPitchFromSemiTones ( semiTones , true ) ;
2023-03-15 01:28:03 +00:00
if ( ! intervalStarted )
{
StartInterval ( beat , length ) ;
}
BeatAction . New ( instance . gameObject , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat , delegate { if ( closeMouth ! = ( int ) MouthOpenClose . OnlyClose ) leftChorusKid . currentPitch = pitch ; leftChorusKid . StartSinging ( ) ; } ) ,
new BeatAction . Action ( beat + length , delegate { if ( closeMouth ! = ( int ) MouthOpenClose . OnlyOpen ) leftChorusKid . StopSinging ( ) ; } ) ,
} ) ;
queuedSingings . Add ( new QueuedSinging
{
startBeat = beat - intervalStartBeat ,
length = length ,
semiTones = semiTones1 ,
closeMouth = closeMouth ,
semiTonesPlayer = semiTonesPlayer ,
repeating = repeating ,
semiTonesLeft2 = semiTonesLeft2 ,
semiTonesLeft3 = semiTonesLeft3 ,
semiTonesMiddle2 = semiTonesMiddle2
} ) ;
}
2023-06-10 19:13:29 +00:00
public void PassTurn ( double beat , float length )
2023-03-15 01:28:03 +00:00
{
if ( queuedSingings . Count = = 0 ) return ;
intervalStarted = false ;
missed = false ;
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared ) ShowHeart ( beat + length + beatInterval * 2 + 1 ) ;
2023-03-15 01:28:03 +00:00
foreach ( var sing in queuedSingings )
{
2023-06-10 19:13:29 +00:00
float playerPitch = SoundByte . GetPitchFromSemiTones ( sing . semiTonesPlayer , true ) ;
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared )
{
GleeClubSingInput spawnedInput = Instantiate ( singInputPrefab , transform ) ;
spawnedInput . pitch = playerPitch ;
spawnedInput . Init ( beat + length + sing . startBeat + beatInterval , sing . length , sing . closeMouth ) ;
}
2023-06-10 19:13:29 +00:00
float pitch = SoundByte . GetPitchFromSemiTones ( sing . semiTones , true ) ;
float pitchLeft2 = SoundByte . GetPitchFromSemiTones ( sing . semiTonesLeft2 , true ) ;
float pitchLeft3 = SoundByte . GetPitchFromSemiTones ( sing . semiTonesLeft3 , true ) ;
float pitchMiddle2 = SoundByte . GetPitchFromSemiTones ( sing . semiTonesMiddle2 , true ) ;
2023-03-15 01:28:03 +00:00
BeatAction . New ( instance . gameObject , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat + length + sing . startBeat , delegate
{
if ( sing . closeMouth ! = ( int ) MouthOpenClose . OnlyClose )
{
middleChorusKid . currentPitch = pitch ;
middleChorusKid . StartSinging ( ) ;
if ( sing . repeating )
{
leftChorusKid . currentPitch = pitchLeft2 ;
leftChorusKid . StartSinging ( ) ;
}
}
} ) ,
new BeatAction . Action ( beat + length + sing . startBeat + sing . length , delegate
{
if ( sing . closeMouth ! = ( int ) MouthOpenClose . OnlyOpen )
{
middleChorusKid . StopSinging ( ) ;
if ( sing . repeating ) leftChorusKid . StopSinging ( ) ;
}
} ) ,
new BeatAction . Action ( beat + length + sing . startBeat + beatInterval , delegate
{
if ( sing . closeMouth ! = ( int ) MouthOpenClose . OnlyClose & & sing . repeating )
{
middleChorusKid . currentPitch = pitchMiddle2 ;
leftChorusKid . currentPitch = pitchLeft3 ;
middleChorusKid . StartSinging ( ) ;
leftChorusKid . StartSinging ( ) ;
}
} ) ,
new BeatAction . Action ( beat + length + sing . startBeat + sing . length + beatInterval , delegate
{
if ( sing . closeMouth ! = ( int ) MouthOpenClose . OnlyOpen & & sing . repeating )
{
middleChorusKid . StopSinging ( ) ;
leftChorusKid . StopSinging ( ) ;
}
} ) ,
} ) ;
}
queuedSingings . Clear ( ) ;
}
2023-06-10 19:13:29 +00:00
public static void PreBaton ( double beat )
2023-03-15 01:28:03 +00:00
{
MultiSound . Play ( new MultiSound . Sound [ ]
{
new MultiSound . Sound ( "gleeClub/BatonUp" , beat ) ,
new MultiSound . Sound ( "gleeClub/BatonDown" , beat + 1 ) ,
} , forcePlay : true ) ;
if ( GameManager . instance . currentGame = = "gleeClub" )
{
instance . Baton ( beat ) ;
}
else
{
queuedBatons . Add ( beat ) ;
}
}
2023-06-10 19:13:29 +00:00
public void Baton ( double beat )
2023-03-15 01:28:03 +00:00
{
missed = false ;
2023-03-15 19:11:31 +00:00
if ( ! playerChorusKid . disappeared ) ScheduleInput ( beat , 1 , InputType . STANDARD_DOWN , JustBaton , MissBaton , Out ) ;
2023-03-15 01:28:03 +00:00
BeatAction . New ( instance . gameObject , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat , delegate
{
condAnim . DoScaledAnimationAsync ( "ConductorBatonUp" , 0.5f ) ;
} ) ,
new BeatAction . Action ( beat + 1 , delegate
{
condAnim . DoScaledAnimationAsync ( "ConductorBatonDown" , 0.5f ) ;
leftChorusKid . StopSinging ( ) ;
middleChorusKid . StopSinging ( ) ;
} ) ,
new BeatAction . Action ( beat + 2 , delegate
{
condAnim . DoUnscaledAnimation ( "ConductorIdle" , 0 , - 1 ) ;
} ) ,
} ) ;
}
void JustBaton ( PlayerActionEvent caller , float state )
{
playerChorusKid . StopSinging ( ) ;
ShowHeart ( caller . timer + caller . startBeat + 1f ) ;
}
void MissBaton ( PlayerActionEvent caller )
{
missed = true ;
}
void Out ( PlayerActionEvent caller ) { }
2023-06-10 19:13:29 +00:00
public void ShowHeart ( double beat )
2023-03-15 01:28:03 +00:00
{
BeatAction . New ( instance . gameObject , new List < BeatAction . Action > ( )
{
new BeatAction . Action ( beat , delegate
{
if ( missed )
{
leftChorusKid . MissPose ( ) ;
middleChorusKid . MissPose ( ) ;
return ;
}
heartAnim . Play ( "HeartIdle" , 0 , 0 ) ;
} ) ,
new BeatAction . Action ( beat + 2 , delegate
{
heartAnim . Play ( "HeartNothing" , 0 , 0 ) ;
} )
} ) ;
}
}
}