mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 11:17:39 +02:00
Game Overlays (#280)
* add accuracy display * temp BG for show * separate overlays prefab make proper shader for star effects * aim shakiness display * implement testing skill star * fully functional skill star * separate section display from editor * fully separate chart section display from timeline * add section to overlays * fix nullreference issues * start game layout settings * add game settings script * fix nonfunctioning scoring * invert y position logic on timing bar * add perfect challenge functionality * fix section not showing up in editor add perfect challenge option * add timing display minimal mode * Update PerfectAndPractice.png * show gismo for minigame bounds in editor * add ability to disable overlays in editor * prepare medals add new timing display graphic * hide screen preview * per-axis camera control added per request * section medals basic functionality * add medal get animations * fix bug with perfect icons * visual enhancements * adjust look of timing display minmode address audio ducking issues(?) * prepare overlay lyt editor add viewport pan, rotate, scale adjust audio setting * add layout editor UI elements * dynamic overlay creation * fix default single timing disp * set up overlay settings controls * start UI events * runtime uuid for component reference * layout editor affects overlay elements * show overlay element previews while editing * advanced audio settings * fix bug in drop-down creation * fallback defaults for the new stuff * fix textbox & overlay visibility bugs
This commit is contained in:
@ -7,6 +7,7 @@ using UnityEngine;
|
||||
using Starpelly;
|
||||
using Newtonsoft.Json;
|
||||
using HeavenStudio.Games;
|
||||
using HeavenStudio.Common;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
@ -21,7 +22,7 @@ namespace HeavenStudio
|
||||
[Header("Components")]
|
||||
public string txt;
|
||||
public string ext;
|
||||
public Camera GameCamera, CursorCam, OverlayCamera;
|
||||
public Camera GameCamera, CursorCam, OverlayCamera, StaticCamera;
|
||||
public GameObject GameLetterbox;
|
||||
public CircleCursor CircleCursor;
|
||||
[HideInInspector] public GameObject GamesHolder;
|
||||
@ -44,11 +45,7 @@ namespace HeavenStudio
|
||||
public bool autoplay;
|
||||
public bool canInput = true;
|
||||
public DynamicBeatmap.ChartSection currentSection, nextSection;
|
||||
public float sectionProgress { get {
|
||||
if (currentSection == null) return 0;
|
||||
if (nextSection == null) return (Conductor.instance.songPositionInBeats - currentSection.beat) / (endBeat - currentSection.beat);
|
||||
return (Conductor.instance.songPositionInBeats - currentSection.beat) / (nextSection.beat - currentSection.beat);
|
||||
}}
|
||||
public float sectionProgress { get; private set; }
|
||||
|
||||
public event Action<float> onBeatChanged;
|
||||
public event Action<DynamicBeatmap.ChartSection> onSectionChange;
|
||||
@ -88,6 +85,7 @@ namespace HeavenStudio
|
||||
return totalPlayerAccuracy / totalInputs;
|
||||
}
|
||||
}
|
||||
bool skillStarCollected = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@ -125,8 +123,23 @@ namespace HeavenStudio
|
||||
Conductor.instance.SetVolume(Beatmap.musicVolume);
|
||||
Conductor.instance.firstBeatOffset = Beatmap.firstBeatOffset;
|
||||
|
||||
GameObject textbox = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Textbox"));
|
||||
textbox.name = "Textbox";
|
||||
// note: serialize this shit in the inspector //
|
||||
GameObject textbox = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Textbox"));
|
||||
textbox.name = "Textbox";
|
||||
|
||||
GameObject overlays = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays"));
|
||||
overlays.name = "Overlays";
|
||||
|
||||
GameObject timingDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/TimingAccuracy"));
|
||||
timingDisp.name = "TimingDisplay";
|
||||
|
||||
GameObject skillStarDisp = Instantiate(Resources.Load<GameObject>("Prefabs/Common/Overlays/SkillStar"));
|
||||
skillStarDisp.name = "SkillStar";
|
||||
|
||||
GoForAPerfect.instance.Disable();
|
||||
/////
|
||||
|
||||
|
||||
if (txt != null && ext != null)
|
||||
{
|
||||
LoadRemix(txt, ext);
|
||||
@ -206,12 +219,25 @@ namespace HeavenStudio
|
||||
}
|
||||
}
|
||||
|
||||
public void ScoreInputAccuracy(double accuracy, bool late, double weight = 1)
|
||||
public void ScoreInputAccuracy(double accuracy, bool late, double time, double weight = 1, bool doDisplay = true)
|
||||
{
|
||||
totalInputs += weight;
|
||||
totalPlayerAccuracy += accuracy * weight;
|
||||
|
||||
if (accuracy < Minigame.rankOkThreshold && weight > 0)
|
||||
{
|
||||
SkillStarManager.instance.KillStar();
|
||||
}
|
||||
|
||||
if (SkillStarManager.instance.IsEligible && !skillStarCollected && accuracy >= 1f)
|
||||
{
|
||||
if (SkillStarManager.instance.DoStarJust())
|
||||
skillStarCollected = true;
|
||||
}
|
||||
|
||||
// push the hit event to the timing display
|
||||
if (doDisplay)
|
||||
TimingAccuracyDisplay.instance.MakeAccuracyVfx(time, late);
|
||||
}
|
||||
|
||||
public void SeekAheadAndPreload(double start, float seekTime = 8f)
|
||||
@ -292,7 +318,6 @@ namespace HeavenStudio
|
||||
}
|
||||
}
|
||||
|
||||
// LateUpdate works a bit better(?) but causes some bugs (like issues with bop animations).
|
||||
private void Update()
|
||||
{
|
||||
PlayerInput.UpdateInputControllers();
|
||||
@ -301,16 +326,16 @@ namespace HeavenStudio
|
||||
return;
|
||||
if (!Conductor.instance.isPlaying)
|
||||
return;
|
||||
Conductor cond = Conductor.instance;
|
||||
|
||||
|
||||
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
||||
|
||||
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
|
||||
if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0)
|
||||
{
|
||||
if (Conductor.instance.songPositionInBeatsAsDouble >= tempoChanges[currentTempoEvent])
|
||||
if (cond.songPositionInBeatsAsDouble >= tempoChanges[currentTempoEvent])
|
||||
{
|
||||
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
|
||||
cond.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
|
||||
currentTempoEvent++;
|
||||
}
|
||||
}
|
||||
@ -318,9 +343,9 @@ namespace HeavenStudio
|
||||
List<float> volumeChanges = Beatmap.volumeChanges.Select(c => c.beat).ToList();
|
||||
if (currentVolumeEvent < Beatmap.volumeChanges.Count && currentVolumeEvent >= 0)
|
||||
{
|
||||
if (Conductor.instance.songPositionInBeatsAsDouble >= volumeChanges[currentVolumeEvent])
|
||||
if (cond.songPositionInBeatsAsDouble >= volumeChanges[currentVolumeEvent])
|
||||
{
|
||||
Conductor.instance.SetVolume(Beatmap.volumeChanges[currentVolumeEvent].volume);
|
||||
cond.SetVolume(Beatmap.volumeChanges[currentVolumeEvent].volume);
|
||||
currentVolumeEvent++;
|
||||
}
|
||||
}
|
||||
@ -328,7 +353,7 @@ namespace HeavenStudio
|
||||
List<float> chartSections = Beatmap.beatmapSections.Select(c => c.beat).ToList();
|
||||
if (currentSectionEvent < Beatmap.beatmapSections.Count && currentSectionEvent >= 0)
|
||||
{
|
||||
if (Conductor.instance.songPositionInBeatsAsDouble >= chartSections[currentSectionEvent])
|
||||
if (cond.songPositionInBeatsAsDouble >= chartSections[currentSectionEvent])
|
||||
{
|
||||
Debug.Log("Section " + Beatmap.beatmapSections[currentSectionEvent].sectionName + " started");
|
||||
currentSection = Beatmap.beatmapSections[currentSectionEvent];
|
||||
@ -343,13 +368,13 @@ namespace HeavenStudio
|
||||
|
||||
float seekTime = 8f;
|
||||
//seek ahead to preload games that have assetbundles
|
||||
SeekAheadAndPreload(Conductor.instance.songPositionInBeatsAsDouble, seekTime);
|
||||
SeekAheadAndPreload(cond.songPositionInBeatsAsDouble, seekTime);
|
||||
|
||||
SeekAheadAndDoPreEvent(Conductor.instance.songPositionInBeatsAsDouble);
|
||||
|
||||
if (currentEvent < Beatmap.entities.Count && currentEvent >= 0)
|
||||
{
|
||||
if (Conductor.instance.songPositionInBeatsAsDouble >= entities[currentEvent])
|
||||
if (cond.songPositionInBeatsAsDouble >= entities[currentEvent])
|
||||
{
|
||||
// allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay
|
||||
var entitiesAtSameBeat = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentEvent].beat && !EventCaller.FXOnlyGames().Contains(EventCaller.instance.GetMinigame(c.datamodel.Split('/')[0])));
|
||||
@ -380,10 +405,26 @@ namespace HeavenStudio
|
||||
// Thank you to @shshwdr for bring this to my attention
|
||||
currentEvent++;
|
||||
}
|
||||
|
||||
// currentEvent += gameManagerEntities.Count;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSection == null)
|
||||
{
|
||||
sectionProgress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float currectSectionStart = (float)cond.GetSongPosFromBeat(currentSection.beat);
|
||||
|
||||
if (nextSection == null)
|
||||
sectionProgress = (cond.songPosition - currectSectionStart) / ((float)cond.GetSongPosFromBeat(endBeat) - currectSectionStart);
|
||||
else
|
||||
sectionProgress = (cond.songPosition - currectSectionStart) / ((float)cond.GetSongPosFromBeat(nextSection.beat) - currectSectionStart);
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate() {
|
||||
OverlaysManager.instance.TogleOverlaysVisibility(Editor.Editor.instance == null || Editor.Editor.instance.fullscreen || ((PersistentDataManager.gameSettings.overlaysInEditor) && (!Editor.Editor.instance.fullscreen)) || HeavenStudio.Editor.GameSettings.InPreview);
|
||||
}
|
||||
|
||||
public void ToggleInputs(bool inputs)
|
||||
@ -402,6 +443,15 @@ namespace HeavenStudio
|
||||
totalInputs = 0;
|
||||
totalPlayerAccuracy = 0;
|
||||
|
||||
TimingAccuracyDisplay.instance.ResetArrow();
|
||||
SkillStarManager.instance.Reset();
|
||||
skillStarCollected = false;
|
||||
|
||||
GoForAPerfect.instance.perfect = true;
|
||||
GoForAPerfect.instance.Disable();
|
||||
|
||||
SectionMedalsManager.instance.Reset();
|
||||
|
||||
StartCoroutine(PlayCo(beat));
|
||||
onBeatChanged?.Invoke(beat);
|
||||
}
|
||||
@ -441,6 +491,12 @@ namespace HeavenStudio
|
||||
onBeatChanged?.Invoke(beat);
|
||||
KillAllSounds();
|
||||
|
||||
// I feel like I should standardize the names
|
||||
SkillStarManager.instance.KillStar();
|
||||
TimingAccuracyDisplay.instance.StopStarFlash();
|
||||
GoForAPerfect.instance.Disable();
|
||||
SectionMedalsManager.instance.OnRemixEnd();
|
||||
|
||||
Debug.Log($"Average input offset for playthrough: {averageInputOffset}ms");
|
||||
Debug.Log($"Accuracy for playthrough: {(PlayerAccuracy * 100) : 0.00}");
|
||||
|
||||
|
Reference in New Issue
Block a user