mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-22 17:45:16 +00:00
Tweezers: Long hair implementation
This commit is contained in:
parent
8a06687907
commit
1da1c7cf5c
5 changed files with 119 additions and 39 deletions
|
@ -820,6 +820,7 @@ MonoBehaviour:
|
||||||
hairSprite: {fileID: 2595271014815681993}
|
hairSprite: {fileID: 2595271014815681993}
|
||||||
stubbleSprite: {fileID: 1989337582260767153}
|
stubbleSprite: {fileID: 1989337582260767153}
|
||||||
holder: {fileID: 2160021042345747175}
|
holder: {fileID: 2160021042345747175}
|
||||||
|
loop: {fileID: 1603625733790180753}
|
||||||
--- !u!1 &3082739543595333088
|
--- !u!1 &3082739543595333088
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -1261,6 +1262,7 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
hitOnFrame: 0
|
hitOnFrame: 0
|
||||||
heldHairSprite: {fileID: 267307033549538062}
|
heldHairSprite: {fileID: 267307033549538062}
|
||||||
|
tweezerSpriteTrans: {fileID: 2763505388420312793}
|
||||||
--- !u!95 &574744067652312223
|
--- !u!95 &574744067652312223
|
||||||
Animator:
|
Animator:
|
||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
|
|
|
@ -84,15 +84,15 @@ AnimationClip:
|
||||||
time: 0
|
time: 0
|
||||||
value: {x: 1, y: 0.8, z: 1}
|
value: {x: 1, y: 0.8, z: 1}
|
||||||
inSlope: {x: 0, y: 0, z: 0}
|
inSlope: {x: 0, y: 0, z: 0}
|
||||||
outSlope: {x: 0, y: 3.3500001, z: 0}
|
outSlope: {x: 0, y: 6, z: 0}
|
||||||
tangentMode: 0
|
tangentMode: 0
|
||||||
weightedMode: 0
|
weightedMode: 0
|
||||||
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
|
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
|
||||||
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
|
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
time: 0.2
|
time: 0.2
|
||||||
value: {x: 1, y: 1.47, z: 1}
|
value: {x: 1, y: 2, z: 1}
|
||||||
inSlope: {x: -0, y: 3.3500001, z: -0}
|
inSlope: {x: -0, y: 6, z: -0}
|
||||||
outSlope: {x: 0, y: 0, z: 0}
|
outSlope: {x: 0, y: 0, z: 0}
|
||||||
tangentMode: 0
|
tangentMode: 0
|
||||||
weightedMode: 0
|
weightedMode: 0
|
||||||
|
@ -425,15 +425,15 @@ AnimationClip:
|
||||||
time: 0
|
time: 0
|
||||||
value: 0.8
|
value: 0.8
|
||||||
inSlope: 0
|
inSlope: 0
|
||||||
outSlope: 3.3500001
|
outSlope: 6
|
||||||
tangentMode: 69
|
tangentMode: 69
|
||||||
weightedMode: 0
|
weightedMode: 0
|
||||||
inWeight: 0.33333334
|
inWeight: 0.33333334
|
||||||
outWeight: 0.33333334
|
outWeight: 0.33333334
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
time: 0.2
|
time: 0.2
|
||||||
value: 1.47
|
value: 2
|
||||||
inSlope: 3.3500001
|
inSlope: 6
|
||||||
outSlope: 0
|
outSlope: 0
|
||||||
tangentMode: 69
|
tangentMode: 69
|
||||||
weightedMode: 0
|
weightedMode: 0
|
||||||
|
|
|
@ -13,52 +13,100 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||||
public GameObject stubbleSprite;
|
public GameObject stubbleSprite;
|
||||||
private RhythmTweezers game;
|
private RhythmTweezers game;
|
||||||
private Tweezers tweezers;
|
private Tweezers tweezers;
|
||||||
|
private Animator anim;
|
||||||
private bool isHolding = false;
|
private int pluckState = 0;
|
||||||
private float holdBeat = 0f;
|
|
||||||
|
|
||||||
public GameObject holder;
|
public GameObject holder;
|
||||||
|
public GameObject loop;
|
||||||
|
|
||||||
|
private AudioSource pullSound;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
game = RhythmTweezers.instance;
|
game = RhythmTweezers.instance;
|
||||||
|
anim = GetComponent<Animator>();
|
||||||
tweezers = game.Tweezers;
|
tweezers = game.Tweezers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
float stateBeat = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset, game.beatInterval);
|
float stateBeat;
|
||||||
StateCheck(stateBeat);
|
|
||||||
|
|
||||||
if (PlayerInput.Pressed() && tweezers.hitOnFrame == 0)
|
switch (pluckState)
|
||||||
{
|
{
|
||||||
if (state.perfect)
|
// Able to be held.
|
||||||
{
|
case 0:
|
||||||
Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}");
|
stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.tweezerBeatOffset + game.beatInterval, 1f);
|
||||||
isHolding = true;
|
StateCheck(stateBeat);
|
||||||
holdBeat = Conductor.instance.songPositionInBeats;
|
|
||||||
}
|
if (PlayerInput.Pressed())
|
||||||
|
{
|
||||||
|
if (state.perfect)
|
||||||
|
{
|
||||||
|
pullSound = Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}");
|
||||||
|
pluckState = 1;
|
||||||
|
ResetState();
|
||||||
|
}
|
||||||
|
else if (state.notPerfect())
|
||||||
|
{
|
||||||
|
// I don't know what happens if you mess up here.
|
||||||
|
pluckState = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// In held state. Able to be released.
|
||||||
|
case 1:
|
||||||
|
stateBeat = Conductor.instance.GetPositionFromMargin(createBeat + game.tweezerBeatOffset + game.beatInterval + 0.5f, 1f);
|
||||||
|
StateCheck(stateBeat);
|
||||||
|
|
||||||
|
if (PlayerInput.PressedUp())
|
||||||
|
{
|
||||||
|
// It's possible to release earlier than earlyTime,
|
||||||
|
// and the hair will automatically be released before lateTime,
|
||||||
|
// so standard state checking isn't applied here
|
||||||
|
// (though StateCheck is still used for autoplay).
|
||||||
|
if (stateBeat >= Minigame.perfectTime)
|
||||||
|
{
|
||||||
|
Ace();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var normalized = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset + game.beatInterval, 0.5f);
|
||||||
|
// Hair gets released early and returns whoops.
|
||||||
|
anim.Play("LoopPullReverse", 0, normalized);
|
||||||
|
tweezers.anim.Play("Idle", 0, 0);
|
||||||
|
|
||||||
|
if (pullSound != null)
|
||||||
|
pullSound.Stop();
|
||||||
|
|
||||||
|
pluckState = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Released or missed. Can't be held or released.
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHolding && Conductor.instance.songPositionInBeats >= holdBeat + 0.5f)
|
if (pluckState == 1)
|
||||||
{
|
{
|
||||||
Destroy(holder.transform.GetChild(0).gameObject);
|
var hairDirection = tweezers.tweezerSpriteTrans.position - holder.transform.position;
|
||||||
isHolding = false;
|
holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection);
|
||||||
Ace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
float normalizedBeat = Conductor.instance.GetPositionFromBeat(createBeat + game.tweezerBeatOffset + game.beatInterval, 0.5f);
|
||||||
if (isHolding)
|
anim.Play("LoopPull", 0, normalizedBeat);
|
||||||
{
|
|
||||||
holder.transform.eulerAngles = new Vector3(0, 0, tweezers.transform.eulerAngles.z * 1.056f);
|
|
||||||
holder.transform.GetChild(0).transform.localScale = Vector2.one / holder.transform.localScale;
|
|
||||||
|
|
||||||
float normalizedBeat = Conductor.instance.GetPositionFromBeat(holdBeat, 0.5f);
|
|
||||||
GetComponent<Animator>().Play("LoopPull", 0, normalizedBeat);
|
|
||||||
tweezers.anim.Play("Tweezers_LongPluck", 0, normalizedBeat);
|
tweezers.anim.Play("Tweezers_LongPluck", 0, normalizedBeat);
|
||||||
// float angleBetweenTweezersAndHair = angleBtw2Points(tweezers.transform.position, holder.transform.position);
|
// float angleBetweenTweezersAndHair = angleBtw2Points(tweezers.transform.position, holder.transform.position);
|
||||||
// holder.transform.rotation = Quaternion.Euler(new Vector3(0, 0, angleBetweenTweezersAndHair));
|
// holder.transform.rotation = Quaternion.Euler(new Vector3(0, 0, angleBetweenTweezersAndHair));
|
||||||
|
|
||||||
|
// Auto-release if holding at release time.
|
||||||
|
if (normalizedBeat >= 1f)
|
||||||
|
Ace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop.transform.localScale = Vector2.one / holder.transform.localScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +117,27 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||||
|
|
||||||
public void Ace()
|
public void Ace()
|
||||||
{
|
{
|
||||||
Jukebox.PlayOneShotGame("rhythmTweezers/longPullEnd");
|
|
||||||
tweezers.LongPluck(true, this);
|
tweezers.LongPluck(true, this);
|
||||||
|
|
||||||
tweezers.hitOnFrame++;
|
tweezers.hitOnFrame++;
|
||||||
|
|
||||||
|
if (pullSound != null)
|
||||||
|
pullSound.Stop();
|
||||||
|
|
||||||
|
pluckState = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAce()
|
||||||
|
{
|
||||||
|
if (pluckState == 0)
|
||||||
|
{
|
||||||
|
pullSound = Jukebox.PlayOneShotGame($"rhythmTweezers/longPull{UnityEngine.Random.Range(1, 5)}");
|
||||||
|
pluckState = 1;
|
||||||
|
ResetState();
|
||||||
|
}
|
||||||
|
else if (pluckState == 1)
|
||||||
|
{
|
||||||
|
Ace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,7 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||||
private bool pluckingThisFrame;
|
private bool pluckingThisFrame;
|
||||||
private bool holdingHair;
|
private bool holdingHair;
|
||||||
public SpriteRenderer heldHairSprite;
|
public SpriteRenderer heldHairSprite;
|
||||||
|
public Transform tweezerSpriteTrans;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
@ -83,8 +84,12 @@ namespace RhythmHeavenMania.Games.RhythmTweezers
|
||||||
|
|
||||||
if (ace)
|
if (ace)
|
||||||
{
|
{
|
||||||
|
Jukebox.PlayOneShotGame("rhythmTweezers/longPullEnd");
|
||||||
|
|
||||||
hair.hairSprite.SetActive(false);
|
hair.hairSprite.SetActive(false);
|
||||||
hair.stubbleSprite.SetActive(true);
|
hair.stubbleSprite.SetActive(true);
|
||||||
|
// Making transparent instead of disabling because animators are silly.
|
||||||
|
hair.loop.GetComponent<SpriteRenderer>().color = Color.clear;
|
||||||
|
|
||||||
game.hairsLeft--;
|
game.hairsLeft--;
|
||||||
game.eyeSize = Mathf.Clamp(game.eyeSize + 1, 0, 10);
|
game.eyeSize = Mathf.Clamp(game.eyeSize + 1, 0, 10);
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace RhythmHeavenMania.Util
|
||||||
FindJukebox().GetComponent<AudioSource>().volume = volume;
|
FindJukebox().GetComponent<AudioSource>().volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayOneShot(string name, float beat = -1)
|
public static AudioSource PlayOneShot(string name, float beat = -1)
|
||||||
{
|
{
|
||||||
GameObject oneShot = new GameObject("oneShot");
|
GameObject oneShot = new GameObject("oneShot");
|
||||||
|
|
||||||
|
@ -55,9 +55,11 @@ namespace RhythmHeavenMania.Util
|
||||||
// snd.pitch = (clip.length / Conductor.instance.secPerBeat);
|
// snd.pitch = (clip.length / Conductor.instance.secPerBeat);
|
||||||
|
|
||||||
GameManager.instance.SoundObjects.Add(oneShot);
|
GameManager.instance.SoundObjects.Add(oneShot);
|
||||||
|
|
||||||
|
return audioSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayOneShotScheduled(string name, double targetTime)
|
public static AudioSource PlayOneShotScheduled(string name, double targetTime)
|
||||||
{
|
{
|
||||||
GameObject oneShot = new GameObject("oneShotScheduled");
|
GameObject oneShot = new GameObject("oneShotScheduled");
|
||||||
|
|
||||||
|
@ -75,22 +77,28 @@ namespace RhythmHeavenMania.Util
|
||||||
audioSource.PlayScheduled(targetTime);
|
audioSource.PlayScheduled(targetTime);
|
||||||
|
|
||||||
GameManager.instance.SoundObjects.Add(oneShot);
|
GameManager.instance.SoundObjects.Add(oneShot);
|
||||||
|
|
||||||
|
return audioSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayOneShotGame(string name, float beat = -1)
|
public static AudioSource PlayOneShotGame(string name, float beat = -1)
|
||||||
{
|
{
|
||||||
if (GameManager.instance.currentGame == name.Split('/')[0])
|
if (GameManager.instance.currentGame == name.Split('/')[0])
|
||||||
{
|
{
|
||||||
PlayOneShot($"games/{name}", beat);
|
return PlayOneShot($"games/{name}", beat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlayOneShotScheduledGame(string name, double targetTime)
|
public static AudioSource PlayOneShotScheduledGame(string name, double targetTime)
|
||||||
{
|
{
|
||||||
if (GameManager.instance.currentGame == name.Split('/')[0])
|
if (GameManager.instance.currentGame == name.Split('/')[0])
|
||||||
{
|
{
|
||||||
PlayOneShotScheduled($"games/{name}", targetTime);
|
return PlayOneShotScheduled($"games/{name}", targetTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue