Skip to content

Commit bf88667

Browse files
Tutorial on first launch of menu
1 parent 92961bc commit bf88667

File tree

4 files changed

+230
-20
lines changed

4 files changed

+230
-20
lines changed

Menu/Buttons.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,10 @@ public class Buttons
15561556
new ButtonInfo[] { // Internal Mods (hidden from user) [25]
15571557
new ButtonInfo { buttonText = "Search", method =() => Settings.Search(), isTogglable = false, toolTip = "Lets you search for specific mods."},
15581558
new ButtonInfo { buttonText = "Global Return", method =() => Settings.GlobalReturn(), isTogglable = false, toolTip = "Returns you to the previous category."},
1559-
new ButtonInfo { buttonText = "Debug Screen", method =() => Settings.Debug(), enableMethod =() => Settings.ShowDebug(), disableMethod =() => Settings.HideDebug(), toolTip = "Shows game and modding related information."}
1559+
new ButtonInfo { buttonText = "Debug Screen", method =() => Settings.Debug(), enableMethod =() => Settings.ShowDebug(), disableMethod =() => Settings.HideDebug(), toolTip = "Shows game and modding related information."},
1560+
1561+
new ButtonInfo { buttonText = "Accept Prompt", method =() => { NotifiLib.ClearAllNotifications(); IsPrompting = false; AcceptAction?.Invoke(); }, isTogglable = false},
1562+
new ButtonInfo { buttonText = "Decline Prompt", method =() => { NotifiLib.ClearAllNotifications(); IsPrompting = false; DeclineAction?.Invoke(); }, isTogglable = false}
15601563
},
15611564

15621565
new ButtonInfo[] { // Sound Library [26]

Menu/Main.cs

Lines changed: 200 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ public static void Prefix()
222222
}
223223
}
224224
}
225+
225226
if (buttonCondition && menu != null)
226227
RecenterMenu();
227228

@@ -545,6 +546,9 @@ public static void Prefix()
545546
lastPressedKeys = keysPressed;
546547
}
547548

549+
if (Settings.TutorialObject != null)
550+
Settings.UpdateTutorial();
551+
548552
// Get the camera (compatible with Yizzi)
549553
try
550554
{
@@ -2451,9 +2455,15 @@ public static void Draw()
24512455
if (enableDebugButton)
24522456
AddDebugButton();
24532457

2454-
if (!disablePageButtons)
2458+
if (!disablePageButtons && !IsPrompting)
24552459
AddPageButtons();
24562460

2461+
if (IsPrompting)
2462+
{
2463+
RenderPrompt();
2464+
return;
2465+
}
2466+
24572467
// Button render code
24582468
int buttonIndexOffset = 0;
24592469
ButtonInfo[] renderButtons = new ButtonInfo[] { };
@@ -2830,9 +2840,6 @@ public static void RecenterMenu()
28302840
} else
28312841
isOnPC = false;
28322842

2833-
if (Settings.TutorialObject != null)
2834-
Settings.UpdateTutorial();
2835-
28362843
if (physicalMenu)
28372844
{
28382845
if (physicalOpenPosition == Vector3.zero)
@@ -2928,11 +2935,174 @@ private static void AddPageButtons()
29282935
}
29292936
}
29302937

