Last active
April 27, 2023 02:09
-
-
Save ShayBox/fdeb46ceeef3420aa962d0ee7ea900f3 to your computer and use it in GitHub Desktop.
My custom VRChat avatar upload tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
using UnityEngine.UI; | |
using VRC.SDK3.Avatars.Components; | |
using VRC.SDKBase.Editor; | |
namespace ShayBox { | |
public class ShaysUploadTool : EditorWindow { | |
#if UNITY_STANDALONE_WIN | |
public static readonly string PLATFORM = "PC"; | |
public static readonly string SUFFIX = " (PC)"; | |
#elif UNITY_ANDROID | |
public static readonly string PLATFORM = "Quest"; | |
public static readonly string SUFFIX = " (Quest)"; | |
#endif | |
[MenuItem(itemName: "Window/Shays Upload Tool")] | |
public static void ShowWindow() => GetWindow<ShaysUploadTool>(title: "Shays Upload Tool"); | |
public void OnEnable() => EditorApplication.playModeStateChanged += PlayModeStateChanged; | |
public void OnDisable() => EditorApplication.playModeStateChanged -= PlayModeStateChanged; | |
public bool isWaitingForPlaymode = false; | |
public void PlayModeStateChanged(PlayModeStateChange state) | |
{ | |
if (state is PlayModeStateChange.EnteredEditMode) | |
{ | |
isWaitingForPlaymode = false; | |
} | |
} | |
public GameObject uploadObject = null; | |
// Window Render Loop | |
public void OnGUI() { | |
// Variables | |
Scene scene = SceneManager.GetActiveScene(); | |
GameObject[] sceneAvatarObjects = scene.GetRootGameObjects() | |
.SelectMany(obj => obj.GetComponentsInChildren<VRCAvatarDescriptor>(includeInactive: false)) | |
.Select(obj => obj.gameObject) | |
.Distinct() | |
.ToArray(); | |
// Pre-conditions | |
if (sceneAvatarObjects.Length < 1) { | |
GUILayout.Label(text: "No Avatars Found"); | |
return; | |
} | |
foreach (GameObject obj in sceneAvatarObjects) { | |
if (GUILayout.Button(text: "Build & Upload " + obj.name)) { | |
isWaitingForPlaymode = true; | |
uploadObject = obj; | |
VRC_SdkBuilder.RunExportAndUploadAvatarBlueprint(obj); | |
} | |
} | |
} | |
// Game Update Loop | |
public void Update() { | |
if (EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) { | |
// Play Mode | |
// Wait for VRCSDK to load | |
if (Time.frameCount < 500 && isWaitingForPlaymode) { | |
return; | |
} | |
// Variables | |
Scene scene = SceneManager.GetActiveScene(); | |
GameObject[] sceneObjects = scene.GetRootGameObjects(); | |
GameObject VRCSDK = sceneObjects.Where(predicate: obj => obj.name.Equals(value: "VRCSDK")).First(); | |
// Pre-conditions | |
if (VRCSDK == null) { | |
GUILayout.Label(text: "No VRCSDK Found"); | |
return; | |
} | |
Toggle[] toggles = VRCSDK.GetComponentsInChildren<Toggle>(); | |
InputField[] inputFields = VRCSDK.GetComponentsInChildren<InputField>(); | |
string input = uploadObject.name.Replace(oldValue: SUFFIX, newValue: ""); | |
if (Time.frameCount == 500) | |
{ | |
toggles.First(predicate: t => t.name.Equals(value: "ToggleWarrant")).isOn = true; | |
inputFields.First(predicate: f => f.name.Equals(value: "Name Input Field")).SetTextWithoutNotify(input); | |
inputFields.First(predicate: f => f.name.Equals(value: "Description Input Field")).SetTextWithoutNotify(input); | |
} | |
if (PLATFORM == "PC") { | |
GameObject gestureManager = sceneObjects.First(predicate: obj => obj.name.Equals(value: "GestureManager")); | |
if (gestureManager != null) { | |
Selection.SetActiveObjectWithContext(obj: gestureManager, context: null); | |
} | |
GameObject VRCCam = sceneObjects.First(predicate: obj => obj.name.Equals(value: "VRCCam")); | |
if (VRCCam == null) { | |
GUILayout.Label(text: "No VRCCam Found"); | |
return; | |
} | |
Animator animator = uploadObject.GetComponent<Animator>(); | |
Transform headTransform = animator.GetBoneTransform(humanBoneId: HumanBodyBones.Head); | |
VRCCam.transform.position = new Vector3(x: headTransform.position.x, y: headTransform.position.y, z: headTransform.localScale.z); | |
} | |
if (Time.frameCount == 600 && isWaitingForPlaymode) | |
{ | |
if (PLATFORM == "PC") | |
{ | |
toggles.First(predicate: t => t.name.Equals(value: "ImageUploadToggle")).isOn = true; | |
} | |
isWaitingForPlaymode = false; | |
Button[] buttons = VRCSDK.GetComponentsInChildren<Button>(includeInactive: true); | |
buttons.First(predicate: b => b.name.Equals(value: "UploadButton")).onClick.Invoke(); | |
} | |
} else if (uploadObject != null) { | |
// Edit Mode | |
uploadObject.SetActive(value: false); | |
uploadObject = null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment