Skip to content

Commit 36973a5

Browse files
committed
Added HitScoreVisualizer integration
1 parent cbe9961 commit 36973a5

File tree

4 files changed

+140
-41
lines changed

4 files changed

+140
-41
lines changed

DisplaySection.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using TMPro;
7+
using UnityEngine;
8+
9+
namespace PerfectionDisplay
10+
{
11+
class DisplaySection : MonoBehaviour
12+
{
13+
TextMeshPro scoreMesh;
14+
public string title;
15+
public string color;
16+
17+
void Awake()
18+
{
19+
scoreMesh = this.gameObject.AddComponent<TextMeshPro>();
20+
scoreMesh.text = "";
21+
scoreMesh.fontSize = 3;
22+
scoreMesh.lineSpacing = -25f;
23+
scoreMesh.lineSpacingAdjustment = -25f;
24+
scoreMesh.enableAutoSizing = false;
25+
scoreMesh.paragraphSpacing = -25f;
26+
scoreMesh.color = Color.white;
27+
scoreMesh.font = Resources.Load<TMP_FontAsset>("Teko-Medium SDF No Glow");
28+
scoreMesh.alignment = TextAlignmentOptions.Center;
29+
}
30+
public void UpdateText(int score, string percent)
31+
{
32+
string text = "<color=" + color + ">" + title+"\n";
33+
if (PerfectDisplay.showNumbers) text += score + "\n";
34+
if (PerfectDisplay.showPercent) text += percent + "%\n";
35+
scoreMesh.text = text;
36+
scoreMesh.ForceMeshUpdate();
37+
}
38+
public void UpdatePosition(float x)
39+
{
40+
transform.localPosition = PerfectDisplay.displayPosition+new Vector3(x,0,0);
41+
}
42+
43+
public float GetWidth()
44+
{
45+
return scoreMesh.GetRenderedValues().x+0.1f;
46+
}
47+
}
48+
}

PerfectDisplay.cs

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
63
using UnityEngine;
7-
using TMPro;
84
using System.Collections;
95

106
namespace PerfectionDisplay
117
{
128
class PerfectDisplay : MonoBehaviour
139
{
14-
TextMeshPro scoreMesh;
1510
ScoreController scoreController;
1611
public static Vector3 displayPosition = new Vector3(0, 2.3f, 7f);
1712
public static int[] scoreRanges = { 100, 90, 50 };
13+
public static string[] hitScoreNames;
14+
public static bool shouldHitscore = true;
1815
public static string[] colors = { "#2175ff", "green", "yellow", "orange", "red" };
1916
int[] scoreCount;
17+
DisplaySection[] sections;
2018
int misses = 0;
2119
int notes = 0;
2220
public static bool showNumbers = true;
@@ -42,13 +40,21 @@ void Awake()
4240
}
4341
private void Init()
4442
{
45-
scoreMesh = this.gameObject.AddComponent<TextMeshPro>();
46-
scoreMesh.text = "";
47-
scoreMesh.fontSize = 3;
48-
scoreMesh.color = Color.white;
49-
scoreMesh.font = Resources.Load<TMP_FontAsset>("Teko-Medium SDF No Glow");
50-
scoreMesh.alignment = TextAlignmentOptions.Center;
51-
scoreMesh.rectTransform.position = displayPosition;
43+
sections = new DisplaySection[colors.Length];
44+
sections[scoreRanges.Length] = new GameObject().AddComponent<DisplaySection>();
45+
sections[scoreRanges.Length].color = colors[scoreRanges.Length];
46+
sections[scoreRanges.Length].title = "<" + scoreRanges[scoreRanges.Length - 1];
47+
if(shouldHitscore) sections[scoreRanges.Length].title = hitScoreNames[hitScoreNames.Length-1];
48+
sections[scoreRanges.Length + 1] = new GameObject().AddComponent<DisplaySection>();
49+
sections[scoreRanges.Length + 1].color = colors[scoreRanges.Length + 1];
50+
sections[scoreRanges.Length + 1].title = "MISS";
51+
for (int i = 0; i < scoreRanges.Length; i++)
52+
{
53+
sections[i] = new GameObject().AddComponent<DisplaySection>();
54+
sections[i].color = colors[i];
55+
sections[i].title = ">" + scoreRanges[i];
56+
if (shouldHitscore) sections[i].title = hitScoreNames[i];
57+
}
5258
if (scoreController != null)
5359
{
5460
scoreController.noteWasMissedEvent += Miss;
@@ -93,47 +99,46 @@ public void Cut(NoteData data, NoteCutInfo info, int combo)
9399

94100
public void UpdateText()
95101
{
96-
String text = "";
97-
if (showNumbers)
102+
float width = 0;
103+
for(int i = 0; i < scoreCount.Length; i++)
98104
{
99-
for (int i = 0; i < scoreRanges.Length; i++)
100-
{
101-
text += "<color=" + colors[i] + ">" + ">" + scoreRanges[i] + "-" + scoreCount[i] + "<color=\"black\">|";
102-
}
103-
text += "<color=" + colors[scoreRanges.Length] + ">" + "<" + scoreRanges[scoreRanges.Length - 1] + "-" + scoreCount[scoreRanges.Length] + "<color=\"black\">|";
104-
text += "<color=" + colors[scoreRanges.Length + 1] + ">" + "MISS-" + misses +"\n";
105+
sections[i].UpdateText(scoreCount[i], GetPercent(scoreCount[i]));
106+
width += sections[i].GetWidth();
105107
}
106-
if (showPercent)
108+
sections[scoreRanges.Length+1].UpdateText(misses, GetPercent(misses));
109+
width += sections[scoreRanges.Length + 1].GetWidth();
110+
111+
float curX = sections[0].GetWidth() / 2; ;
112+
for (int i = 0; i < scoreCount.Length; i++)
107113
{
108-
for (int i = 0; i < scoreRanges.Length; i++)
109-
{
110-
text += "<color=" + colors[i] + ">" + ">" + scoreRanges[i] + "-" + GetPercent(scoreCount[i]) + "%<color=\"black\">|";
111-
}
112-
text += "<color=" + colors[scoreRanges.Length] + ">" + "<" + scoreRanges[scoreRanges.Length - 1] + "-" + GetPercent(scoreCount[scoreRanges.Length]) + "%<color=\"black\">|";
113-
text += "<color=" + colors[scoreRanges.Length + 1] + ">" + "MISS-" + GetPercent(misses) + "%";
114+
sections[i].UpdatePosition(-(width/2)+curX);
115+
curX += sections[i].GetWidth() / 2;
116+
curX += sections[i + 1].GetWidth() / 2;
114117
}
118+
sections[scoreRanges.Length+1].UpdatePosition(-(width / 2) + curX);
119+
120+
115121
Plugin.lastText = "Range\n";
116122
for (int i = 0; i < scoreRanges.Length; i++)
117123
{
118-
Plugin.lastText += "<color=" + colors[i] + ">" + ">" + scoreRanges[i] + "\n";
124+
Plugin.lastText += "<color=" + colors[i] + ">" + (shouldHitscore?hitScoreNames[i]:(">" + scoreRanges[i])) + "\n";
119125
}
120-
Plugin.lastText += "<color=" + colors[scoreRanges.Length] + ">" + "<" + scoreRanges[scoreRanges.Length - 1] + "\n";
126+
Plugin.lastText += "<color=" + colors[scoreRanges.Length] + ">" + (shouldHitscore ? hitScoreNames[scoreRanges.Length - 1] : ("<" + scoreRanges[scoreRanges.Length - 1])) + "\n";
121127
Plugin.lastText += "<color=" + colors[scoreRanges.Length + 1] + ">" + "MISS";
122128
Plugin.lastCount = "Count\n";
123129
for (int i = 0; i < scoreRanges.Length; i++)
124130
{
125131
Plugin.lastCount += "<color=" + colors[i] + ">" + scoreCount[i] + "\n";
126132
}
127-
Plugin.lastCount += "<color=" + colors[scoreRanges.Length] + ">" + scoreCount[scoreRanges.Length - 1] + "\n";
133+
Plugin.lastCount += "<color=" + colors[scoreRanges.Length] + ">" + scoreCount[scoreRanges.Length] + "\n";
128134
Plugin.lastCount += "<color=" + colors[scoreRanges.Length + 1] + ">" + misses;
129135
Plugin.lastPercent = "Percent\n";
130136
for (int i = 0; i < scoreRanges.Length; i++)
131137
{
132138
Plugin.lastPercent += "<color=" + colors[i] + ">" + GetPercent(scoreCount[i]) + "%\n";
133139
}
134-
Plugin.lastPercent += "<color=" + colors[scoreRanges.Length] + ">" + GetPercent(scoreCount[scoreRanges.Length - 1]) + "%\n";
135-
Plugin.lastPercent += "<color=" + colors[scoreRanges.Length + 1] + ">" + GetPercent(misses);
136-
scoreMesh.text = text;
140+
Plugin.lastPercent += "<color=" + colors[scoreRanges.Length] + ">" + GetPercent(scoreCount[scoreRanges.Length]) + "%\n";
141+
Plugin.lastPercent += "<color=" + colors[scoreRanges.Length + 1] + ">" + GetPercent(misses)+"%";
137142
}
138143
private String GetPercent(int hits)
139144
{

Perfection Display.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
<Reference Include="Assembly-CSharp">
3737
<HintPath>E:\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\Assembly-CSharp.dll</HintPath>
3838
</Reference>
39+
<Reference Include="HitScoreVisualizer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
40+
<SpecificVersion>False</SpecificVersion>
41+
<HintPath>..\..\..\..\Desktop\HitScoreVisualizer.dll</HintPath>
42+
</Reference>
3943
<Reference Include="IllusionPlugin">
4044
<HintPath>E:\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\IllusionPlugin.dll</HintPath>
4145
</Reference>
@@ -68,6 +72,7 @@
6872
</Reference>
6973
</ItemGroup>
7074
<ItemGroup>
75+
<Compile Include="DisplaySection.cs" />
7176
<Compile Include="PerfectDisplay.cs" />
7277
<Compile Include="Plugin.cs" />
7378
<Compile Include="Properties\AssemblyInfo.cs" />

Plugin.cs

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using IllusionPlugin;
22
using System;
33
using System.Globalization;
4+
using System.IO;
45
using System.Linq;
6+
using System.Reflection;
57
using TMPro;
68
using UnityEngine;
79
using UnityEngine.SceneManagement;
@@ -11,13 +13,15 @@ namespace PerfectionDisplay
1113
public class Plugin : IPlugin
1214
{
1315
public string Name => "Perfection Display";
14-
public string Version => "1.2.0";
16+
public string Version => "1.3.0";
1517

1618
public static string lastText = "";
1719
public static string lastPercent = "";
1820
public static string lastCount = "";
1921

2022
private readonly string[] env = { "DefaultEnvironment", "BigMirrorEnvironment", "TriangleEnvironment", "NiceEnvironment" };
23+
24+
bool init = true;
2125

2226
public void OnApplicationStart()
2327
{
@@ -68,15 +72,35 @@ public void OnApplicationStart()
6872
}
6973
PerfectDisplay.showNumbers = ModPrefs.GetBool("PerfectionDisplay", "Show Count", PerfectDisplay.showNumbers, true);
7074
PerfectDisplay.showPercent = ModPrefs.GetBool("PerfectionDisplay", "Show Percent", PerfectDisplay.showPercent, true);
75+
PerfectDisplay.shouldHitscore = ModPrefs.GetBool("PerfectionDisplay", "HitScoreVisualizer Integration", PerfectDisplay.shouldHitscore, true);
7176
}
7277

7378
public void OnApplicationQuit()
7479
{
7580
SceneManager.activeSceneChanged -= OnSceneChanged;
7681
}
77-
82+
private void LoadHitScore()
83+
{
84+
HitScoreVisualizer.Config.Judgment[] judgments = HitScoreVisualizer.Config.instance.judgments;
85+
PerfectDisplay.scoreRanges = new int[judgments.Length - 1];
86+
PerfectDisplay.hitScoreNames = new string[judgments.Length];
87+
PerfectDisplay.colors = new string[judgments.Length + 1];
88+
for (int i = 0; i < judgments.Length; i++)
89+
{
90+
if (i != PerfectDisplay.scoreRanges.Length) PerfectDisplay.scoreRanges[i] = judgments[i].threshold - 1;
91+
PerfectDisplay.hitScoreNames[i] = judgments[i].text.Replace("%n", "").Replace("%s", "").Replace("%B", "").Replace("%C", "").Replace("%A", "").Trim();
92+
PerfectDisplay.colors[i] = "#" + ((int)(judgments[i].color[0] * 255)).ToString("X2") + ((int)(judgments[i].color[1] * 255)).ToString("X2") + ((int)(judgments[i].color[2] * 255)).ToString("X2") + ((int)(judgments[i].color[3] * 255)).ToString("X2");
93+
}
94+
PerfectDisplay.colors[PerfectDisplay.colors.Length - 1] = "#FF0000";
95+
}
7896
private void OnSceneChanged(Scene _, Scene scene)
7997
{
98+
if (init)
99+
{
100+
init = false;
101+
if (PerfectDisplay.shouldHitscore && HasType("HitScoreVisualizer")) LoadHitScore();
102+
else PerfectDisplay.shouldHitscore = false;
103+
}
80104
if(scene.name.Equals("Menu"))
81105
{
82106
foreach (var rootGameObject in scene.GetRootGameObjects())
@@ -86,21 +110,24 @@ private void OnSceneChanged(Scene _, Scene scene)
86110
TextMeshProUGUI text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll<TextMeshProUGUI>().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false);
87111
text.fontSize = 4;
88112
text.color = Color.white;
113+
text.paragraphSpacing = -15f;
89114
text.text = lastText;
90-
text.alignment = TextAlignmentOptions.Left;
91-
text.rectTransform.localPosition = new Vector3(-20, 28, 0);
115+
text.alignment = TextAlignmentOptions.TopLeft;
116+
text.rectTransform.localPosition = new Vector3(-25, 40, 0);
92117
text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll<TextMeshProUGUI>().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false);
93118
text.fontSize = 4;
94119
text.color = Color.white;
120+
text.paragraphSpacing = -15f;
95121
text.text = lastCount;
96-
text.alignment = TextAlignmentOptions.Left;
97-
text.rectTransform.localPosition = new Vector3(3, 28, 0);
122+
text.alignment = TextAlignmentOptions.TopLeft;
123+
text.rectTransform.localPosition = new Vector3(0-5, 40, 0);
98124
text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll<TextMeshProUGUI>().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false);
99125
text.fontSize = 4;
100126
text.color = Color.white;
127+
text.paragraphSpacing = -15f;
101128
text.text = lastPercent;
102-
text.alignment = TextAlignmentOptions.Left;
103-
text.rectTransform.localPosition = new Vector3(-10, 28, 0);
129+
text.alignment = TextAlignmentOptions.TopLeft;
130+
text.rectTransform.localPosition = new Vector3(10-5, 40, 0);
104131
return;
105132
}
106133
}
@@ -110,6 +137,20 @@ private void OnSceneChanged(Scene _, Scene scene)
110137
new GameObject("PerfectDisplay").AddComponent<PerfectDisplay>();
111138
}
112139

140+
private bool HasType(string typeName)
141+
{
142+
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
143+
{
144+
foreach (Type type in assembly.GetTypes())
145+
{
146+
if (type.Namespace == typeName)
147+
return true;
148+
}
149+
}
150+
151+
return false;
152+
}
153+
113154
public void OnLevelWasLoaded(int level)
114155
{
115156
}

0 commit comments

Comments
 (0)