2931-
private static void CreatePageButtonPair(string prevButtonName, string nextButtonName, Vector3 buttonScale, Vector3 prevButtonPos, Vector3 nextButtonPos, Vector3 prevTextPos, Vector3 nextTextPos, GradientColorKey[] colorKeys, Vector2? textSize = null)
2938+
private static void RenderPrompt()
29322939
{
2933-
GameObject prevButton = CreatePageButton(prevButtonName, buttonScale, prevButtonPos, prevTextPos, colorKeys, textSize, 0);
2940+
Text promptText = new GameObject
2941+
{
2942+
transform =
2943+
{
2944+
parent = canvasObj.transform
2945+
}
2946+
}.AddComponent<Text>();
2947+
promptText.font = activeFont;
2948+
promptText.text = PromptMessage;
2949+
2950+
if (doCustomName)
2951+
promptText.text = customMenuName;
2952+
2953+
if (translate)
2954+
promptText.text = TranslateText(promptText.text, output => ReloadMenu());
2955+
2956+
if (lowercaseMode)
2957+
promptText.text = promptText.text.ToLower();
2958+
2959+
if (uppercaseMode)
2960+
promptText.text = promptText.text.ToUpper();
2961+
2962+
promptText.fontSize = 1;
2963+
promptText.color = titleColor;
2964+
2965+
promptText.supportRichText = true;
2966+
promptText.fontStyle = activeFontStyle;
2967+
promptText.alignment = TextAnchor.MiddleCenter;
2968+
promptText.resizeTextForBestFit = true;
2969+
promptText.resizeTextMinSize = 0;
2970+
RectTransform component = promptText.GetComponent<RectTransform>();
2971+
component.localPosition = Vector3.zero;
2972+
component.sizeDelta = new Vector2(0.28f, 0.28f);
2973+
2974+
component.localPosition = new Vector3(0.06f, 0f, 0f);
2975+
component.rotation = Quaternion.Euler(new Vector3(180f, 90f, 90f));
2976+
2977+
if (outlineText)
2978+
OutlineCanvasObject(promptText);
2979+
2980+
GradientColorKey[] colorKeys = new GradientColorKey[]
2981+
{
2982+
new GradientColorKey(buttonDefaultA, 0f),
2983+
new GradientColorKey(buttonDefaultB, 0.5f),
2984+
new GradientColorKey(buttonDefaultA, 1f)
2985+
};
2986+
2987+
{
2988+
GameObject button = GameObject.CreatePrimitive(PrimitiveType.Cube);
2989+
2990+
if (themeType == 30)
2991+
button.GetComponent<Renderer>().enabled = false;
2992+
2993+
if (!UnityInput.Current.GetKey(KeyCode.Q) && !(isSearching && isPcWhenSearching))
2994+
button.layer = 2;
2995+
2996+
button.GetComponent<BoxCollider>().isTrigger = true;
2997+
button.transform.parent = menu.transform;
2998+
button.transform.rotation = Quaternion.identity;
2999+
button.transform.localScale = new Vector3(0.09f, 0.4375f, 0.08f);
3000+
button.transform.localPosition = new Vector3(0.56f, 0.2375f, -0.43f);
3001+
3002+
button.AddComponent<Classes.Button>().relatedText = "Accept Prompt";
3003+
button.GetComponent<Renderer>().material.color = buttonDefaultA;
3004+
3005+
if (lastClickedName != "Accept Prompt")
3006+
{
3007+
ColorChanger colorChanger = button.AddComponent<ColorChanger>();
3008+
colorChanger.colors = new Gradient { colorKeys = colorKeys };
3009+
}
3010+
else
3011+
CoroutineManager.RunCoroutine(ButtonClick(-99, button.GetComponent<Renderer>()));
3012+
3013+
Text text = new GameObject { transform = { parent = canvasObj.transform } }.AddComponent<Text>();
3014+
text.font = activeFont;
3015+
text.text = AcceptText;
3016+
text.fontSize = 1;
3017+
text.color = textColor;
3018+
text.alignment = TextAnchor.MiddleCenter;
3019+
text.resizeTextForBestFit = true;
3020+
text.resizeTextMinSize = 0;
29343021

2935-
GameObject nextButton = CreatePageButton(nextButtonName, buttonScale, nextButtonPos, nextTextPos, colorKeys, textSize, 1);
3022+
RectTransform textRect = text.GetComponent<RectTransform>();
3023+
textRect.sizeDelta = new Vector2(0.2f, 0.03f);
3024+
3025+
if (arrowType == 11)
3026+
textRect.sizeDelta = new Vector2(textRect.sizeDelta.x, textRect.sizeDelta.y * 6f);
3027+
3028+
if (NoAutoSizeText)
3029+
textRect.sizeDelta = new Vector2(9f, 0.015f);
3030+
3031+
textRect.localPosition = new Vector3(0.064f, 0.075f, -0.16f);
3032+
textRect.rotation = Quaternion.Euler(new Vector3(180f, 90f, 90f));
3033+
3034+
if (outlineText)
3035+
OutlineCanvasObject(text);
3036+
3037+
if (shouldOutline)
3038+
OutlineObj(button, !swapButtonColors);
3039+
3040+
if (shouldRound)
3041+
RoundObj(button);
3042+
}
3043+
3044+
{
3045+
GameObject button = GameObject.CreatePrimitive(PrimitiveType.Cube);
3046+
3047+
if (themeType == 30)
3048+
button.GetComponent<Renderer>().enabled = false;
3049+
3050+
if (!UnityInput.Current.GetKey(KeyCode.Q) && !(isSearching && isPcWhenSearching))
3051+
button.layer = 2;
3052+
3053+
button.GetComponent<BoxCollider>().isTrigger = true;
3054+
button.transform.parent = menu.transform;
3055+
button.transform.rotation = Quaternion.identity;
3056+
button.transform.localScale = new Vector3(0.09f, 0.4375f, 0.08f);
3057+
button.transform.localPosition = new Vector3(0.56f, -0.2375f, -0.43f);
3058+
3059+
button.AddComponent<Classes.Button>().relatedText = "Decline Prompt";
3060+
button.GetComponent<Renderer>().material.color = buttonDefaultA;
3061+
3062+
if (lastClickedName != "Decline Prompt")
3063+
{
3064+
ColorChanger colorChanger = button.AddComponent<ColorChanger>();
3065+
colorChanger.colors = new Gradient { colorKeys = colorKeys };
3066+
}
3067+
else
3068+
CoroutineManager.RunCoroutine(ButtonClick(-99, button.GetComponent<Renderer>()));
3069+
3070+
Text text = new GameObject { transform = { parent = canvasObj.transform } }.AddComponent<Text>();
3071+
text.font = activeFont;
3072+
text.text = DeclineText;
3073+
text.fontSize = 1;
3074+
text.color = textColor;
3075+
text.alignment = TextAnchor.MiddleCenter;
3076+
text.resizeTextForBestFit = true;
3077+
text.resizeTextMinSize = 0;
3078+
3079+
RectTransform textRect = text.GetComponent<RectTransform>();
3080+
textRect.sizeDelta = new Vector2(0.2f, 0.03f);
3081+
3082+
if (arrowType == 11)
3083+
textRect.sizeDelta = new Vector2(textRect.sizeDelta.x, textRect.sizeDelta.y * 6f);
3084+
3085+
if (NoAutoSizeText)
3086+
textRect.sizeDelta = new Vector2(9f, 0.015f);
3087+
3088+
textRect.localPosition = new Vector3(0.064f, -0.075f, -0.16f);
3089+
textRect.rotation = Quaternion.Euler(new Vector3(180f, 90f, 90f));
3090+
3091+
if (outlineText)
3092+
OutlineCanvasObject(text);
3093+
3094+
if (shouldOutline)
3095+
OutlineObj(button, !swapButtonColors);
3096+
3097+
if (shouldRound)
3098+
RoundObj(button);
3099+
}
3100+
}
3101+
3102+
private static void CreatePageButtonPair(string prevButtonName, string nextButtonName, Vector3 buttonScale, Vector3 prevButtonPos, Vector3 nextButtonPos, Vector3 prevTextPos, Vector3 nextTextPos, GradientColorKey[] colorKeys, Vector2? textSize = null)
3103+
{
3104+
GameObject prevButton = AdvancedAddButton(prevButtonName, buttonScale, prevButtonPos, prevTextPos, colorKeys, textSize, 0);
3105+
GameObject nextButton = AdvancedAddButton(nextButtonName, buttonScale, nextButtonPos, nextTextPos, colorKeys, textSize, 1);
29363106

29373107
if (shouldOutline)
29383108
{
@@ -2947,7 +3117,7 @@ private static void CreatePageButtonPair(string prevButtonName, string nextButto
29473117
}
29483118
}
29493119

2950-
private static GameObject CreatePageButton(string buttonName, Vector3 scale, Vector3 position, Vector3 textPosition, GradientColorKey[] colorKeys, Vector2? textSize, int arrowIndex)
3120+
private static GameObject AdvancedAddButton(string buttonName, Vector3 scale, Vector3 position, Vector3 textPosition, GradientColorKey[] colorKeys, Vector2? textSize, int arrowIndex)
29513121
{
29523122
GameObject button = GameObject.CreatePrimitive(PrimitiveType.Cube);
29533123

@@ -2984,7 +3154,6 @@ private static GameObject CreatePageButton(string buttonName, Vector3 scale, Vec
29843154
text.resizeTextMinSize = 0;
29853155

29863156
RectTransform textRect = text.GetComponent<RectTransform>();
2987-
textRect.localPosition = Vector3.zero;
29883157
textRect.sizeDelta = textSize ?? new Vector2(0.2f, 0.03f);
29893158

29903159
if (arrowType == 11)
@@ -3202,6 +3371,25 @@ public static void RoundObj(GameObject toRound, float Bevel = 0.02f)
32023371
ToRoundRenderer.enabled = false;
32033372
}
32043373

3374+
public static bool IsPrompting;
3375+
public static string PromptMessage;
3376+
3377+
public static string AcceptText = "Yes";
3378+
public static string DeclineText = "No";
3379+
3380+
public static Action AcceptAction;
3381+
public static Action DeclineAction;
3382+
3383+
public static void Prompt(string Message, Action Accept = null, Action Decline = null, string AcceptButton = "Yes", string DeclineButton = "No")
3384+
{
3385+
IsPrompting = true;
3386+
PromptMessage = Message;
3387+
AcceptText = AcceptButton;
3388+
DeclineText = DeclineButton;
3389+
AcceptAction = Accept;
3390+
DeclineAction = Decline;
3391+
}
3392+
32053393
private static void LoadAssetBundle()
32063394
{
32073395
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("iiMenu.Resources.iimenu");
@@ -5531,6 +5719,9 @@ public static void OnLaunch()
55315719
if (!Font.GetOSInstalledFontNames().Contains("Agency FB"))
55325720
AgencyFB = LoadAsset<Font>("Agency");
55335721

5722+
if (Plugin.FirstLaunch)
5723+
Prompt("It seems like this is your first time using the menu. Would you like to watch a quick tutorial to get to know how to use it?", () => Settings.ShowTutorial());
5724+
55345725
PhotonNetwork.NetworkingClient.EventReceived += EventReceived;
55355726
SceneManager.sceneLoaded += SceneLoaded;
55365727

Mods/Settings.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using BepInEx;
12
using GorillaLocomotion;
23
using GorillaNetworking;
34
using iiMenu.Classes;
@@ -15,9 +16,11 @@
1516
using System.Net;
1617
using System.Reflection;
1718
using UnityEngine;
19+
using UnityEngine.InputSystem;
1820
using UnityEngine.UI;
1921
using UnityEngine.Video;
2022
using UnityEngine.Windows.Speech;
23+
using UnityEngine.XR;
2124
using static iiMenu.Classes.RigManager;
2225
using static iiMenu.Menu.Main;
2326

@@ -166,6 +169,7 @@ public static void GlobalReturn()
166169
{
167170
NotifiLib.ClearAllNotifications();
168171
Toggle(Buttons.buttons[currentCategoryIndex][0].buttonText, true);
172+
IsPrompting = false;
169173
}
170174

171175
public static GameObject TutorialObject;
@@ -181,8 +185,9 @@ public static void ShowTutorial()
181185
TutorialObject.transform.rotation = GorillaTagger.Instance.bodyCollider.transform.rotation * Quaternion.Euler(0f, 180f, 0f);
182186

183187
VideoPlayer videoPlayer = TutorialObject.transform.Find("Video").GetComponent<VideoPlayer>();
184-
videoPlayer.url = $"https://github.com/iiDk-the-actual/ModInfo/raw/main/tutorial-q{(ControllerInputPoller.instance.leftControllerDevice.name.ToLower().Contains("quest2") ? "2" : "3")}.mp4";
185-
188+
videoPlayer.url = $"https://github.com/iiDk-the-actual/ModInfo/raw/main/tutorial-q{(XRSettings.isDeviceActive && ControllerInputPoller.instance.leftControllerDevice.name.ToLower().Contains("quest2") ? "2" : "3")}.mp4";
189+
videoPlayer.isLooping = true;
190+
186191
videoPlayer.AddComponent<TutorialButton>().buttonType = TutorialButton.ButtonType.Pause;
187192

188193
TutorialObject.transform.Find("Close").AddComponent<TutorialButton>().buttonType = TutorialButton.ButtonType.Close;
@@ -191,7 +196,7 @@ public static void ShowTutorial()
191196
private static bool lastTrigger;
192197
public static void UpdateTutorial()
193198
{
194-
if (Vector3.Distance(VRKeyboard.transform.position, GorillaTagger.Instance.bodyCollider.transform.position) > menuScale)
199+
if (Vector3.Distance(TutorialObject.transform.position, GorillaTagger.Instance.bodyCollider.transform.position) > 2f)
195200
{
196201
TutorialObject.transform.position = GorillaTagger.Instance.bodyCollider.transform.position + GorillaTagger.Instance.bodyCollider.transform.forward * 1f + Vector3.up * 0.25f;
197202
TutorialObject.transform.rotation = GorillaTagger.Instance.bodyCollider.transform.rotation * Quaternion.Euler(0f, 180f, 0f);
@@ -202,8 +207,8 @@ public static void UpdateTutorial()
202207
TutorialSelector = new GameObject("iiMenu_TutorialSelector").AddComponent<LineRenderer>();
203208
TutorialSelector.material.shader = Shader.Find("Sprites/Default");
204209

205-
TutorialSelector.startWidth = 0.025f;
206-
TutorialSelector.endWidth = 0.025f;
210+
TutorialSelector.startWidth = 0.01f;
211+
TutorialSelector.endWidth = 0.01f;
207212

208213
TutorialSelector.positionCount = 2;
209214

@@ -213,19 +218,24 @@ public static void UpdateTutorial()
213218
TutorialSelector.startColor = BrightenColor(GetBGColor(0f));
214219
TutorialSelector.endColor = BrightenColor(GetBGColor(0.5f));
215220

216-
Physics.Raycast(GorillaTagger.Instance.rightHandTransform.position + ((-GorillaTagger.Instance.rightHandTransform.up / 4f) * (scaleWithPlayer ? GTPlayer.Instance.scale : 1f)), GorillaTagger.Instance.rightHandTransform.up, out var Ray, 512f, NoInvisLayerMask());
221+
Physics.Raycast(GorillaTagger.Instance.rightHandTransform.position + (-GorillaTagger.Instance.rightHandTransform.up / 4f), GorillaTagger.Instance.rightHandTransform.up, out var Ray, 512f, NoInvisLayerMask());
222+
if (!XRSettings.isDeviceActive)
223+
{
224+
Ray ray = TPC.ScreenPointToRay(Mouse.current.position.ReadValue());
225+
Physics.Raycast(ray, out Ray, 512f, NoInvisLayerMask());
226+
}
217227

218228
TutorialSelector.SetPosition(0, GorillaTagger.Instance.rightHandTransform.position);
219-
TutorialSelector.SetPosition(1, Ray.point);
229+
TutorialSelector.SetPosition(1, Ray.point == Vector3.zero ? GorillaTagger.Instance.rightHandTransform.position : Ray.point);
220230

221-
if (rightTrigger > 0.5f && !lastTrigger)
231+
if ((rightTrigger > 0.5f || Mouse.current.leftButton.isPressed) && !lastTrigger)
222232
{
223233
TutorialButton gunTarget = Ray.collider.GetComponentInParent<TutorialButton>();
224234
if (gunTarget)
225235
gunTarget.ClickButton();
226236
}
227237

228-
lastTrigger = rightTrigger > 0.5f;
238+
lastTrigger = rightTrigger > 0.5f || Mouse.current.leftButton.isPressed;
229239
}
230240

231241
public class TutorialButton : MonoBehaviour
@@ -3340,6 +3350,12 @@ public static void LoadPreferences()
33403350
{
33413351
try
33423352
{
3353+
if (!File.Exists($"{PluginInfo.BaseDirectory}/iiMenu_Preferences.txt"))
3354+
{
3355+
hasLoadedPreferences = true;
3356+
return;
3357+
}
3358+
33433359
string text = File.ReadAllText($"{PluginInfo.BaseDirectory}/iiMenu_Preferences.txt");
33443360
LoadPreferencesFromText(text);
33453361
} catch (Exception e) { LogManager.Log("Error loading preferences: " + e.Message); }

PluginInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public class PluginInfo
55
public const string GUID = "org.iidk.gorillatag.iimenu";
66
public const string Name = "ii's Stupid Menu";
77
public const string Description = "Created by @goldentrophy with love <3";
8-
public const string BuildTimestamp = "2025-08-09T01:50:28Z";
8+
public const string BuildTimestamp = "2025-08-09T03:56:58Z";
99
public const string Version = "6.8.1";
1010

1111
public const string BaseDirectory = "iisStupidMenu";

0 commit comments

Comments
 (0)