diff --git a/PreviewScroller/PreviewScroller.csproj b/PreviewScroller/PreviewScroller.csproj new file mode 100644 index 0000000..04b1da4 --- /dev/null +++ b/PreviewScroller/PreviewScroller.csproj @@ -0,0 +1,40 @@ + + + + net472 + PreviewScroller + PreviewScroller + + + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Assembly-CSharp.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Il2Cppmscorlib.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Il2CppSystem.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\Il2CppSystem.Core.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\MelonLoader.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnhollowerBaseLib.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.CoreModule.dll + + + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.UI.dll + + + + + + + + \ No newline at end of file diff --git a/PreviewScroller/PreviewScrollerMod.cs b/PreviewScroller/PreviewScrollerMod.cs new file mode 100644 index 0000000..cb8b92b --- /dev/null +++ b/PreviewScroller/PreviewScrollerMod.cs @@ -0,0 +1,92 @@ +using System; +using System.Linq; +using System.Reflection; +using Harmony; +using MelonLoader; +using UnhollowerRuntimeLib; +using UnityEngine; +using UnityEngine.UI; +using VRC.UI; + +[assembly: MelonInfo(typeof(PreviewScroller.PreviewScrollerMod), "PreviewScroller", "0.0.1", "loukylor", "https://github.com/loukylor/VRC-Mods")] +[assembly: MelonGame("VRChat", "VRChat")] + +namespace PreviewScroller +{ + public class PreviewScrollerMod : MelonMod + { + public override void VRChat_OnUiManagerInit() + { + foreach (MethodInfo method in typeof(PageAvatar).GetMethods().Where(mi => mi.Name.StartsWith("Method_Private_Void_String_GameObject_AvatarPerformanceStats_"))) + Harmony.Patch(method, null, new HarmonyMethod(typeof(PreviewScrollerMod).GetMethod(nameof(OnPedestalAvatarInstantiated), BindingFlags.NonPublic | BindingFlags.Static))); + GameObject scrollerContainer = new GameObject("ScrollerContainer", new UnhollowerBaseLib.Il2CppReferenceArray(new Il2CppSystem.Type[2] { Il2CppType.Of(), Il2CppType.Of() })); + RectTransform scrollerContainerRect = scrollerContainer.GetComponent(); + scrollerContainerRect.SetParent(GameObject.Find("UserInterface/MenuContent/Screens/Avatar").transform); + scrollerContainerRect.anchoredPosition3D = new Vector3(-565, 20, 1); + scrollerContainerRect.localScale = Vector3.one; + scrollerContainerRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 400); + scrollerContainerRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 650); + + GameObject scrollerContent = new GameObject("ScrollerContent", new UnhollowerBaseLib.Il2CppReferenceArray(new Il2CppSystem.Type[2] { Il2CppType.Of(), Il2CppType.Of() })); + RectTransform scrollerContentRect = scrollerContent.GetComponent(); + scrollerContentRect.SetParent(scrollerContainerRect); + + scrollerContentRect.anchoredPosition3D = Vector3.zero; + scrollerContentRect.localScale = Vector3.one; + scrollerContentRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 800); + scrollerContentRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 1300); + //scrollerContentRect.GetComponent().sprite = GameObject.Find("UserInterface/QuickMenu/UIElementsMenu/NameplatesOnButton").GetComponent().sprite; + scrollerContentRect.GetComponent().color = new Color(0, 0, 0, 0); + + ScrollRect scrollRect = scrollerContainer.AddComponent(); + scrollRect.content = scrollerContentRect; + scrollRect.movementType = ScrollRect.MovementType.Unrestricted; + scrollRect.decelerationRate = 0.03f; + scrollRect.onValueChanged = new ScrollRect.ScrollRectEvent(); + GameObject pedestal = GameObject.Find("UserInterface/MenuContent/Screens/Avatar/AvatarPreviewBase/MainRoot/MainModel"); + pedestal.transform.localPosition += new Vector3(0, 0.5f); + MonoBehaviour autoTurn = pedestal.GetComponents().First(c => c.GetIl2CppType().FullName == "UnityStandardAssets.Utility.AutoMoveAndRotate"); + UnityEngine.Object.DestroyImmediate(autoTurn); + + Vector2 lastPos = Vector2.zero; + + scrollRect.onValueChanged.AddListener(new Action((pos) => + { + Vector2 velocity = pos - lastPos; + + lastPos = pos; + Vector2 scrollRectVelocity = scrollRect.velocity; + if (scrollRect.verticalNormalizedPosition > 1 && velocity.y > 0) + { + scrollRect.verticalNormalizedPosition = 0; + lastPos.y = 0; + } + else if (scrollRect.verticalNormalizedPosition < 0 && velocity.y < 0) + { + scrollRect.verticalNormalizedPosition = 1; + lastPos.y = 1; + } + if (scrollRect.horizontalNormalizedPosition > 1 && velocity.x > 0) + { + scrollRect.horizontalNormalizedPosition = 0; + lastPos.x = 0; + } + else if (scrollRect.horizontalNormalizedPosition < 0 && velocity.x < 0) + { + scrollRect.horizontalNormalizedPosition = 1; + lastPos.x = 1; + } + pedestal.transform.Rotate(new Vector2(velocity.normalized.y, velocity.normalized.x), velocity.magnitude * 375 * Time.deltaTime); + pedestal.transform.parent.localPosition = new Vector3(0, -0.5f); + scrollRect.velocity = scrollRectVelocity; + })); + } + private static void OnPedestalAvatarInstantiated(GameObject __1) + { + if (__1 == null) return; + + __1.transform.localPosition = new Vector3(0, -0.5f); + __1.transform.parent.localRotation = new Quaternion(); + } + } +} diff --git a/README.md b/README.md index df8f644..b4f1455 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ More detailed instructions and more mods can be found in the [VRChat Modding Gro - [CloningBeGone](#cloningbegone) - [InstanceHistory](#instancehistory) - [PlayerList](#playerlist) +- [PreviewScroller](#previewscroller) - [ReloadAvatars](#reloadavatars) - [UserInfoExtensions](#userinfoextensions) @@ -99,6 +100,9 @@ Oh yea, also report any errors to me. You can make an issue or ping/DM me. ## Picture of List ![Picture of List](https://i.imgur.com/Tt6ZYqB.png) +# PreviewScroller +A mod that let's you sort of scroll the avatar preview so you can control where it's facing + # ReloadAvatars Adds buttons to reload a single user's avatar or all users' avatar.