mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 08:17:38 +02:00
Tweezers: Functioning gameplay loop + Editor implementation.
This commit is contained in:
@ -7,16 +7,18 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||
public class Hair : PlayerActionObject
|
||||
{
|
||||
public float createBeat;
|
||||
private RhythmTweezers game;
|
||||
private Tweezers tweezers;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
tweezers = RhythmTweezers.instance.Tweezers;
|
||||
game = RhythmTweezers.instance;
|
||||
tweezers = game.Tweezers;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float stateBeat = Conductor.instance.GetPositionFromBeat(createBeat, 4f);
|
||||
float stateBeat = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset, game.beatInterval);
|
||||
StateCheck(stateBeat);
|
||||
|
||||
if (PlayerInput.Pressed() && tweezers.hitOnFrame == 0)
|
||||
|
@ -1,6 +1,9 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using Starpelly;
|
||||
using DG.Tweening;
|
||||
|
||||
using RhythmHeavenMania.Util;
|
||||
|
||||
@ -9,16 +12,22 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||
// use PlayerActionObject for the actual tweezers but this isn't playable rn so IDC
|
||||
public class RhythmTweezers : Minigame
|
||||
{
|
||||
public Transform VegetableHolder;
|
||||
public GameObject Vegetable;
|
||||
public Animator VegetableAnimator;
|
||||
public Tweezers Tweezers;
|
||||
public GameObject hairBase;
|
||||
|
||||
[SerializeField] private GameObject HairsHolder;
|
||||
[NonSerialized] public int hairsLeft = 0;
|
||||
|
||||
public float tweezersBeatOffset;
|
||||
public Vector2 tweezersRotOffset;
|
||||
public float rotSpd;
|
||||
public float offset;
|
||||
public float beatInterval = 4f;
|
||||
float intervalStartBeat;
|
||||
bool intervalStarted;
|
||||
public float tweezerBeatOffset = 0f;
|
||||
|
||||
Tween transitionTween;
|
||||
bool transitioning = false;
|
||||
|
||||
public static RhythmTweezers instance { get; set; }
|
||||
|
||||
@ -27,39 +36,108 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
public void SpawnHair(float beat)
|
||||
{
|
||||
float beat = 0;
|
||||
float offset = 0f;
|
||||
BeatAction.New(HairsHolder, new List<BeatAction.Action>()
|
||||
// End transition early if the next hair is a lil early.
|
||||
StopTransitionIfActive();
|
||||
|
||||
// If interval hasn't started, assume this is the first hair of the interval.
|
||||
if (!intervalStarted)
|
||||
{
|
||||
new BeatAction.Action(beat + offset, delegate { SpawnHair(beat + offset); }),
|
||||
new BeatAction.Action(beat + 1f + offset, delegate { SpawnHair(beat + 1f + offset); }),
|
||||
new BeatAction.Action(beat + 2f + offset, delegate
|
||||
{
|
||||
SpawnHair(beat + 2f + offset);
|
||||
}),
|
||||
new BeatAction.Action(beat + 3f + offset, delegate { SpawnHair(beat + 3f + offset); }),
|
||||
});
|
||||
SetIntervalStart(beat, beatInterval);
|
||||
}
|
||||
|
||||
Jukebox.PlayOneShotGame("rhythmTweezers/shortAppear", beat);
|
||||
Hair hair = Instantiate(hairBase, HairsHolder.transform).GetComponent<Hair>();
|
||||
hair.gameObject.SetActive(true);
|
||||
|
||||
float rot = -58f + 116 * Mathp.Normalize(beat, intervalStartBeat, intervalStartBeat + beatInterval - 1f);
|
||||
hair.transform.eulerAngles = new Vector3(0, 0, rot);
|
||||
hair.createBeat = beat;
|
||||
hairsLeft++;
|
||||
}
|
||||
|
||||
private void SpawnHair(float beat)
|
||||
public void SetIntervalStart(float beat, float interval = 4f)
|
||||
{
|
||||
Jukebox.PlayOneShotGame("rhythmTweezers/shortAppear", beat);
|
||||
GameObject hair = Instantiate(HairsHolder.transform.GetChild(0).gameObject, HairsHolder.transform);
|
||||
hair.SetActive(true);
|
||||
// End transition early if the interval starts a lil early.
|
||||
StopTransitionIfActive();
|
||||
|
||||
float rot = ((offset / 3f) * (beat * 2f)) - offset;
|
||||
intervalStartBeat = beat;
|
||||
beatInterval = interval;
|
||||
intervalStarted = true;
|
||||
hairsLeft = 0;
|
||||
}
|
||||
|
||||
hair.transform.eulerAngles = new Vector3(0, 0, rot);
|
||||
hair.GetComponent<Hair>().createBeat = beat;
|
||||
const float vegDupeOffset = 16.7f;
|
||||
public void NextVegetable(float beat)
|
||||
{
|
||||
transitioning = true;
|
||||
|
||||
Jukebox.PlayOneShotGame("rhythmTweezers/register", beat);
|
||||
|
||||
// Move both vegetables to the left by vegDupeOffset, then reset their positions.
|
||||
// On position reset, reset state of core vegetable.
|
||||
transitionTween = VegetableHolder.DOLocalMoveX(-vegDupeOffset, Conductor.instance.secPerBeat * 0.5f)
|
||||
.OnComplete(() => {
|
||||
|
||||
var holderPos = VegetableHolder.localPosition;
|
||||
VegetableHolder.localPosition = new Vector3(0f, holderPos.y, holderPos.z);
|
||||
|
||||
ResetVegetable();
|
||||
transitioning = false;
|
||||
intervalStarted = false;
|
||||
|
||||
}).SetEase(Ease.InOutSine);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float normalizedBeat = Conductor.instance.GetLoopPositionFromBeat(tweezersBeatOffset, rotSpd);
|
||||
float rot = Mathf.Lerp(tweezersRotOffset.x, tweezersRotOffset.y, normalizedBeat);
|
||||
Tweezers.transform.eulerAngles = new Vector3(0, 0, rot);
|
||||
if (!Conductor.instance.isPlaying && !Conductor.instance.isPaused && intervalStarted)
|
||||
{
|
||||
StopTransitionIfActive();
|
||||
ResetVegetable();
|
||||
intervalStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
// Set tweezer angle.
|
||||
var tweezerAngle = -180f;
|
||||
|
||||
if (intervalStarted)
|
||||
{
|
||||
var tweezerTime = Conductor.instance.songPositionInBeats - beatInterval - tweezerBeatOffset;
|
||||
var unclampedAngle = -58f + 116 * Mathp.Normalize(tweezerTime, intervalStartBeat, intervalStartBeat + beatInterval - 1f);
|
||||
tweezerAngle = Mathf.Clamp(unclampedAngle, -180f, 180f);
|
||||
}
|
||||
|
||||
Tweezers.transform.eulerAngles = new Vector3(0, 0, tweezerAngle);
|
||||
|
||||
// Set tweezer to follow vegetable.
|
||||
var currentTweezerPos = Tweezers.transform.localPosition;
|
||||
Tweezers.transform.localPosition = new Vector3(currentTweezerPos.x, Vegetable.transform.localPosition.y + 1f, currentTweezerPos.z);
|
||||
}
|
||||
|
||||
private void ResetVegetable()
|
||||
{
|
||||
foreach (Transform t in HairsHolder.transform)
|
||||
{
|
||||
var go = t.gameObject;
|
||||
if (go != hairBase)
|
||||
GameObject.Destroy(go);
|
||||
}
|
||||
|
||||
VegetableAnimator.Play("Idle", 0, 0);
|
||||
}
|
||||
|
||||
private void StopTransitionIfActive()
|
||||
{
|
||||
if (transitioning)
|
||||
{
|
||||
if (transitionTween != null)
|
||||
transitionTween.Kill(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,17 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||
|
||||
if (ace)
|
||||
{
|
||||
RhythmTweezers.instance.Vegetable.GetComponent<Animator>().Play("Hop", 0, 0);
|
||||
var game = RhythmTweezers.instance;
|
||||
|
||||
Jukebox.PlayOneShotGame($"rhythmTweezers/shortPluck{Random.Range(1, 21)}");
|
||||
Destroy(hair.gameObject);
|
||||
|
||||
game.hairsLeft--;
|
||||
|
||||
if (game.hairsLeft <= 0)
|
||||
vegetableAnim.Play("HopFinal", 0, 0);
|
||||
else
|
||||
vegetableAnim.Play("Hop", 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using RhythmHeavenMania.Games.Spaceball;
|
||||
using RhythmHeavenMania.Games.KarateMan;
|
||||
using RhythmHeavenMania.Games.SpaceSoccer;
|
||||
using RhythmHeavenMania.Games.DJSchool;
|
||||
using RhythmHeavenMania.Games.RhythmTweezers;
|
||||
|
||||
namespace RhythmHeavenMania
|
||||
{
|
||||
@ -187,9 +188,15 @@ namespace RhythmHeavenMania
|
||||
new GameAction("break c'mon ooh", delegate { DJSchool.instance.BreakCmon(eventCaller.currentEntity.beat); }, 3f),
|
||||
new GameAction("scratch-o hey", delegate { DJSchool.instance.ScratchoHey(eventCaller.currentEntity.beat); }, 3f),
|
||||
}),
|
||||
/*new Minigame("rhythmTweezers", "VeggieTales", "008c97", false, false, new List<GameAction>()
|
||||
new Minigame("rhythmTweezers", "Rhythm Tweezers \n<color=#eb5454>[WIP don't use]</color>", "98b389", false, false, new List<GameAction>()
|
||||
{
|
||||
new GameAction("start interval", delegate { RhythmTweezers.instance.SetIntervalStart(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 4f, true),
|
||||
new GameAction("short hair", delegate { RhythmTweezers.instance.SpawnHair(eventCaller.currentEntity.beat); }, 0.5f),
|
||||
new GameAction("next vegetable", delegate { RhythmTweezers.instance.NextVegetable(eventCaller.currentEntity.beat); }, 0.5f),
|
||||
new GameAction("set tweezer delay", delegate { RhythmTweezers.instance.tweezerBeatOffset = eventCaller.currentEntity.length; }, 1f, true),
|
||||
new GameAction("reset tweezer delay", delegate { RhythmTweezers.instance.tweezerBeatOffset = 0f; }, 0.5f),
|
||||
}),
|
||||
/*
|
||||
new Minigame("rhythmRally", "Rhythm Rally", "B888F8", true, false, new List<GameAction>()
|
||||
{
|
||||
|
||||
|
Reference in New Issue
Block a user