├── .gitignore
├── LICENSE
├── Loading screen pictures
├── Loading screen pictures.csproj
└── LoadingScreenPictures.cs
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Loading screen pictures/bin/
2 | Loading screen pictures/obj/
3 | .vs/
4 | Loading screen pictures.sln
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright 2021 (C) MarkViews
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this
6 | software and associated documentation files (the "Software"), to deal in the Software
7 | without restriction, including without limitation the rights to use, copy, modify,
8 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Loading screen pictures/Loading screen pictures.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {D4CF15C8-47C6-452B-9082-1DAB52F33964}
8 | Library
9 | Loading_screen_pictures
10 | LoadingScreenPictures
11 | v4.7.2
12 | 512
13 | true
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 | False
35 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Assembly-CSharp.dll
36 |
37 |
38 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Il2Cppmscorlib.dll
39 |
40 |
41 | False
42 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\MelonLoader.dll
43 |
44 |
45 |
46 |
47 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnhollowerBaseLib.dll
48 |
49 |
50 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.CoreModule.dll
51 |
52 |
53 | False
54 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.ImageConversionModule.dll
55 |
56 |
57 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.PhysicsModule.dll
58 |
59 |
60 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\VRCCore-Editor.dll
61 |
62 |
63 | ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\VRCCore-Standalone.dll
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Loading screen pictures/LoadingScreenPictures.cs:
--------------------------------------------------------------------------------
1 | using Il2CppSystem;
2 | using MelonLoader;
3 | using System.IO;
4 | using UnityEngine;
5 | using Loading_screen_pictures;
6 | using System.Linq;
7 | using System.Collections;
8 |
9 | [assembly: MelonInfo(typeof(LoadingScreenPictures), "Loading Screen Pictures", "1.3.2", "MarkViews", "https://github.com/markviews/LoadingScreenPictures")]
10 | [assembly: MelonGame("VRChat", "VRChat")]
11 |
12 | namespace Loading_screen_pictures {
13 | internal class LoadingScreenPictures : MelonMod {
14 |
15 | private GameObject mainFrame;
16 | private GameObject cube;
17 | private Texture lastTexture;
18 | private Renderer screenRender, pic;
19 | private string folder_dir;
20 | private bool initUI = false;
21 | private bool enabled = true;
22 | private Vector3 originalSize;
23 |
24 | public override void OnApplicationStart() {
25 | MelonCoroutines.Start(UiManagerInitializer());
26 | string default_dir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + @"\VRChat";
27 | MelonPreferences.CreateCategory("LoadingScreenPictures", "Loading Screen Pictures");
28 | MelonPreferences.CreateEntry("LoadingScreenPictures", "directory", default_dir, "Folder to get pictures from");
29 | MelonPreferences.CreateEntry("LoadingScreenPictures", "enabled", true, "Enable");
30 | folder_dir = MelonPreferences.GetEntryValue("LoadingScreenPictures", "directory");
31 | enabled = MelonPreferences.GetEntryValue("LoadingScreenPictures", "enabled");
32 |
33 | if (default_dir != folder_dir && !Directory.Exists(folder_dir)) {
34 | folder_dir = default_dir;
35 | MelonLogger.Msg("Couldn't find configured directory, using default directory");
36 | }
37 | }
38 |
39 | public IEnumerator UiManagerInitializer() {
40 | while (VRCUiManager.prop_VRCUiManager_0 == null) yield return null;
41 | setup();
42 | initUI = true;
43 | }
44 |
45 | public override void OnPreferencesSaved() {
46 | enabled = MelonPreferences.GetEntryValue("LoadingScreenPictures", "enabled");
47 | if (enabled) setup();
48 | else disable();
49 | }
50 |
51 | private float wait = 0.0f;
52 | private bool hidden = false;
53 |
54 | public override void OnUpdate() {
55 | if (!enabled) return;
56 |
57 | if (Time.time > wait) {
58 | wait += 5f;
59 | if (hidden) {
60 | hidden = false;
61 | setup();
62 | }
63 | }
64 |
65 | if (lastTexture == null) return;
66 | if (lastTexture == screenRender.material.mainTexture) return;
67 | lastTexture = screenRender.material.mainTexture;
68 | changePic();
69 | }
70 |
71 | public override void OnSceneWasInitialized(int buildIndex, string sceneName) {
72 | switch (buildIndex) {
73 | case 1:
74 | case 2:
75 | break;
76 | default: //Causes this to run only once instead of multiple times.
77 | if (initUI && lastTexture == null)
78 | setup();
79 | break;
80 | }
81 | }
82 |
83 | private void changePic() {
84 | Texture2D texture = new Texture2D(2, 2);
85 | ImageConversion.LoadImage(texture, File.ReadAllBytes(randImage()));
86 | pic.material.mainTexture = texture;
87 | if (pic.material.mainTexture.height > pic.material.mainTexture.width) {
88 | cube.transform.localScale = new Vector3(0.099f, 1, 0.175f);
89 | mainFrame.transform.localScale = new Vector3(10.80f, 19.20f, 1);
90 | } else {
91 | cube.transform.localScale = new Vector3(0.175f, 1, 0.099f);
92 | mainFrame.transform.localScale = new Vector3(19.20f, 10.80f, 1);
93 | }
94 | }
95 |
96 | private void disable() {
97 | MelonLogger.Msg("Disabled");
98 | if (mainFrame) mainFrame.transform.localScale = originalSize;
99 | if (screenRender) screenRender.enabled = true;
100 | if (cube) GameObject.Destroy(cube);
101 | lastTexture = null;
102 | }
103 |
104 | private void setup() {
105 | if (!enabled || lastTexture != null) return;
106 | mainFrame = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel/InfoPanel_Template_ANIM/SCREEN/mainFrame");
107 | originalSize = mainFrame.transform.localScale;
108 |
109 | GameObject screen = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel/InfoPanel_Template_ANIM/SCREEN/mainScreen");
110 | //check if screenshots folder is empty
111 | String imageLink = randImage();
112 | if (imageLink == null) {
113 | MelonLogger.Msg("No screenshots found in: " + folder_dir);
114 | return;
115 | }
116 |
117 | GameObject parentScreen = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel/InfoPanel_Template_ANIM/SCREEN");
118 | screenRender = screen.GetComponent();
119 | lastTexture = screenRender.material.mainTexture;
120 |
121 | //create new image
122 | cube = GameObject.CreatePrimitive(PrimitiveType.Plane);
123 | cube.transform.SetParent(parentScreen.transform);
124 | cube.transform.rotation = screen.transform.rotation;
125 | cube.transform.localPosition = new Vector3(0, 0, -0.19f);
126 | cube.GetComponent().enabled = false;
127 | cube.layer = LayerMask.NameToLayer("InternalUI");
128 | Texture2D texture = new Texture2D(2, 2);
129 | ImageConversion.LoadImage(texture, File.ReadAllBytes(imageLink));
130 | pic = cube.GetComponent();
131 | pic.material.mainTexture = texture;
132 |
133 | //disable origial picture
134 | screenRender.enabled = false;
135 |
136 | //resize frame
137 | if (pic.material.mainTexture.height > pic.material.mainTexture.width) {
138 | cube.transform.localScale = new Vector3(0.099f, 1, 0.175f);
139 | mainFrame.transform.localScale = new Vector3(10.80f, 19.20f, 1);
140 | } else {
141 | cube.transform.localScale = new Vector3(0.175f, 1, 0.099f);
142 | mainFrame.transform.localScale = new Vector3(19.20f, 10.80f, 1);
143 | }
144 |
145 | //hide icon and title
146 | GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel/InfoPanel_Template_ANIM/ICON").active = false;
147 | GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel/InfoPanel_Template_ANIM/TITLE").active = false;
148 |
149 | MelonLogger.Msg("Setup Game Objects.");
150 | }
151 |
152 | private String randImage() {
153 | if (!Directory.Exists(folder_dir)) return null;
154 | string[] pics = Directory.GetFiles(folder_dir, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".png") || s.EndsWith(".jpeg")).ToArray();
155 | if (pics.Length == 0) return null;
156 | int randPic = new Il2CppSystem.Random().Next(0, pics.Length);
157 | return pics[randPic].ToString();
158 | }
159 |
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Loading Screen Pictures
2 | Replaces the tips in the loading screen with pictures from your VRChat screenshots folder!
3 |
4 |
5 | ### How to use
6 | 1. Download and install [MelonLoader](https://melonwiki.xyz/#/README)
7 | 2. Download [LoadingScreenPictures.dll](https://github.com/markviews/LoadingScreenPictures/releases)
8 | 3. Drag `LoadingScreenPictures.dll` into `VRChat/Mods`
9 | 4. Screenshots you take in game will show up in your loading screen!
10 |
11 | ### Notes
12 | * You can change the directory images are searched for in `VRChat/UserData/modprefs.ini`
13 | * Compatible with PhotoOrganization mod (searches subfolders)
14 | * Reads `.png` and `.jpeg` files
15 |
16 | 
17 |
18 | ### Credits
19 | * HeyImRuu for adding vertical photo support
20 | * Arion-Kun for helping with error catching and optimization
21 |
--------------------------------------------------------------------------------