mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 13:47:38 +02:00
Alternate Control Styles Support (#554)
* add mouse controller * support different control styles in options deprecate old input check methods * fully functional input actions system * btsds InputAction * blue bear InputAction * more games fix bugs with some input related systems * coin toss re-toss * cheer readers touch * dog ninja touch * multiple games * last of the easy games' touch * more specialized games * specialized games 2 * finish ktb games * remove legacy settings disclaimer * "only" two games left * karate man touch * rockers touch still needs fixes and bad judge strum * DSGuy flicking animation * playstyle chart property * improve performance of minigame preloading * improve look of cursor make assetbundles use chunk-based compression refactor assetbundle loading methods a bit * prime conductor stream playback to stabilize seeking operations * fix air rally swing on pad release * use virtual mouse pointer * add UniTask * make BeatAction use UniTask * implement UniTask to replace some coroutines * add touch style UI elements and effects games now support the ability to define two cursor colours if they need split screen touch inputs * update plugins and buildscript * implement thresholded pointer position clipping * fix clamping * instant show / hide fix discord game SDK crashes
This commit is contained in:
@ -1,12 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using DG.Tweening;
|
||||
using HeavenStudio.Util;
|
||||
using Starpelly;
|
||||
|
||||
using HeavenStudio.Common;
|
||||
|
||||
namespace HeavenStudio.Games
|
||||
@ -27,11 +22,13 @@ namespace HeavenStudio.Games
|
||||
|
||||
public ActionEventCallback OnDestroy; //Function to trigger whenever this event gets destroyed. /!\ Shouldn't be used for a minigame! Use OnMiss instead /!\
|
||||
|
||||
public PlayerInput.InputAction InputAction;
|
||||
|
||||
public double startBeat;
|
||||
public double timer;
|
||||
|
||||
public bool isEligible = true;
|
||||
public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss
|
||||
public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss
|
||||
public bool enabled = true; //Indicates if the PlayerActionEvent is enabled. If set to false, it'll not trigger any events and destroy itself AFTER it's not relevant anymore
|
||||
public bool triggersAutoplay = true;
|
||||
bool lockedByEvent = false;
|
||||
@ -44,11 +41,11 @@ namespace HeavenStudio.Games
|
||||
public InputType inputType; //The type of input. Check the InputType class to see a list of all of them
|
||||
|
||||
public bool perfectOnly = false; //Indicates that the input only recognize perfect inputs.
|
||||
|
||||
|
||||
public bool countsForAccuracy = true; //Indicates if the input counts for the accuracy or not. If set to false, it'll not be counted in the accuracy calculation
|
||||
|
||||
public void setHitCallback(ActionEventCallbackState OnHit)
|
||||
{
|
||||
{
|
||||
this.OnHit = OnHit;
|
||||
}
|
||||
|
||||
@ -62,13 +59,17 @@ namespace HeavenStudio.Games
|
||||
this.IsHittable = IsHittable;
|
||||
}
|
||||
|
||||
public void Enable() { enabled = true; }
|
||||
public void Enable() { enabled = true; }
|
||||
public void Disable() { enabled = false; }
|
||||
public void QueueDeletion() { markForDeletion = true; }
|
||||
|
||||
public bool IsCorrectInput(out double dt)
|
||||
{
|
||||
dt = 0;
|
||||
if (InputAction != null)
|
||||
{
|
||||
return PlayerInput.GetIsAction(InputAction, out dt);
|
||||
}
|
||||
return (
|
||||
//General inputs, both down and up
|
||||
(PlayerInput.Pressed(out dt) && inputType.HasFlag(InputType.STANDARD_DOWN)) ||
|
||||
@ -103,7 +104,7 @@ namespace HeavenStudio.Games
|
||||
public void Update()
|
||||
{
|
||||
if (markForDeletion) CleanUp();
|
||||
if(!Conductor.instance.NotStopped()) CleanUp(); // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
||||
if (!Conductor.instance.NotStopped()) CleanUp(); // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
||||
|
||||
if (noAutoplay && autoplayOnly) autoplayOnly = false;
|
||||
if (noAutoplay && triggersAutoplay) triggersAutoplay = false;
|
||||
@ -127,12 +128,16 @@ namespace HeavenStudio.Games
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!autoplayOnly && (IsHittable == null || IsHittable != null && IsHittable()) && IsCorrectInput(out double dt))
|
||||
{
|
||||
normalizedTime -= dt;
|
||||
if (IsExpectingInputNow())
|
||||
{
|
||||
// if (InputAction != null)
|
||||
// {
|
||||
// Debug.Log("Hit " + InputAction.name);
|
||||
// }
|
||||
double stateProg = ((normalizedTime - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2;
|
||||
Hit(stateProg, normalizedTime);
|
||||
}
|
||||
@ -143,9 +148,12 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
}
|
||||
|
||||
public void LateUpdate() {
|
||||
if (markForDeletion) {
|
||||
CleanUp();
|
||||
public void LateUpdate()
|
||||
{
|
||||
if (markForDeletion)
|
||||
{
|
||||
allEvents.Remove(this);
|
||||
OnDestroy(this);
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
foreach (PlayerActionEvent evt in allEvents)
|
||||
@ -156,12 +164,22 @@ namespace HeavenStudio.Games
|
||||
|
||||
private bool CheckEventLock()
|
||||
{
|
||||
foreach(PlayerActionEvent toCompare in allEvents)
|
||||
foreach (PlayerActionEvent toCompare in allEvents)
|
||||
{
|
||||
if (toCompare == this) continue;
|
||||
if (toCompare.autoplayOnly) continue;
|
||||
if ((toCompare.inputType & this.inputType) == 0) continue;
|
||||
if (!toCompare.IsExpectingInputNow()) continue;
|
||||
if (InputAction != null)
|
||||
{
|
||||
if (toCompare.InputAction == null) continue;
|
||||
int catIdx = (int)PlayerInput.CurrentControlStyle;
|
||||
if (toCompare.InputAction != null
|
||||
&& toCompare.InputAction.inputLockCategory[catIdx] != InputAction.inputLockCategory[catIdx]) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((toCompare.inputType & this.inputType) == 0) continue;
|
||||
if (!toCompare.IsExpectingInputNow()) continue;
|
||||
}
|
||||
|
||||
double t1 = this.startBeat + this.timer;
|
||||
double t2 = toCompare.startBeat + toCompare.timer;
|
||||
@ -169,7 +187,7 @@ namespace HeavenStudio.Games
|
||||
|
||||
// compare distance between current time and the events
|
||||
// events that happen at the exact same time with the exact same inputs will return true
|
||||
if (Math.Abs(t1 - songPos) > Math.Abs(t2 - songPos))
|
||||
if (Math.Abs(t1 - songPos) > Math.Abs(t2 - songPos))
|
||||
return false;
|
||||
else if (t1 != t2) // if they are the same time, we don't want to lock the event
|
||||
toCompare.lockedByEvent = true;
|
||||
@ -179,7 +197,7 @@ namespace HeavenStudio.Games
|
||||
|
||||
private void AutoplayInput(double normalizedTime, bool autoPlay = false)
|
||||
{
|
||||
if (triggersAutoplay && (GameManager.instance.autoplay || autoPlay) && GameManager.instance.canInput && normalizedTime >= 1f - (Time.deltaTime*0.5f))
|
||||
if (triggersAutoplay && (GameManager.instance.autoplay || autoPlay) && GameManager.instance.canInput && normalizedTime >= 1f - (Time.deltaTime * 0.5f))
|
||||
{
|
||||
AutoplayEvent();
|
||||
if (!autoPlay)
|
||||
@ -205,7 +223,6 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
if (!enabled) return false;
|
||||
if (!isEligible) return false;
|
||||
if (markForDeletion) return false;
|
||||
|
||||
double normalizedBeat = GetNormalizedTime();
|
||||
return normalizedBeat > Minigame.NgEarlyTime() && normalizedBeat < Minigame.NgLateTime();
|
||||
@ -237,7 +254,7 @@ namespace HeavenStudio.Games
|
||||
}
|
||||
|
||||
//The state parameter is either -1 -> Early, 0 -> Perfect, 1 -> Late
|
||||
public void Hit(double state, double time)
|
||||
public void Hit(double state, double time)
|
||||
{
|
||||
if (OnHit != null && enabled)
|
||||
{
|
||||
@ -247,7 +264,7 @@ namespace HeavenStudio.Games
|
||||
int offset = Mathf.CeilToInt((float)normalized * 1000);
|
||||
GameManager.instance.AvgInputOffset = offset;
|
||||
state = System.Math.Max(-1.0, System.Math.Min(1.0, state));
|
||||
OnHit(this, (float) state);
|
||||
OnHit(this, (float)state);
|
||||
|
||||
CleanUp();
|
||||
if (countsForAccuracy && !(noAutoplay || autoplayOnly) && isEligible)
|
||||
@ -263,9 +280,10 @@ namespace HeavenStudio.Games
|
||||
GoForAPerfect.instance.Hit();
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
Blank();
|
||||
Blank();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -333,7 +351,7 @@ namespace HeavenStudio.Games
|
||||
|
||||
public void Blank()
|
||||
{
|
||||
if(OnBlank != null && enabled && !autoplayOnly)
|
||||
if (OnBlank != null && enabled && !autoplayOnly)
|
||||
{
|
||||
OnBlank(this);
|
||||
}
|
||||
@ -342,8 +360,6 @@ namespace HeavenStudio.Games
|
||||
public void CleanUp()
|
||||
{
|
||||
if (markForDeletion) return;
|
||||
allEvents.Remove(this);
|
||||
OnDestroy(this);
|
||||
markForDeletion = true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user