mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 15:07:39 +02:00
Monkey watch (#555)
* basic setup+inputs this is gonna be so annoying to optimize i am SO overwhelmed with the options that i have object pooling, disabling the monkeys, literally just placing them manually... idk. * custom monkeys + more setup stuff it's all coming together . * a few tweaks committing to update the spritesheet * hi ev * player stuff * player anims * particles * more of prefab * upscale for this sheet * prefab more * oops * anims n stuff * assign the stuff, a little bit of rotation * better sheet * balloon sheet * particles * Revert "particles" This reverts commitfe4d589731
. * Revert "Revert "particles"" This reverts commitce117b280d
. * fixed the watch outline + pink monkey prefab variant the bccad really is a life saver * anims for monkeys * convert to dictionary yippee for dictionaries * better camera * click animations are all done * custom monkeys are actually good now :) * prefab adjustments * oopps2 * tweaked particles * inactive monkeys/custom monkeys + prefab fixes they should work perfectly now, and the prefab should also need no further adjustment hopefully... * many animations * click fixes * the prefab needed One more adjustment * oops again hopefully the shadow is good now * sheet adjustment * all yellow anims done * progress. starting on the monkeys appear block rn, and then i'll work on the monkey spawning logic. honestly should be pretty easy (and i DON'T think this will be something i look back on as if i was crazy 😄 ) * open / close hole * monkey spawning working better * pink monkey anims * clean slate * gonna test something * proper camera * Camera movements done * pink monkey sounds and a small bug fix * clock arrow now moves * gettin ready to spawn el monkeys * monkeys should spawn now ig * bug fixes * oops * monkeys appear added * more fixes yahoo * shadow tweak * bug fixes * zoom out beginnings * hour more smooth * smooth minute too * it now zooms out lol * middle monkey * oopsie doopsie * hot air balloon * oops * anim * disappear fix * ticks on input now * prepare earlier * tiny tweak * oops again * fixed the input bug * holes * middle monkey anims * fixed layering * zoom out tweaks and shadow movement * camera tweak * tweaks * quad * camera tweak * quart * inspcetor * shadow correct * Okay * zoom out seperation * instant * balloon movement * balloon fixed * fixed particle * icon * fixed beataction parameters * monkey watch camera refactor run sourcegen --------- Co-authored-by: AstrlJelly <bdlawson115@gmail.com> Co-authored-by: ev <85412919+evdial@users.noreply.github.com> Co-authored-by: minenice55 <star.elementa@gmail.com>
This commit is contained in:
8
Assets/Scripts/Games/MonkeyWatch.meta
Normal file
8
Assets/Scripts/Games/MonkeyWatch.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9498cb5d0e7602445ae5927c270f232e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
133
Assets/Scripts/Games/MonkeyWatch/BalloonHandler.cs
Normal file
133
Assets/Scripts/Games/MonkeyWatch/BalloonHandler.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MonkeyWatch
|
||||
{
|
||||
public class BalloonHandler : MonoBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private Transform anchor;
|
||||
[SerializeField] private Transform target;
|
||||
[SerializeField] private Transform balloonTrans;
|
||||
[SerializeField] private SpriteRenderer[] srs;
|
||||
[SerializeField] private SpriteRenderer shadow;
|
||||
[Header("Properties")]
|
||||
[SerializeField] private float xOffset;
|
||||
[SerializeField] private float yOffset;
|
||||
|
||||
private float shadowOpacity;
|
||||
private float additionalXOffset;
|
||||
private float additionalYOffset;
|
||||
private double movementFirstBeat = -2;
|
||||
private double movementLastBeat = -1;
|
||||
|
||||
private List<Movement> movements = new();
|
||||
private int movementIndex = 0;
|
||||
|
||||
private struct Movement
|
||||
{
|
||||
public double beat;
|
||||
public float length;
|
||||
|
||||
public float xStart;
|
||||
public float xEnd;
|
||||
public float yStart;
|
||||
public float yEnd;
|
||||
public float angleStart;
|
||||
public float angleEnd;
|
||||
public Util.EasingFunction.Ease ease;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
shadowOpacity = shadow.color.a;
|
||||
}
|
||||
|
||||
public void Init(double beat)
|
||||
{
|
||||
var allEvents = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "balloon" });
|
||||
allEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
if (allEvents.Count > 0)
|
||||
{
|
||||
movementFirstBeat = allEvents[0].beat;
|
||||
movementLastBeat = allEvents[^1].beat + allEvents[^1].length - 0.25;
|
||||
}
|
||||
foreach (var e in allEvents)
|
||||
{
|
||||
movements.Add(new Movement
|
||||
{
|
||||
beat = e.beat,
|
||||
length = e.length,
|
||||
xStart = e["xStart"],
|
||||
xEnd = e["xEnd"],
|
||||
yStart = e["yStart"],
|
||||
yEnd = e["yEnd"],
|
||||
angleStart = e["angleStart"],
|
||||
angleEnd = e["angleEnd"],
|
||||
ease = (Util.EasingFunction.Ease)e["ease"]
|
||||
});
|
||||
}
|
||||
Update();
|
||||
}
|
||||
|
||||
private void UpdateIndex()
|
||||
{
|
||||
movementIndex++;
|
||||
if (movementIndex >= movements.Count) return;
|
||||
if (Conductor.instance.songPositionInBeatsAsDouble > movements[movementIndex].beat + movements[movementIndex].length)
|
||||
{
|
||||
UpdateIndex();
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var cond = Conductor.instance;
|
||||
float normalizedFirst = Mathf.Clamp01(cond.GetPositionFromBeat(movementFirstBeat, 0.25f));
|
||||
float normalizedLast = Mathf.Clamp01(cond.GetPositionFromBeat(movementLastBeat, 0.25f));
|
||||
if (normalizedFirst >= 1)
|
||||
{
|
||||
foreach (var sr in srs)
|
||||
{
|
||||
sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, 1 - normalizedLast);
|
||||
}
|
||||
shadow.color = new Color(shadow.color.r, shadow.color.g, shadow.color.b, Mathf.Lerp(shadowOpacity, 0, normalizedLast));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var sr in srs)
|
||||
{
|
||||
sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, normalizedFirst);
|
||||
}
|
||||
shadow.color = new Color(shadow.color.r, shadow.color.g, shadow.color.b, Mathf.Lerp(0, shadowOpacity, normalizedFirst));
|
||||
}
|
||||
if (movements.Count > 0 && movementIndex < movements.Count)
|
||||
{
|
||||
if (cond.songPositionInBeatsAsDouble > movements[movementIndex].beat + movements[movementIndex].length)
|
||||
{
|
||||
UpdateIndex();
|
||||
if (movementIndex >= movements.Count) return;
|
||||
}
|
||||
|
||||
var e = movements[movementIndex];
|
||||
|
||||
float normalizedBeat = Mathf.Clamp01(cond.GetPositionFromBeat(e.beat, e.length));
|
||||
|
||||
var func = Util.EasingFunction.GetEasingFunction(e.ease);
|
||||
|
||||
float newX = func(e.xStart, e.xEnd, normalizedBeat);
|
||||
float newY = func(e.yStart, e.yEnd, normalizedBeat);
|
||||
float newAngle = func(e.angleStart, e.angleEnd, normalizedBeat);
|
||||
|
||||
additionalXOffset = newX;
|
||||
additionalYOffset = newY;
|
||||
|
||||
anchor.localEulerAngles = new Vector3(0, 0, newAngle);
|
||||
}
|
||||
|
||||
balloonTrans.position = new Vector3(target.position.x + xOffset + additionalXOffset, target.position.y + yOffset + additionalYOffset, target.position.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Games/MonkeyWatch/BalloonHandler.cs.meta
Normal file
11
Assets/Scripts/Games/MonkeyWatch/BalloonHandler.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4201255ef0e619469e1ef4af5aebcb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
115
Assets/Scripts/Games/MonkeyWatch/MonkeyClockArrow.cs
Normal file
115
Assets/Scripts/Games/MonkeyWatch/MonkeyClockArrow.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using HeavenStudio.Util;
|
||||
using Starpelly;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MonkeyWatch
|
||||
{
|
||||
public class MonkeyClockArrow : MonoBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private Animator anim;
|
||||
[SerializeField] private Transform anchorRotateTransform;
|
||||
[SerializeField] private Animator playerMonkeyAnim;
|
||||
[SerializeField] private ParticleSystem yellowClap;
|
||||
[SerializeField] private ParticleSystem pinkClap;
|
||||
[SerializeField] private Transform shadowTrans;
|
||||
[SerializeField] private Transform camMoveTrans;
|
||||
[Header("Properties")]
|
||||
[SerializeField] private float shadowXRange = 2f;
|
||||
[SerializeField] private float shadowYRange = 1f;
|
||||
|
||||
private MonkeyWatch game;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
game = MonkeyWatch.instance;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (PlayerInput.GetIsAction(MonkeyWatch.InputAction_BasicPress) && !game.IsExpectingInputNow(MonkeyWatch.InputAction_BasicPress))
|
||||
{
|
||||
PlayerClap(false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Move()
|
||||
{
|
||||
anchorRotateTransform.localEulerAngles = new Vector3(0, 0, anchorRotateTransform.localEulerAngles.z - 6);
|
||||
anim.DoScaledAnimationAsync("Click", 0.4f);
|
||||
MoveShadow();
|
||||
}
|
||||
|
||||
private void MoveShadow()
|
||||
{
|
||||
float realAngle = anchorRotateTransform.localEulerAngles.z % 360 - 360;
|
||||
realAngle *= -1;
|
||||
|
||||
float x;
|
||||
float y;
|
||||
|
||||
if (realAngle <= 180)
|
||||
{
|
||||
float normalizedAngle = Mathp.Normalize(realAngle, 0, 180);
|
||||
x = Mathf.Lerp(0, shadowXRange, normalizedAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
float normalizedAngle = Mathp.Normalize(realAngle, 180, 360);
|
||||
x = Mathf.Lerp(shadowXRange, 0, normalizedAngle);
|
||||
}
|
||||
|
||||
float realAngleY = anchorRotateTransform.localEulerAngles.z % 180 - 180;
|
||||
realAngleY *= -1;
|
||||
|
||||
if (realAngleY <= 90)
|
||||
{
|
||||
float normalizedAngle = Mathp.Normalize(realAngleY, 0, 90);
|
||||
y = Mathf.Lerp(0, shadowYRange, normalizedAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
float normalizedAngle = Mathp.Normalize(realAngleY, 90, 180);
|
||||
y = Mathf.Lerp(shadowYRange, 0, normalizedAngle);
|
||||
}
|
||||
shadowTrans.localPosition = new Vector3(x, y);
|
||||
}
|
||||
|
||||
public void MoveToAngle(float angle)
|
||||
{
|
||||
anchorRotateTransform.localEulerAngles = new Vector3(0, 0, -angle);
|
||||
}
|
||||
|
||||
public bool PlayerIsClapAnim()
|
||||
{
|
||||
return !playerMonkeyAnim.IsAnimationNotPlaying();
|
||||
}
|
||||
|
||||
public void PlayerClap(bool big, bool barely, bool whiff)
|
||||
{
|
||||
if (playerMonkeyAnim.IsPlayingAnimationNames("PlayerClapBarely") && whiff) return;
|
||||
if (whiff)
|
||||
{
|
||||
game.middleMonkey.DoScaledAnimationAsync("MiddleMonkeyMiss", 0.4f);
|
||||
SoundByte.PlayOneShot("miss");
|
||||
}
|
||||
if (barely || whiff)
|
||||
{
|
||||
playerMonkeyAnim.DoScaledAnimationAsync("PlayerClapBarely", 0.4f);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerMonkeyAnim.DoScaledAnimationAsync(big ? "PlayerClapBig" : "PlayerClap", 0.4f);
|
||||
ParticleSystem clapToSpawn = big ? pinkClap : yellowClap;
|
||||
ParticleSystem spawnedClap = Instantiate(clapToSpawn, camMoveTrans, true);
|
||||
spawnedClap.transform.eulerAngles = Vector3.zero;
|
||||
spawnedClap.transform.GetChild(0).GetComponent<ParticleSystem>().SetAsyncScaling(0.4f);
|
||||
spawnedClap.PlayScaledAsync(0.4f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
11
Assets/Scripts/Games/MonkeyWatch/MonkeyClockArrow.cs.meta
Normal file
11
Assets/Scripts/Games/MonkeyWatch/MonkeyClockArrow.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb4fe7e944029da4b950e4ed4957b63b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
712
Assets/Scripts/Games/MonkeyWatch/MonkeyWatch.cs
Normal file
712
Assets/Scripts/Games/MonkeyWatch/MonkeyWatch.cs
Normal file
@ -0,0 +1,712 @@
|
||||
using HeavenStudio.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Jukebox;
|
||||
|
||||
namespace HeavenStudio.Games.Loaders
|
||||
{
|
||||
using static Minigames;
|
||||
public static class RvlMonkeyWatchLoader
|
||||
{
|
||||
public static Minigame AddGame(EventCaller eventCaller)
|
||||
{
|
||||
return new Minigame("monkeyWatch", "Monkey Watch", "f0338d", false, false, new List<GameAction>()
|
||||
{
|
||||
new GameAction("appear", "Monkeys Appear")
|
||||
{
|
||||
function = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.instance.MonkeysAppear(e.beat, e.length, e["value"], e.beat);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
resizable = true,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("value", new EntityTypes.Integer(1, 30, 4), "Repeat Amount")
|
||||
}
|
||||
},
|
||||
new GameAction("clap", "Clapping")
|
||||
{
|
||||
preFunction = delegate
|
||||
{
|
||||
MonkeyWatch.PreStartClapping(eventCaller.currentEntity.beat);
|
||||
},
|
||||
preFunctionLength = 4f,
|
||||
defaultLength = 2f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("min", new EntityTypes.Integer(0, 59, 0), "Set Starting Second", "A second is equivalent to one monkey.")
|
||||
}
|
||||
},
|
||||
new GameAction("off", "Pink Monkeys")
|
||||
{
|
||||
preFunction = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.PinkMonkeySound(e.beat, e.length, e["muteC"], e["muteE"]);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("muteC", false, "Mute Ooki"),
|
||||
new Param("muteE", false, "Mute Eeks")
|
||||
}
|
||||
},
|
||||
new GameAction("offStretch", "Pink Monkeys (Stretchable)")
|
||||
{
|
||||
preFunction = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.PinkMonkeySound(e.beat, e.length, e["muteC"], e["muteE"]);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
resizable = true,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("muteC", false, "Mute Ooki"),
|
||||
new Param("muteE", false, "Mute Eeks")
|
||||
}
|
||||
},
|
||||
new GameAction("offInterval", "Custom Pink Monkey Interval")
|
||||
{
|
||||
preFunction = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.PinkMonkeySoundCustom(e.beat, e.length, e["muteC"], e["muteE"]);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
resizable = true,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("muteC", false, "Mute Ooki"),
|
||||
new Param("muteE", false, "Mute Eeks")
|
||||
}
|
||||
},
|
||||
new GameAction("offCustom", "Custom Pink Monkey")
|
||||
{
|
||||
defaultLength = 0.5f
|
||||
},
|
||||
new GameAction("zoomOut", "Zoom Out")
|
||||
{
|
||||
function = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.instance.ZoomOut(e.beat, e["timeMode"], e["hour"], e["minute"], e["instant"]);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("instant", false, "Instant"),
|
||||
new Param("timeMode", MonkeyWatch.TimeMode.RealTime, "Time Mode", "Set the clock to system time or a certain time"),
|
||||
new Param("hour", new EntityTypes.Integer(0, 12, 3), "Hour"),
|
||||
new Param("minute", new EntityTypes.Integer(0, 59, 0), "Minute")
|
||||
}
|
||||
},
|
||||
new GameAction("zoomIn", "Zoom In")
|
||||
{
|
||||
function = delegate
|
||||
{
|
||||
var e = eventCaller.currentEntity;
|
||||
MonkeyWatch.instance.ZoomIn(e.beat, e["timeMode"], e["hour"], e["minute"], e["instant"]);
|
||||
},
|
||||
defaultLength = 2f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("instant", false, "Instant"),
|
||||
new Param("timeMode", MonkeyWatch.TimeMode.RealTime, "Time Mode", "Set the clock to system time or a certain time"),
|
||||
new Param("hour", new EntityTypes.Integer(0, 12, 3), "Hour"),
|
||||
new Param("minute", new EntityTypes.Integer(0, 59, 0), "Minute")
|
||||
}
|
||||
},
|
||||
new GameAction("balloon", "Balloon Movement")
|
||||
{
|
||||
resizable = true,
|
||||
defaultLength = 4f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("angleStart", new EntityTypes.Float(-360, 360, 0), "Start Angle"),
|
||||
new Param("angleEnd", new EntityTypes.Float(-360, 360, 0), "End Angle"),
|
||||
new Param("yStart", new EntityTypes.Float(-200, 200, 0), "Y Start"),
|
||||
new Param("yEnd", new EntityTypes.Float(-200, 200, 0), "Y End"),
|
||||
new Param("xStart", new EntityTypes.Float(-200, 200, 0), "X Start"),
|
||||
new Param("xEnd", new EntityTypes.Float(-200, 200, 0), "X End"),
|
||||
new Param("ease", Util.EasingFunction.Ease.Linear, "Ease")
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace HeavenStudio.Games
|
||||
{
|
||||
using Scripts_MonkeyWatch;
|
||||
|
||||
public class MonkeyWatch : Minigame
|
||||
{
|
||||
public enum TimeMode
|
||||
{
|
||||
RealTime,
|
||||
SetTime
|
||||
}
|
||||
|
||||
private const float degreePerMonkey = 6f;
|
||||
|
||||
public static MonkeyWatch instance;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField] private Transform cameraAnchor;
|
||||
[SerializeField] private Transform cameraTransform;
|
||||
[SerializeField] private Transform cameraMoveable;
|
||||
public MonkeyClockArrow monkeyClockArrow;
|
||||
[SerializeField] private WatchMonkeyHandler monkeyHandler;
|
||||
[SerializeField] private WatchBackgroundHandler backgroundHandler;
|
||||
[SerializeField] private BalloonHandler balloonHandler;
|
||||
public Animator middleMonkey;
|
||||
|
||||
[Header("Properties")]
|
||||
[SerializeField] private float fullZoomOut = 40f;
|
||||
[SerializeField] private Util.EasingFunction.Ease zoomOutEase;
|
||||
[SerializeField] private float zoomOutBeatLength = 2f;
|
||||
[SerializeField] private float zoomInBeatLength = 2f;
|
||||
[SerializeField] private Util.EasingFunction.Ease zoomInEase;
|
||||
private float lastAngle = 0f;
|
||||
private int cameraIndex = 0;
|
||||
private float cameraWantAngle, cameraAngleDelay;
|
||||
private float delayRate = 0.5f, targetDelayRate;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
funcOut = Util.EasingFunction.GetEasingFunction(zoomOutEase);
|
||||
funcIn = Util.EasingFunction.GetEasingFunction(zoomInEase);
|
||||
pinkMonkeys = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "off", "offStretch" });
|
||||
pinkMonkeysCustom = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "offInterval" });
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CameraUpdate();
|
||||
}
|
||||
|
||||
private double lastReportedBeat = 0;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CameraUpdate();
|
||||
}
|
||||
|
||||
public override void OnBeatPulse(double beat)
|
||||
{
|
||||
middleMonkey.DoScaledAnimationAsync("MiddleMonkeyBop", 0.4f);
|
||||
}
|
||||
|
||||
public void PlayerMonkeyClap(bool big, bool barely)
|
||||
{
|
||||
monkeyClockArrow.PlayerClap(big, barely, false);
|
||||
}
|
||||
|
||||
public void ZoomOut(double beat, int timeMode, int hours, int minutes, bool instant)
|
||||
{
|
||||
zoomOutStartBeat = beat - (instant ? zoomOutBeatLength : 0);
|
||||
zoomIn = false;
|
||||
backgroundHandler.SetFade(beat, instant ? 0 : 0.25f, true, (TimeMode)timeMode, hours, minutes);
|
||||
CameraUpdate();
|
||||
}
|
||||
public void ZoomIn(double beat, int timeMode, int hours, int minutes, bool instant)
|
||||
{
|
||||
zoomOutStartBeat = beat - (instant ? zoomInBeatLength : 0);
|
||||
zoomIn = true;
|
||||
backgroundHandler.SetFade(beat, instant ? 0 : 0.25f, false, (TimeMode)timeMode, hours, minutes);
|
||||
CameraUpdate();
|
||||
}
|
||||
|
||||
public void PersistZoomOut(double beat)
|
||||
{
|
||||
var allZooms = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "zoomOut" }).FindAll(x => x.beat < beat && x.beat + x.length > beat);
|
||||
foreach (var zoom in allZooms)
|
||||
{
|
||||
ZoomOut(zoom.beat, zoom["timeMode"], zoom["hour"], zoom["minute"], zoom["instant"]);
|
||||
}
|
||||
var allZoomsIn = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "zoomIn" }).FindAll(x => x.beat < beat && x.beat + x.length > beat);
|
||||
foreach (var zoom in allZoomsIn)
|
||||
{
|
||||
ZoomIn(zoom.beat, zoom["timeMode"], zoom["hour"], zoom["minute"], zoom["instant"]);
|
||||
}
|
||||
}
|
||||
|
||||
private double persistBeat = 0;
|
||||
private double theNextGameSwitchBeat = double.MaxValue;
|
||||
private double clappingBeat = 0;
|
||||
|
||||
public override void OnGameSwitch(double beat)
|
||||
{
|
||||
balloonHandler.Init(beat);
|
||||
persistBeat = beat;
|
||||
GetCameraMovements(beat, false);
|
||||
monkeyClockArrow.MoveToAngle(lastAngle);
|
||||
monkeyHandler.Init((int)(lastAngle / degreePerMonkey));
|
||||
if (wantClap >= beat && IsClapBeat(wantClap))
|
||||
{
|
||||
StartClapping(wantClap);
|
||||
}
|
||||
PersistAppear(beat);
|
||||
PersistZoomOut(beat);
|
||||
|
||||
bool IsClapBeat(double clapBeat)
|
||||
{
|
||||
return EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "clap" }).Find(x => x.beat == clapBeat) != null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPlay(double beat)
|
||||
{
|
||||
balloonHandler.Init(beat);
|
||||
persistBeat = beat;
|
||||
GetCameraMovements(beat, true);
|
||||
monkeyClockArrow.MoveToAngle(lastAngle);
|
||||
monkeyHandler.Init((int)(lastAngle / degreePerMonkey));
|
||||
PersistAppear(beat);
|
||||
PersistZoomOut(beat);
|
||||
}
|
||||
|
||||
private void PersistAppear(double beat)
|
||||
{
|
||||
var allEvents = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "appear" }).FindAll(x => x.beat + x["value"] > beat && x.beat < beat);
|
||||
|
||||
foreach (var e in allEvents)
|
||||
{
|
||||
MonkeysAppear(e.beat, e.length, e["value"], beat);
|
||||
}
|
||||
}
|
||||
|
||||
public void MonkeysAppear(double beat, float length, int repeatAmount, double gameSwitchBeat)
|
||||
{
|
||||
List<BeatAction.Action> actions = new();
|
||||
|
||||
double lastBeat = clappingBeat;
|
||||
|
||||
int index = 0;
|
||||
while (index < repeatAmount)
|
||||
{
|
||||
|
||||
if (IsPinkMonkeyAtBeat(lastBeat, out float pinkLength))
|
||||
{
|
||||
for (int i = 0; i < pinkLength; i++)
|
||||
{
|
||||
if (index >= repeatAmount) break;
|
||||
bool beforeGameSwitch = beat + (index * length) < gameSwitchBeat;
|
||||
double realLastBeat = lastBeat;
|
||||
actions.Add(new BeatAction.Action(beat + (index * length), delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(realLastBeat, true, beforeGameSwitch);
|
||||
}));
|
||||
index++;
|
||||
lastBeat += 1;
|
||||
}
|
||||
}
|
||||
else if (IsCustomPinkMonkeyAtBeat(lastBeat, out float pinkCustomLength))
|
||||
{
|
||||
var relevantPinks = FindCustomOffbeatMonkeysBetweenBeat(lastBeat, lastBeat + pinkCustomLength);
|
||||
relevantPinks.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
|
||||
for (int i = 0; i < relevantPinks.Count; i++)
|
||||
{
|
||||
if (index >= repeatAmount) break;
|
||||
int jindex = i;
|
||||
bool beforeGameSwitch = beat + (index * length) < gameSwitchBeat;
|
||||
actions.Add(new BeatAction.Action(beat + (index * length), delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(relevantPinks[jindex].beat, true, beforeGameSwitch);
|
||||
}));
|
||||
index++;
|
||||
}
|
||||
lastBeat += pinkCustomLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
double realLastBeat = lastBeat;
|
||||
bool beforeGameSwitch = beat + (index * length) < gameSwitchBeat;
|
||||
actions.Add(new BeatAction.Action(beat + (index * length), delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(realLastBeat, false, beforeGameSwitch);
|
||||
}));
|
||||
index++;
|
||||
lastBeat += 2;
|
||||
}
|
||||
}
|
||||
|
||||
actions.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
BeatAction.New(instance, actions);
|
||||
}
|
||||
|
||||
#region clapping
|
||||
|
||||
private bool clapRecursing = false;
|
||||
private List<RiqEntity> pinkMonkeys = new();
|
||||
private List<RiqEntity> pinkMonkeysCustom = new();
|
||||
|
||||
private bool IsPinkMonkeyAtBeat(double beat, out float length)
|
||||
{
|
||||
length = 2;
|
||||
var e = pinkMonkeys.Find(x => x.beat == beat);
|
||||
bool isNotNull = e != null;
|
||||
if (isNotNull) length = e.length;
|
||||
return isNotNull;
|
||||
}
|
||||
|
||||
private bool IsCustomPinkMonkeyAtBeat(double beat, out float length)
|
||||
{
|
||||
length = 2;
|
||||
var e = pinkMonkeysCustom.Find(x => x.beat == beat);
|
||||
bool isNotNull = e != null;
|
||||
if (isNotNull) length = e.length;
|
||||
return isNotNull;
|
||||
}
|
||||
|
||||
private static double wantClap = double.MinValue;
|
||||
|
||||
public static void PreStartClapping(double beat)
|
||||
{
|
||||
if (GameManager.instance.currentGame == "monkeyWatch")
|
||||
{
|
||||
instance.StartClapping(beat);
|
||||
}
|
||||
wantClap = beat;
|
||||
}
|
||||
|
||||
private void StartClapping(double beat)
|
||||
{
|
||||
if (clapRecursing) return;
|
||||
clapRecursing = true;
|
||||
|
||||
ClapRecursing(beat);
|
||||
}
|
||||
|
||||
private void ClapRecursing(double beat)
|
||||
{
|
||||
if (beat >= theNextGameSwitchBeat) return;
|
||||
if (IsPinkMonkeyAtBeat(beat, out float length1))
|
||||
{
|
||||
PinkClap(length1);
|
||||
}
|
||||
else if (IsCustomPinkMonkeyAtBeat(beat, out float length2))
|
||||
{
|
||||
PinkClapCustom(length2);
|
||||
}
|
||||
else
|
||||
{
|
||||
NormalClap();
|
||||
}
|
||||
|
||||
void NormalClap()
|
||||
{
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat - 4, delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(beat, false, beat - 4 < persistBeat);
|
||||
ClapRecursing(beat + 2);
|
||||
cameraWantAngle += degreePerMonkey;
|
||||
}),
|
||||
new BeatAction.Action(beat - 1, delegate
|
||||
{
|
||||
monkeyHandler.GetMonkeyAtBeat(beat).Prepare(beat, beat + 1);
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
void PinkClap(float length)
|
||||
{
|
||||
List<BeatAction.Action> actions = new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat - 4, delegate
|
||||
{
|
||||
ClapRecursing(beat + length);
|
||||
})
|
||||
};
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
int index = i;
|
||||
actions.AddRange(new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat + i - 4, delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(beat + index, true, beat + index - 4 < persistBeat);
|
||||
cameraWantAngle += degreePerMonkey;
|
||||
}),
|
||||
new BeatAction.Action(beat + i - 1, delegate
|
||||
{
|
||||
monkeyHandler.GetMonkeyAtBeat(beat + index).Prepare(beat + index, beat + index + 0.5);
|
||||
}),
|
||||
});
|
||||
}
|
||||
actions.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
BeatAction.New(instance, actions);
|
||||
}
|
||||
|
||||
void PinkClapCustom(float length)
|
||||
{
|
||||
List<BeatAction.Action> actions = new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat - 4, delegate
|
||||
{
|
||||
ClapRecursing(beat + length);
|
||||
})
|
||||
};
|
||||
|
||||
var relevantEvents = FindCustomOffbeatMonkeysBetweenBeat(beat, beat + length);
|
||||
relevantEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
|
||||
for (int i = 0; i < relevantEvents.Count; i++)
|
||||
{
|
||||
var e = relevantEvents[i];
|
||||
actions.AddRange(new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(e.beat - 4, delegate
|
||||
{
|
||||
monkeyHandler.SpawnMonkey(e.beat, true, e.beat - 4 < persistBeat);
|
||||
cameraWantAngle += degreePerMonkey;
|
||||
}),
|
||||
new BeatAction.Action(e.beat - 1.5, delegate
|
||||
{
|
||||
monkeyHandler.GetMonkeyAtBeat(e.beat).Prepare(e.beat - 0.5, e.beat);
|
||||
}),
|
||||
});
|
||||
}
|
||||
actions.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
BeatAction.New(instance, actions);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Camera
|
||||
private void GetCameraMovements(double beat, bool onPlay)
|
||||
{
|
||||
double lastGameSwitchBeat = beat;
|
||||
if (onPlay)
|
||||
{
|
||||
var allEndsBeforeBeat = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame" }).FindAll(x => x.beat <= beat);
|
||||
if (allEndsBeforeBeat.Count > 0)
|
||||
{
|
||||
allEndsBeforeBeat.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
lastGameSwitchBeat = allEndsBeforeBeat[^1].beat;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastGameSwitchBeat = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
double nextGameSwitchBeat = double.MaxValue;
|
||||
|
||||
var allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame", "end" }).FindAll(x => x.beat > lastGameSwitchBeat);
|
||||
if (allEnds.Count > 0)
|
||||
{
|
||||
allEnds.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
nextGameSwitchBeat = allEnds[0].beat;
|
||||
}
|
||||
|
||||
theNextGameSwitchBeat = nextGameSwitchBeat;
|
||||
|
||||
double startClappingBeat = 0;
|
||||
float startAngle = 0;
|
||||
bool overrideStartBeat = true;
|
||||
|
||||
var clappingEvents = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "clap" }).FindAll(x => x.beat >= lastGameSwitchBeat && x.beat < nextGameSwitchBeat);
|
||||
if (clappingEvents.Count > 0)
|
||||
{
|
||||
clappingEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
startClappingBeat = clappingEvents[0].beat;
|
||||
startAngle = clappingEvents[0]["min"] * degreePerMonkey;
|
||||
cameraWantAngle = startAngle;
|
||||
cameraAngleDelay = startAngle;
|
||||
overrideStartBeat = false;
|
||||
}
|
||||
lastAngle = startAngle;
|
||||
clappingBeat = startClappingBeat;
|
||||
|
||||
var pinkClappingEvents = EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "off", "offStretch", "offInterval" }).FindAll(x => x.beat >= lastGameSwitchBeat && x.beat < nextGameSwitchBeat);
|
||||
if (pinkClappingEvents.Count > 0)
|
||||
{
|
||||
pinkClappingEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
if (overrideStartBeat) startClappingBeat = pinkClappingEvents[0].beat;
|
||||
clappingBeat = startClappingBeat;
|
||||
|
||||
var relevantPinkClappingEvents = pinkClappingEvents.FindAll(x => (x.beat - startClappingBeat) % 2 == 0);
|
||||
relevantPinkClappingEvents.Sort((x, y) => x.beat.CompareTo(y.beat));
|
||||
|
||||
double lastClappingBeat = startClappingBeat;
|
||||
float lastAngleToCheck = startAngle;
|
||||
|
||||
for (int i = 0; i < relevantPinkClappingEvents.Count; i++)
|
||||
{
|
||||
var e = relevantPinkClappingEvents[i];
|
||||
if (e.beat < lastClappingBeat) continue;
|
||||
|
||||
float angleToAdd;
|
||||
if (e.datamodel == "monkeyWatch/offInterval")
|
||||
{
|
||||
angleToAdd = FindCustomOffbeatMonkeysBetweenBeat(e.beat, e.beat + e.length).Count * degreePerMonkey;
|
||||
}
|
||||
else
|
||||
{
|
||||
angleToAdd = Mathf.Ceil(e.length) * degreePerMonkey;
|
||||
}
|
||||
|
||||
if (e.beat - lastClappingBeat > 0)
|
||||
{
|
||||
lastAngleToCheck += (float)((e.beat - lastClappingBeat) / 2) * degreePerMonkey;
|
||||
}
|
||||
|
||||
lastAngleToCheck += angleToAdd;
|
||||
lastClappingBeat = e.beat + e.length;
|
||||
}
|
||||
startClappingBeat = lastClappingBeat;
|
||||
startAngle = lastAngleToCheck;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCamera()
|
||||
{
|
||||
// lastAngle = cameraMovements[cameraIndex].degreeTo;
|
||||
// cameraIndex++;
|
||||
// if (cameraIndex + 1 < cameraMovements.Count && conductor.songPositionInBeats >= cameraMovements[cameraIndex].beat + cameraMovements[cameraIndex].length)
|
||||
// {
|
||||
// UpdateCamera();
|
||||
// }
|
||||
}
|
||||
|
||||
private double zoomOutStartBeat = -2;
|
||||
private bool zoomIn = true;
|
||||
private Util.EasingFunction.Function funcOut;
|
||||
private Util.EasingFunction.Function funcIn;
|
||||
|
||||
private void CameraUpdate()
|
||||
{
|
||||
if (conductor.isPlaying && !conductor.isPaused)
|
||||
{
|
||||
float degreesBehind = cameraWantAngle - 2 * degreePerMonkey;
|
||||
float degreesBehindFast = cameraWantAngle - 3f * degreePerMonkey;
|
||||
targetDelayRate = Mathf.Max((cameraAngleDelay - degreesBehindFast) / (degreesBehindFast - cameraWantAngle), 0) + 0.5f;
|
||||
delayRate = Mathf.Lerp(delayRate, targetDelayRate, Time.deltaTime * (1f / conductor.pitchedSecPerBeat) * 0.5f);
|
||||
if (cameraAngleDelay < degreesBehind)
|
||||
{
|
||||
cameraAngleDelay += degreePerMonkey * Time.deltaTime * (1f / conductor.pitchedSecPerBeat) * delayRate;
|
||||
cameraAngleDelay = Mathf.Min(cameraAngleDelay, cameraWantAngle);
|
||||
}
|
||||
cameraAnchor.localEulerAngles = new Vector3(0, 0, cameraAngleDelay);
|
||||
}
|
||||
|
||||
float normalizedZoomBeat = conductor.GetPositionFromBeat(zoomOutStartBeat, zoomIn ? zoomInBeatLength : zoomOutBeatLength);
|
||||
float newX = 0f;
|
||||
float newY = 0f;
|
||||
float newZ = 0f;
|
||||
if (zoomIn)
|
||||
{
|
||||
newX = funcIn(0, cameraTransform.position.x, Mathf.Clamp01(normalizedZoomBeat));
|
||||
newY = funcIn(0, cameraTransform.position.y, Mathf.Clamp01(normalizedZoomBeat));
|
||||
newZ = funcIn(fullZoomOut, 0, Mathf.Clamp01(normalizedZoomBeat));
|
||||
}
|
||||
else
|
||||
{
|
||||
newX = funcOut(cameraTransform.position.x, 0, Mathf.Clamp01(normalizedZoomBeat));
|
||||
newY = funcOut(cameraTransform.position.y, 0, Mathf.Clamp01(normalizedZoomBeat));
|
||||
newZ = funcOut(0, fullZoomOut, Mathf.Clamp01(normalizedZoomBeat));
|
||||
}
|
||||
|
||||
if (zoomIn && normalizedZoomBeat > 1f)
|
||||
{
|
||||
cameraMoveable.position = new Vector3(cameraTransform.position.x, cameraTransform.position.y * -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraMoveable.position = new Vector3(newX, -newY, newZ);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static List<RiqEntity> FindCustomOffbeatMonkeysBetweenBeat(double beat, double endBeat)
|
||||
{
|
||||
return EventCaller.GetAllInGameManagerList("monkeyWatch", new string[] { "offCustom" }).FindAll(x => x.beat >= beat && x.beat < endBeat);
|
||||
}
|
||||
|
||||
#region pink monkey sounds
|
||||
|
||||
public static void PinkMonkeySound(double beat, float length, bool muteOoki, bool muteEek)
|
||||
{
|
||||
List<MultiSound.Sound> soundsToPlay = new();
|
||||
if (!muteOoki)
|
||||
{
|
||||
soundsToPlay.AddRange(new List<MultiSound.Sound>()
|
||||
{
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki1", beat - 2),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki1Echo1", beat - 1.75),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki2", beat - 1),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki2Echo1", beat - 0.75),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki3", beat),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki3Echo1", beat + 0.25),
|
||||
});
|
||||
}
|
||||
|
||||
if (!muteEek)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
int randomKi = UnityEngine.Random.Range(1, 3);
|
||||
soundsToPlay.AddRange(new List<MultiSound.Sound>()
|
||||
{
|
||||
new MultiSound.Sound($"monkeyWatch/voiceKi{randomKi}", beat + i + 0.5),
|
||||
new MultiSound.Sound($"monkeyWatch/voiceKi{randomKi}Echo{UnityEngine.Random.Range(1, 3)}", beat + i + 0.75),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (soundsToPlay.Count > 0) MultiSound.Play(soundsToPlay.ToArray(), forcePlay: true);
|
||||
}
|
||||
|
||||
public static void PinkMonkeySoundCustom(double beat, float length, bool muteOoki, bool muteEek)
|
||||
{
|
||||
List<MultiSound.Sound> soundsToPlay = new();
|
||||
var allCustoms = FindCustomOffbeatMonkeysBetweenBeat(beat, beat + length);
|
||||
if (!muteOoki)
|
||||
{
|
||||
soundsToPlay.AddRange(new List<MultiSound.Sound>()
|
||||
{
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki1", beat - 2),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki1Echo1", beat - 1.75),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki2", beat - 1),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki2Echo1", beat - 0.75),
|
||||
});
|
||||
if (allCustoms.Find(x => x.beat == beat) == null)
|
||||
{
|
||||
soundsToPlay.AddRange(new List<MultiSound.Sound>()
|
||||
{
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki3", beat),
|
||||
new MultiSound.Sound("monkeyWatch/voiceUki3Echo1", beat + 0.25),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!muteEek)
|
||||
{
|
||||
foreach (var custom in allCustoms)
|
||||
{
|
||||
int randomKi = UnityEngine.Random.Range(1, 3);
|
||||
soundsToPlay.AddRange(new List<MultiSound.Sound>()
|
||||
{
|
||||
new MultiSound.Sound($"monkeyWatch/voiceKi{randomKi}", custom.beat),
|
||||
new MultiSound.Sound($"monkeyWatch/voiceKi{randomKi}Echo{UnityEngine.Random.Range(1, 3)}", custom.beat + 0.25),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (soundsToPlay.Count > 0) MultiSound.Play(soundsToPlay.ToArray(), forcePlay: true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
11
Assets/Scripts/Games/MonkeyWatch/MonkeyWatch.cs.meta
Normal file
11
Assets/Scripts/Games/MonkeyWatch/MonkeyWatch.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99a29cf6197a42148a8863b67958be70
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
89
Assets/Scripts/Games/MonkeyWatch/WatchBackgroundHandler.cs
Normal file
89
Assets/Scripts/Games/MonkeyWatch/WatchBackgroundHandler.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using HeavenStudio.Util;
|
||||
using Starpelly;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MonkeyWatch
|
||||
{
|
||||
public class WatchBackgroundHandler : MonoBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private SpriteRenderer[] srsIn;
|
||||
[SerializeField] private SpriteRenderer[] srsOut;
|
||||
[SerializeField] private Transform anchorHour;
|
||||
[SerializeField] private Transform anchorMinute;
|
||||
|
||||
private double fadeBeat = -1;
|
||||
private float fadeLength = 0f;
|
||||
private bool fadeOut = false;
|
||||
private bool realTime = true;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var cond = Conductor.instance;
|
||||
|
||||
float normalizedBeat = Mathf.Clamp01(cond.GetPositionFromBeat(fadeBeat, fadeLength));
|
||||
|
||||
if (fadeOut)
|
||||
{
|
||||
foreach (var s in srsIn)
|
||||
{
|
||||
s.color = new Color(s.color.r, s.color.g, s.color.b, 1 - normalizedBeat);
|
||||
}
|
||||
|
||||
foreach (var s in srsOut)
|
||||
{
|
||||
s.color = new Color(s.color.r, s.color.g, s.color.b, normalizedBeat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var s in srsIn)
|
||||
{
|
||||
s.color = new Color(s.color.r, s.color.g, s.color.b, normalizedBeat);
|
||||
}
|
||||
|
||||
foreach (var s in srsOut)
|
||||
{
|
||||
s.color = new Color(s.color.r, s.color.g, s.color.b, 1 - normalizedBeat);
|
||||
}
|
||||
}
|
||||
|
||||
if (realTime)
|
||||
{
|
||||
var nowTime = System.DateTime.Now;
|
||||
|
||||
SetArrowsToTime(nowTime.Hour, nowTime.Minute, nowTime.Second);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFade(double beat, float length, bool outFade, MonkeyWatch.TimeMode timeMode, int hours, int minutes)
|
||||
{
|
||||
fadeBeat = beat;
|
||||
fadeLength = length;
|
||||
fadeOut = outFade;
|
||||
realTime = timeMode == MonkeyWatch.TimeMode.RealTime;
|
||||
if (!realTime)
|
||||
{
|
||||
SetArrowsToTime(hours, minutes, 0);
|
||||
}
|
||||
Update();
|
||||
}
|
||||
|
||||
private void SetArrowsToTime(int hours, int minutes, int seconds)
|
||||
{
|
||||
float normalizedHour = Mathp.Normalize(hours + (minutes / 60f) + (seconds / 3600f), 0f, 12f);
|
||||
anchorHour.localEulerAngles = new Vector3(0, 0, -Mathf.LerpUnclamped(0, 360, normalizedHour));
|
||||
|
||||
float normalizedMinute = Mathp.Normalize(minutes + (seconds / 60f), 0, 60);
|
||||
anchorMinute.localEulerAngles = new Vector3(0, 0, -Mathf.LerpUnclamped(0, 360, normalizedMinute));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c89276e2caf959949a2a775c9f228443
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
113
Assets/Scripts/Games/MonkeyWatch/WatchMonkey.cs
Normal file
113
Assets/Scripts/Games/MonkeyWatch/WatchMonkey.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using HeavenStudio.Util;
|
||||
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MonkeyWatch
|
||||
{
|
||||
public class WatchMonkey : MonoBehaviour
|
||||
{
|
||||
private Animator anim;
|
||||
private Animator holeAnim;
|
||||
[Header("Properties")]
|
||||
[SerializeField] private bool isPink;
|
||||
|
||||
private MonkeyWatch game;
|
||||
|
||||
private int direction = 0;
|
||||
public double monkeyBeat;
|
||||
|
||||
private double disappearBeat = 0;
|
||||
private bool disappear = false;
|
||||
|
||||
private PlayerActionEvent inputEvent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
game = MonkeyWatch.instance;
|
||||
anim = GetComponent<Animator>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (disappear)
|
||||
{
|
||||
float normalizedBeat = Conductor.instance.GetPositionFromBeat(disappearBeat, 0.5f);
|
||||
anim.DoNormalizedAnimation(isPink ? "PinkAppear" : "Appear", 1 - normalizedBeat);
|
||||
float normalizedBeatClose = Conductor.instance.GetPositionFromBeat(disappearBeat + 0.25f, 0.25f);
|
||||
holeAnim.DoNormalizedAnimation("HoleClose", Mathf.Clamp01(normalizedBeatClose));
|
||||
if (normalizedBeat > 1f)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Appear(double beat, bool instant, Animator hole, int dir)
|
||||
{
|
||||
monkeyBeat = beat;
|
||||
direction = dir;
|
||||
holeAnim = hole;
|
||||
holeAnim.DoScaledAnimationAsync("HoleOpen", 0.4f, instant ? 1 : 0);
|
||||
anim.DoScaledAnimationAsync(isPink ? "PinkAppear" : "Appear", 0.4f, instant ? 1 : 0);
|
||||
}
|
||||
|
||||
public void Disappear(double beat)
|
||||
{
|
||||
disappear = true;
|
||||
disappearBeat = beat;
|
||||
Update();
|
||||
}
|
||||
|
||||
public void Prepare(double prepareBeat, double inputBeat)
|
||||
{
|
||||
anim.DoScaledAnimationAsync(isPink ? "PinkPrepare" + direction : "Prepare" + direction, 0);
|
||||
inputEvent = game.ScheduleInput(prepareBeat, inputBeat - prepareBeat, MonkeyWatch.InputAction_BasicPress, Just, Miss, Empty);
|
||||
BeatAction.New(this, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(prepareBeat - 0.25, delegate
|
||||
{
|
||||
if (inputEvent != null && inputEvent.enabled) anim.DoScaledAnimationAsync(isPink ? "PinkPrepare" + direction : "Prepare" + direction, 0.4f);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
private void Just(PlayerActionEvent caller, float state)
|
||||
{
|
||||
bool barely = state >= 1f || state <= -1f;
|
||||
if (barely)
|
||||
{
|
||||
SoundByte.PlayOneShot("nearMiss");
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundByte.PlayOneShotGame(isPink ? "monkeyWatch/clapOffbeat" : $"monkeyWatch/clapOnbeat{UnityEngine.Random.Range(1, 6)}");
|
||||
}
|
||||
game.monkeyClockArrow.Move();
|
||||
game.PlayerMonkeyClap(isPink, barely);
|
||||
|
||||
anim.DoScaledAnimationAsync(isPink ? "PinkClap" + direction : "Clap" + direction, 0.4f);
|
||||
BeatAction.New(this, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(caller.timer + caller.startBeat + 1, delegate
|
||||
{
|
||||
string whichAnim = barely ? "Barely" : "Just";
|
||||
anim.DoScaledAnimationAsync(isPink ? "Pink" + whichAnim : whichAnim, 0.4f);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
private void Miss(PlayerActionEvent caller)
|
||||
{
|
||||
anim.DoScaledAnimationAsync(isPink ? "PinkMiss" : "Miss", 0.4f);
|
||||
game.monkeyClockArrow.Move();
|
||||
}
|
||||
|
||||
private void Empty(PlayerActionEvent caller)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Games/MonkeyWatch/WatchMonkey.cs.meta
Normal file
11
Assets/Scripts/Games/MonkeyWatch/WatchMonkey.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23217e6c428ce954e8fd08940b856233
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
90
Assets/Scripts/Games/MonkeyWatch/WatchMonkeyHandler.cs
Normal file
90
Assets/Scripts/Games/MonkeyWatch/WatchMonkeyHandler.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using HeavenStudio.Util;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace HeavenStudio.Games.Scripts_MonkeyWatch
|
||||
{
|
||||
public class WatchMonkeyHandler : MonoBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
[SerializeField] private WatchMonkey yellowMonkeyRef;
|
||||
[SerializeField] private WatchMonkey pinkMonkeyRef;
|
||||
|
||||
[Header("Properties")]
|
||||
[SerializeField] private int maxMonkeys = 30;
|
||||
|
||||
private MonkeyWatch game;
|
||||
|
||||
private int startMinute = 0;
|
||||
private int watchHoleIndex = 0;
|
||||
private List<Transform> watchHoles = new();
|
||||
private List<WatchMonkey> currentMonkeys = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
game = MonkeyWatch.instance;
|
||||
for (int i = 0; i < 60; i++)
|
||||
{
|
||||
watchHoles.Add(transform.GetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(int minute)
|
||||
{
|
||||
startMinute = minute;
|
||||
watchHoleIndex = startMinute;
|
||||
}
|
||||
private Transform GetNextAvailableWatchHole()
|
||||
{
|
||||
int currentIndex = watchHoleIndex;
|
||||
watchHoleIndex++;
|
||||
if (watchHoleIndex >= watchHoles.Count)
|
||||
{
|
||||
watchHoleIndex = 0;
|
||||
}
|
||||
return watchHoles[currentIndex];
|
||||
}
|
||||
|
||||
public void SpawnMonkey(double beat, bool isPink, bool instant)
|
||||
{
|
||||
if (GetMonkeyAtBeat(beat) != null) return;
|
||||
int index = watchHoleIndex;
|
||||
var hole = GetNextAvailableWatchHole();
|
||||
WatchMonkey spawnedMonkey = Instantiate(isPink ? pinkMonkeyRef : yellowMonkeyRef, hole);
|
||||
spawnedMonkey.Appear(beat, instant, hole.GetComponent<Animator>(), GetMonkeyAngle(index));
|
||||
spawnedMonkey.transform.eulerAngles = Vector3.zero;
|
||||
var sortingGroup = spawnedMonkey.GetComponent<SortingGroup>();
|
||||
if (index <= 30) sortingGroup.sortingOrder = 50 + watchHoleIndex;
|
||||
else sortingGroup.sortingOrder = 50 + watchHoleIndex - (watchHoleIndex - 29);
|
||||
currentMonkeys.Add(spawnedMonkey);
|
||||
if (currentMonkeys.Count > maxMonkeys)
|
||||
{
|
||||
currentMonkeys[0].Disappear(Conductor.instance.songPositionInBeats);
|
||||
currentMonkeys.Remove(currentMonkeys[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public WatchMonkey GetMonkeyAtBeat(double beat)
|
||||
{
|
||||
return currentMonkeys.Find(x => x.monkeyBeat == beat);
|
||||
}
|
||||
|
||||
private int GetMonkeyAngle(int monkey)
|
||||
{
|
||||
return monkey switch
|
||||
{
|
||||
>= 4 and <= 12 => 2,
|
||||
>= 12 and <= 19 => 3,
|
||||
>= 19 and <= 27 => 4,
|
||||
>= 27 and <= 34 => 5,
|
||||
>= 34 and <= 42 => 6,
|
||||
>= 42 and <= 49 => 7,
|
||||
>= 49 and <= 56 => 8,
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Assets/Scripts/Games/MonkeyWatch/WatchMonkeyHandler.cs.meta
Normal file
11
Assets/Scripts/Games/MonkeyWatch/WatchMonkeyHandler.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0769f835f6039b41b98b9487eb743d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -169,6 +169,7 @@ namespace HeavenStudio.Games.Scripts_SeeSaw
|
||||
break;
|
||||
}
|
||||
float newCamY = 0f;
|
||||
|
||||
if (!see && game.cameraMove)
|
||||
{
|
||||
switch (currentState)
|
||||
|
Reference in New Issue
Block a user