Add VRChat and GitHub packages to Unity project
This commit is contained in:
1 parent
0334a52b21
commit
85538aaccc
3297 files changed
+847877
No files matched your search
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02cde43b860294140a44ee8e3f228987
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Copyright 2014-2015 Amazon.com,
|
||||
// Inc. or its affiliates. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the AWS Mobile SDK For Unity
|
||||
// Sample Application License Agreement (the "License").
|
||||
// You may not use this file except in compliance with the
|
||||
// License. A copy of the License is located
|
||||
// in the "license" file accompanying this file. This file is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, express or implied. See the License
|
||||
// for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Amazon.Runtime;
|
||||
using System.IO;
|
||||
using System;
|
||||
using Amazon.S3.Util;
|
||||
using System.Collections.Generic;
|
||||
using Amazon.CognitoIdentity;
|
||||
using Amazon;
|
||||
|
||||
public class S3Manager : MonoBehaviour
|
||||
{
|
||||
public string IdentityPoolId = "us-east-1:066cd25b-b249-4394-a267-7a49247aa8f9"; // vrchat identity pool id
|
||||
public string CognitoIdentityRegion = RegionEndpoint.USEast1.SystemName;
|
||||
private RegionEndpoint _CognitoIdentityRegion
|
||||
{
|
||||
get { return RegionEndpoint.GetBySystemName(CognitoIdentityRegion); }
|
||||
}
|
||||
public string S3Region = RegionEndpoint.USEast1.SystemName;
|
||||
private RegionEndpoint _S3Region
|
||||
{
|
||||
get { return RegionEndpoint.GetBySystemName(S3Region); }
|
||||
}
|
||||
public string S3BucketName = "vrc-uploads"; // vrchat
|
||||
|
||||
|
||||
private IAmazonS3 _s3Client;
|
||||
private AWSCredentials _credentials;
|
||||
|
||||
private AWSCredentials Credentials
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_credentials == null)
|
||||
_credentials = new CognitoAWSCredentials(IdentityPoolId, _CognitoIdentityRegion);
|
||||
return _credentials;
|
||||
}
|
||||
}
|
||||
|
||||
private IAmazonS3 Client
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_s3Client == null)
|
||||
{
|
||||
_s3Client = new AmazonS3Client(Credentials, _S3Region);
|
||||
}
|
||||
//test comment
|
||||
return _s3Client;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
UnityInitializer.AttachToGameObject(this.gameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post Object to S3 Bucket.
|
||||
/// </summary>
|
||||
public PostObjectRequest PostObject(string filePath, string s3FolderName, Action<string> onSuccess = null)
|
||||
{
|
||||
string fileName = s3FolderName + "/" + System.IO.Path.GetFileName(filePath);
|
||||
VRC.Core.Logger.Log ("uploading " + fileName, VRC.Core.DebugLevel.All);
|
||||
|
||||
AWSConfigs.LoggingConfig.LogTo = LoggingOptions.None;
|
||||
|
||||
var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
VRC.Core.Logger.Log ("Creating request object", VRC.Core.DebugLevel.All);
|
||||
|
||||
var request = new PostObjectRequest()
|
||||
{
|
||||
Bucket = S3BucketName,
|
||||
Key = fileName,
|
||||
InputStream = stream,
|
||||
CannedACL = S3CannedACL.Private
|
||||
};
|
||||
|
||||
VRC.Core.Logger.Log ("Making HTTP post call", VRC.Core.DebugLevel.All);
|
||||
|
||||
StartCoroutine(PostObjectRoutine(request, onSuccess));
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
IEnumerator PostObjectRoutine(PostObjectRequest request, Action<string> onSuccess)
|
||||
{
|
||||
// make sure UnityInitializer call has time to initialize
|
||||
yield return null;
|
||||
yield return null;
|
||||
|
||||
Client.PostObjectAsync(request, (responseObj) =>
|
||||
{
|
||||
if (responseObj.Exception == null)
|
||||
{
|
||||
VRC.Core.Logger.Log("object " + responseObj.Request.Key + " posted to bucket " + responseObj.Request.Bucket, VRC.Core.DebugLevel.All);
|
||||
string s3Url = string.Format("https://s3-us-west-2.amazonaws.com/{0}/{1}", responseObj.Request.Bucket, responseObj.Request.Key);
|
||||
if(onSuccess != null)
|
||||
onSuccess(s3Url);
|
||||
}
|
||||
else
|
||||
{
|
||||
VRC.Core.Logger.Log ("Exception while posting the result object");
|
||||
VRC.Core.Logger.Log("receieved error " + responseObj.Response.HttpStatusCode.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d6a1d7b0624f414ba6fb922687a06da
|
||||
timeCreated: 1480975716
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 059f8224659cefb4fa29c1c01d87a653
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daf80f83bd8638d4886542fc3230e9f6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#if VRC_SDK_PIPELINE_SAMPLES
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
namespace VRC.SDKBase.Editor.BuildPipeline.Samples
|
||||
{
|
||||
public class VRCSDKBuildRequestedCallbackSample : IVRCSDKBuildRequestedCallback
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public bool OnBuildRequested(VRCSDKRequestedBuildType requestedBuildType)
|
||||
{
|
||||
return EditorUtility.DisplayDialog("Build Confirmation", "Are you sure you want to build?", "Yes", "Not Yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a1d20f4241085e46bdddc71b691465b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "VRC.SDKBase.Editor.BuildPipeline",
|
||||
"references": [],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21332e1f0d937794d916d2402ba1943a
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 095dab1d766b9f74ea16555fc915be80
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using VRC.Core;
|
||||
|
||||
[CustomEditor(typeof(ApiCache))]
|
||||
public class ApiCacheEditor : Editor {
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
foreach (System.Type type in ApiCache.cache.Keys)
|
||||
{
|
||||
Dictionary<string, ApiCache.CacheEntry> typeCache = ApiCache.cache[type];
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(type.Name);
|
||||
EditorGUILayout.LabelField(typeCache.Count.ToString());
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39cdf3092ab81be4b9e623cb5a8819d8
|
||||
timeCreated: 1509575680
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,218 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using VRC.SDKBase;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class AutoAddSpatialAudioComponents
|
||||
{
|
||||
|
||||
public static bool Enabled = true;
|
||||
|
||||
static AutoAddSpatialAudioComponents()
|
||||
{
|
||||
EditorApplication.hierarchyChanged += OnHierarchyWindowChanged;
|
||||
EditorApplication.projectChanged += OnProjectWindowChanged;
|
||||
RegisterCallbacks();
|
||||
}
|
||||
|
||||
static void OnHierarchyWindowChanged()
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged;
|
||||
return;
|
||||
}
|
||||
|
||||
// check for proper use of VRCSP, and warn
|
||||
//TryToAddSpatializationToAllAudioSources(true, false);
|
||||
}
|
||||
|
||||
static void OnProjectWindowChanged()
|
||||
{
|
||||
RegisterCallbacks();
|
||||
}
|
||||
|
||||
static void RegisterCallbacks()
|
||||
{
|
||||
VRCSdkControlPanel._EnableSpatialization = VRCSDKControlPanel_EnableSpatialization;
|
||||
}
|
||||
|
||||
// callback from VrcSdkControlPanel in dll
|
||||
public static void VRCSDKControlPanel_EnableSpatialization()
|
||||
{
|
||||
Debug.Log("Enabling spatialization on 3D AudioSources...");
|
||||
TryToAddSpatializationToAllAudioSources(false, true);
|
||||
}
|
||||
|
||||
static bool ApplyDefaultSpatializationToAudioSource(AudioSource audioSrc, bool force = false)
|
||||
{
|
||||
if (audioSrc == null)
|
||||
return false;
|
||||
|
||||
var vrcsp = audioSrc.gameObject.GetComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
|
||||
// don't make changes if we already have a vrcsp and we aren't forcing
|
||||
if (vrcsp != null && !force)
|
||||
return false;
|
||||
|
||||
if (force)
|
||||
audioSrc.spatialBlend = 1;
|
||||
|
||||
bool initValues = force;
|
||||
|
||||
// is audio source set to be 2D?
|
||||
bool is2D = audioSrc.spatialBlend == 0;
|
||||
|
||||
if (vrcsp == null)
|
||||
{
|
||||
// no onsp and no vrcsp, so add
|
||||
vrcsp = audioSrc.gameObject.AddComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
if (is2D)
|
||||
{
|
||||
// this audio source was marked as 2D, leave the vrcsp disabled
|
||||
vrcsp.EnableSpatialization = false;
|
||||
}
|
||||
initValues = true;
|
||||
}
|
||||
|
||||
audioSrc.spatialize = vrcsp.EnableSpatialization;
|
||||
vrcsp.enabled = true;
|
||||
|
||||
if (initValues)
|
||||
{
|
||||
bool isAvatar = audioSrc.GetComponentInParent<VRC.SDKBase.VRC_AvatarDescriptor>();
|
||||
|
||||
vrcsp.Gain = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxGain : VRCSDK2.AudioManagerSettings.RoomAudioGain;
|
||||
vrcsp.Near = 0;
|
||||
vrcsp.Far = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxRange : VRCSDK2.AudioManagerSettings.RoomAudioMaxRange;
|
||||
vrcsp.UseAudioSourceVolumeCurve = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void TryToAddSpatializationToAllAudioSources(bool newAudioSourcesOnly, bool includeInactive)
|
||||
{
|
||||
AudioSource[] allAudioSources = includeInactive ? Resources.FindObjectsOfTypeAll<AudioSource>() : Object.FindObjectsOfType<AudioSource>();
|
||||
foreach (AudioSource src in allAudioSources)
|
||||
{
|
||||
if (src == null || src.gameObject == null || src.gameObject.scene != UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newAudioSourcesOnly)
|
||||
{
|
||||
if (!IsNewAudioSource(src))
|
||||
continue;
|
||||
|
||||
UnityEngine.Audio.AudioMixerGroup mixer = AssetDatabase.LoadAssetAtPath<UnityEngine.Audio.AudioMixerGroup>("Assets/VRCSDK/Dependencies/OSPNative/scenes/mixers/SpatializerMixer.mixer");
|
||||
if (mixer != null)
|
||||
{
|
||||
src.outputAudioMixerGroup = mixer;
|
||||
}
|
||||
}
|
||||
|
||||
if (ApplyDefaultSpatializationToAudioSource(src, false))
|
||||
{
|
||||
Debug.Log("Automatically added VRC_SpatialAudioSource component to " + GetGameObjectPath(src.gameObject) + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsNewAudioSource(AudioSource src)
|
||||
{
|
||||
var vrcsp = src.GetComponent<VRC_SpatialAudioSource>();
|
||||
if (vrcsp != null)
|
||||
return false;
|
||||
|
||||
if (src.clip != null)
|
||||
return false;
|
||||
if (src.outputAudioMixerGroup != null)
|
||||
return false;
|
||||
|
||||
if (src.mute || src.bypassEffects || src.bypassReverbZones || !src.playOnAwake || src.loop)
|
||||
return false;
|
||||
|
||||
if (src.priority != 128 ||
|
||||
!Mathf.Approximately(src.volume, 1.0f) ||
|
||||
!Mathf.Approximately(src.pitch, 1.0f) ||
|
||||
!Mathf.Approximately(src.panStereo, 0.0f) ||
|
||||
!Mathf.Approximately(src.spatialBlend, 0.0f) ||
|
||||
!Mathf.Approximately(src.reverbZoneMix, 1.0f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Mathf.Approximately(src.dopplerLevel, 1.0f) ||
|
||||
!Mathf.Approximately(src.spread, 0.0f) ||
|
||||
src.rolloffMode != AudioRolloffMode.Logarithmic ||
|
||||
!Mathf.Approximately(src.minDistance, 1.0f) ||
|
||||
!Mathf.Approximately(src.maxDistance, 500.0f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static string GetGameObjectPath(GameObject obj)
|
||||
{
|
||||
string path = "/" + obj.name;
|
||||
while (obj.transform.parent != null)
|
||||
{
|
||||
obj = obj.transform.parent.gameObject;
|
||||
path = "/" + obj.name + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public static void ConvertONSPAudioSource(AudioSource src)
|
||||
{
|
||||
if (src == null) return;
|
||||
|
||||
var onsp = src.GetComponent<ONSPAudioSource>();
|
||||
if (onsp != null)
|
||||
{
|
||||
var vrcsp = src.gameObject.GetComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
if (vrcsp == null)
|
||||
{
|
||||
// copy the values from deprecated component
|
||||
vrcsp = src.gameObject.AddComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
vrcsp.Gain = onsp.Gain;
|
||||
vrcsp.Near = onsp.Near;
|
||||
vrcsp.Far = onsp.Far;
|
||||
vrcsp.UseAudioSourceVolumeCurve = !onsp.UseInvSqr;
|
||||
vrcsp.EnableSpatialization = onsp.EnableSpatialization;
|
||||
}
|
||||
// remove deprecated component
|
||||
Component.DestroyImmediate(onsp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddVRCSpatialToBareAudioSource(AudioSource src)
|
||||
{
|
||||
if (src == null) return;
|
||||
|
||||
var vrcsp = src.gameObject.GetComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
if (vrcsp != null) return;
|
||||
|
||||
vrcsp = src.gameObject.AddComponent<VRC.SDKBase.VRC_SpatialAudioSource>();
|
||||
|
||||
// add default values
|
||||
bool isAvatar = src.gameObject.GetComponentInParent<VRC.SDKBase.VRC_AvatarDescriptor>();
|
||||
|
||||
vrcsp.Gain = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxGain : VRCSDK2.AudioManagerSettings.RoomAudioGain;
|
||||
vrcsp.Near = 0;
|
||||
vrcsp.Far = isAvatar ? VRCSDK2.AudioManagerSettings.AvatarAudioMaxRange : VRCSDK2.AudioManagerSettings.RoomAudioMaxRange;
|
||||
vrcsp.UseAudioSourceVolumeCurve = false;
|
||||
|
||||
// enable spatialization if src is not 2D
|
||||
AnimationCurve curve = src.GetCustomCurve(AudioSourceCurveType.SpatialBlend);
|
||||
if (src.spatialBlend == 0 || (curve == null || curve.keys.Length <= 1))
|
||||
vrcsp.EnableSpatialization = false;
|
||||
else
|
||||
vrcsp.EnableSpatialization = true;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a364ece829b6234888c59987a305a00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
public class EditorCoroutine
|
||||
{
|
||||
public static EditorCoroutine Start( IEnumerator _routine )
|
||||
{
|
||||
EditorCoroutine coroutine = new EditorCoroutine(_routine);
|
||||
coroutine.start();
|
||||
return coroutine;
|
||||
}
|
||||
|
||||
|
||||
public static EditorCoroutine Start(System.Action _action)
|
||||
{
|
||||
EditorCoroutine coroutine = new EditorCoroutine(_action);
|
||||
coroutine.start();
|
||||
return coroutine;
|
||||
}
|
||||
|
||||
readonly IEnumerator routine;
|
||||
EditorCoroutine( IEnumerator _routine )
|
||||
{
|
||||
routine = _routine;
|
||||
}
|
||||
|
||||
readonly System.Action action;
|
||||
EditorCoroutine(System.Action _action)
|
||||
{
|
||||
action = _action;
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
EditorApplication.update += update;
|
||||
}
|
||||
public void stop()
|
||||
{
|
||||
EditorApplication.update -= update;
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
if (routine != null)
|
||||
{
|
||||
if (!routine.MoveNext())
|
||||
stop();
|
||||
}
|
||||
else if (action != null)
|
||||
{
|
||||
action();
|
||||
stop();
|
||||
}
|
||||
else
|
||||
stop();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89005ebc9543e0a4284893c09ca19b1d
|
||||
timeCreated: 1473271738
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class EditorHandling
|
||||
{
|
||||
static EditorHandling()
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.sceneOpened += SceneOpenedCallback;
|
||||
}
|
||||
|
||||
static void SceneOpenedCallback( Scene scene, UnityEditor.SceneManagement.OpenSceneMode mode)
|
||||
{
|
||||
// refresh window when scene is opened to display content images correctly
|
||||
if (null != VRCSdkControlPanel.window) VRCSdkControlPanel.window.Reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d6c2e367eaa9564ebf6267ec163cfbd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,357 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_EventHandler))]
|
||||
public class EventHandlerEditor : Editor
|
||||
{
|
||||
bool showDeferredEvents = false;
|
||||
|
||||
static VRCSDK2.VRC_EventHandler.VrcEventType lastAddedEventType = VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
VRCSDK2.VRC_EventHandler myTarget = (VRCSDK2.VRC_EventHandler)target;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("ID:");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (myTarget.GetComponent<VRCSDK2.VRC_Trigger>() != null)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Add Events via the VRC_Trigger on this object.");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
RenderOldEditor(myTarget);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
|
||||
}
|
||||
|
||||
if (myTarget.deferredEvents.Count > 0)
|
||||
{
|
||||
showDeferredEvents = EditorGUILayout.Foldout(showDeferredEvents, "Deferred Events");
|
||||
if (showDeferredEvents)
|
||||
RenderEvents(myTarget.deferredEvents);
|
||||
}
|
||||
}
|
||||
|
||||
int[] sendMessageMethodIndicies;
|
||||
private void RenderOldEditor(VRCSDK2.VRC_EventHandler myTarget)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Please use a VRC_Trigger in the future.", MessageType.Error);
|
||||
|
||||
if (GUILayout.Button("Add Event Handler"))
|
||||
myTarget.Events.Add(new VRCSDK2.VRC_EventHandler.VrcEvent());
|
||||
|
||||
bool first = true;
|
||||
int deleteEventIndex = -1;
|
||||
if (sendMessageMethodIndicies == null || sendMessageMethodIndicies.Length != myTarget.Events.Count)
|
||||
sendMessageMethodIndicies = new int[myTarget.Events.Count + 1];
|
||||
|
||||
for (int i = 0; i < myTarget.Events.Count; ++i)
|
||||
{
|
||||
if (!first)
|
||||
EditorGUILayout.Separator();
|
||||
first = false;
|
||||
|
||||
EditorGUILayout.LabelField("Event " + (i + 1).ToString());
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Event Name");
|
||||
myTarget.Events[i].Name = EditorGUILayout.TextField(myTarget.Events[i].Name);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Event Type");
|
||||
myTarget.Events[i].EventType = (VRCSDK2.VRC_EventHandler.VrcEventType)EditorGUILayout.EnumPopup(myTarget.Events[i].EventType);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
switch (myTarget.Events[i].EventType)
|
||||
{
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationBool:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Variable");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Operation");
|
||||
myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationFloat:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Variable");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Value");
|
||||
myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationTrigger:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Trigger");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.AudioTrigger:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("AudioSource");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.MeshVisibility:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Mesh");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Operation");
|
||||
myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.PlayAnimation:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Target");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Animation");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.RunConsoleCommand:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Command");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Receiver");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Message");
|
||||
|
||||
// sorry for this shit show. Below allows us to show a list of public methods, but also allow custom messages
|
||||
var methods = VRC_EditorTools.GetAccessibleMethodsOnGameObject(myTarget.Events[i].ParameterObject);
|
||||
List<string> methodList = methods.Values.Aggregate(new List<string>(), (acc, lst) => { acc.AddRange(lst.Select(mi => mi.Name)); return acc; });
|
||||
methodList.Add("Custom Message");
|
||||
|
||||
string[] _choices = methodList.ToArray();
|
||||
|
||||
int currentIndex = methodList.Count - 1;
|
||||
|
||||
if (methodList.Contains(myTarget.Events[i].ParameterString))
|
||||
currentIndex = methodList.IndexOf(myTarget.Events[i].ParameterString);
|
||||
|
||||
sendMessageMethodIndicies[i] = EditorGUILayout.Popup(currentIndex, _choices);
|
||||
|
||||
if (sendMessageMethodIndicies[i] != methodList.Count - 1)
|
||||
{
|
||||
myTarget.Events[i].ParameterString = _choices[sendMessageMethodIndicies[i]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (methodList.Contains(myTarget.Events[i].ParameterString))
|
||||
myTarget.Events[i].ParameterString = "";
|
||||
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.SetGameObjectActive:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("GameObject");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Operation");
|
||||
myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.SetParticlePlaying:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Target");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Operation");
|
||||
myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.TeleportPlayer:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Location");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Align Room To Destination");
|
||||
myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelURI:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("URI");
|
||||
myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Panel");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelVolume:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Volume");
|
||||
myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Panel");
|
||||
myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
default:
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUIStyle redText = new GUIStyle();
|
||||
redText.normal.textColor = Color.red;
|
||||
EditorGUILayout.LabelField("Unsupported event type", redText);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
break;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Delete " + myTarget.Events[i].Name + "?");
|
||||
if (GUILayout.Button("delete"))
|
||||
deleteEventIndex = i;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (myTarget.Events[i].ParameterObject == null)
|
||||
myTarget.Events[i].ParameterObject = myTarget.gameObject;
|
||||
}
|
||||
|
||||
|
||||
if (deleteEventIndex != -1)
|
||||
myTarget.Events.RemoveAt(deleteEventIndex);
|
||||
}
|
||||
|
||||
private void RenderEvents(IEnumerable<VRCSDK2.VRC_EventHandler.EventInfo> entries)
|
||||
{
|
||||
foreach (VRCSDK2.VRC_EventHandler.EventInfo entry in entries)
|
||||
{
|
||||
EditorGUILayout.PrefixLabel("Target");
|
||||
EditorGUILayout.ObjectField(entry.evt.ParameterObject, typeof(GameObject), true);
|
||||
|
||||
EditorGUILayout.LabelField(string.Format("Name: {0}", entry.evt.Name));
|
||||
EditorGUILayout.LabelField(string.Format("Type: {0}", entry.evt.EventType));
|
||||
EditorGUILayout.LabelField(string.Format("Bool: {0}", entry.evt.ParameterBool));
|
||||
EditorGUILayout.LabelField(string.Format("Float: {0}", entry.evt.ParameterFloat));
|
||||
EditorGUILayout.LabelField(string.Format("Int: {0}", entry.evt.ParameterInt));
|
||||
EditorGUILayout.LabelField(string.Format("String: {0}", entry.evt.ParameterString));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RenderEditor(VRCSDK2.VRC_EventHandler myTarget)
|
||||
{
|
||||
bool first = true;
|
||||
int deleteEventIndex = -1;
|
||||
|
||||
for (int i = 0; i < myTarget.Events.Count; ++i)
|
||||
{
|
||||
if (!first)
|
||||
EditorGUILayout.Separator();
|
||||
first = false;
|
||||
|
||||
if (RenderEventHeader(myTarget, myTarget.Events[i]))
|
||||
deleteEventIndex = i;
|
||||
|
||||
RenderEventHeader(myTarget, myTarget.Events[i]);
|
||||
|
||||
if (myTarget.Events[i].ParameterObject == null)
|
||||
myTarget.Events[i].ParameterObject = myTarget.gameObject;
|
||||
}
|
||||
|
||||
if (deleteEventIndex != -1)
|
||||
myTarget.Events.RemoveAt(deleteEventIndex);
|
||||
}
|
||||
|
||||
public static VRCSDK2.VRC_EventHandler.VrcEvent RenderAddEvent(VRCSDK2.VRC_EventHandler myTarget)
|
||||
{
|
||||
VRCSDK2.VRC_EventHandler.VrcEvent newEvent = null;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
lastAddedEventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", lastAddedEventType, (v) => v != VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject && v != VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage);
|
||||
if (GUILayout.Button("Add"))
|
||||
{
|
||||
newEvent = new VRCSDK2.VRC_EventHandler.VrcEvent
|
||||
{
|
||||
EventType = lastAddedEventType,
|
||||
ParameterObject = myTarget.gameObject
|
||||
};
|
||||
myTarget.Events.Add(newEvent);
|
||||
EditorUtility.SetDirty(myTarget);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
public static bool RenderEventHeader(VRCSDK2.VRC_EventHandler myTarget, VRCSDK2.VRC_EventHandler.VrcEvent evt)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
evt.EventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", evt.EventType, (v) => v != VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject && v != VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage);
|
||||
bool delete = GUILayout.Button("Remove");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
return delete;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRC.SDKBase.VRC_EventHandler))]
|
||||
public class SDKBaseEventHandlerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Event Handlers are not supported in VRCSDK3.");
|
||||
if (GUILayout.Button("replace me with the correct VRC_EventHandler"))
|
||||
{
|
||||
var go = ((VRC.SDKBase.VRC_EventHandler)target).gameObject;
|
||||
DestroyImmediate(target);
|
||||
go.AddComponent<VRCSDK2.VRC_EventHandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
[CustomEditor(typeof(VRC.SDKBase.VRC_EventHandler))]
|
||||
public class SDKBaseEventHandlerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Event Handlers are not supported in VRCSDK3.");
|
||||
if( GUILayout.Button("delete me") )
|
||||
DestroyImmediate(target);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4810e652e8242384c834320970702290
|
||||
timeCreated: 1454469344
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#pragma warning disable 0618
|
||||
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_KeyEvents))]
|
||||
public class VRC_KeyEventsEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_UseEvents))]
|
||||
public class VRC_UseEventsEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_TriggerColliderEventTrigger))]
|
||||
public class VRC_TriggerColliderEventTriggerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_TimedEvents))]
|
||||
public class VRC_TimedEventsEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 0618
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 482185bf29f12074dada194ffef6a682
|
||||
timeCreated: 1475877803
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,225 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using VRC.SDK3.Editor;
|
||||
using VRC.SDKBase.Editor;
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_AvatarDescriptor))]
|
||||
public class AvatarDescriptorEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_AvatarDescriptor avatarDescriptor;
|
||||
VRC.Core.PipelineManager pipelineManager;
|
||||
|
||||
SkinnedMeshRenderer selectedMesh;
|
||||
List<string> blendShapeNames = null;
|
||||
|
||||
bool shouldRefreshVisemes = false;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (avatarDescriptor == null)
|
||||
avatarDescriptor = (VRCSDK2.VRC_AvatarDescriptor)target;
|
||||
|
||||
if (pipelineManager == null)
|
||||
{
|
||||
pipelineManager = avatarDescriptor.GetComponent<VRC.Core.PipelineManager>();
|
||||
if (pipelineManager == null)
|
||||
avatarDescriptor.gameObject.AddComponent<VRC.Core.PipelineManager>();
|
||||
}
|
||||
|
||||
// DrawDefaultInspector();
|
||||
|
||||
if(VRCSdkControlPanel.window != null)
|
||||
{
|
||||
if( GUILayout.Button( "Select this avatar in the SDK control panel" ) )
|
||||
VRCSdkControlPanelAvatarBuilder.SelectAvatar(avatarDescriptor);
|
||||
}
|
||||
|
||||
avatarDescriptor.ViewPosition = EditorGUILayout.Vector3Field("View Position", avatarDescriptor.ViewPosition);
|
||||
//avatarDescriptor.Name = EditorGUILayout.TextField("Avatar Name", avatarDescriptor.Name);
|
||||
avatarDescriptor.Animations = (VRCSDK2.VRC_AvatarDescriptor.AnimationSet)EditorGUILayout.EnumPopup("Default Animation Set", avatarDescriptor.Animations);
|
||||
avatarDescriptor.CustomStandingAnims = (AnimatorOverrideController)EditorGUILayout.ObjectField("Custom Standing Anims", avatarDescriptor.CustomStandingAnims, typeof(AnimatorOverrideController), true, null);
|
||||
avatarDescriptor.CustomSittingAnims = (AnimatorOverrideController)EditorGUILayout.ObjectField("Custom Sitting Anims", avatarDescriptor.CustomSittingAnims, typeof(AnimatorOverrideController), true, null);
|
||||
avatarDescriptor.ScaleIPD = EditorGUILayout.Toggle("Scale IPD", avatarDescriptor.ScaleIPD);
|
||||
|
||||
avatarDescriptor.lipSync = (VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle)EditorGUILayout.EnumPopup("Lip Sync", avatarDescriptor.lipSync);
|
||||
switch (avatarDescriptor.lipSync)
|
||||
{
|
||||
case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.Default:
|
||||
if (GUILayout.Button("Auto Detect!"))
|
||||
AutoDetectLipSync();
|
||||
break;
|
||||
|
||||
case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBlendShape:
|
||||
avatarDescriptor.VisemeSkinnedMesh = (SkinnedMeshRenderer)EditorGUILayout.ObjectField("Face Mesh", avatarDescriptor.VisemeSkinnedMesh, typeof(SkinnedMeshRenderer), true);
|
||||
if (avatarDescriptor.VisemeSkinnedMesh != null)
|
||||
{
|
||||
DetermineBlendShapeNames();
|
||||
|
||||
int current = -1;
|
||||
for (int b = 0; b < blendShapeNames.Count; ++b)
|
||||
if (avatarDescriptor.MouthOpenBlendShapeName == blendShapeNames[b])
|
||||
current = b;
|
||||
|
||||
string title = "Jaw Flap Blend Shape";
|
||||
int next = EditorGUILayout.Popup(title, current, blendShapeNames.ToArray());
|
||||
if (next >= 0)
|
||||
avatarDescriptor.MouthOpenBlendShapeName = blendShapeNames[next];
|
||||
}
|
||||
break;
|
||||
|
||||
case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBone:
|
||||
avatarDescriptor.lipSyncJawBone = (Transform)EditorGUILayout.ObjectField("Jaw Bone", avatarDescriptor.lipSyncJawBone, typeof(Transform), true);
|
||||
break;
|
||||
|
||||
case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.VisemeBlendShape:
|
||||
SkinnedMeshRenderer prev = avatarDescriptor.VisemeSkinnedMesh;
|
||||
avatarDescriptor.VisemeSkinnedMesh = (SkinnedMeshRenderer)EditorGUILayout.ObjectField("Face Mesh", avatarDescriptor.VisemeSkinnedMesh, typeof(SkinnedMeshRenderer), true);
|
||||
if (avatarDescriptor.VisemeSkinnedMesh != prev)
|
||||
shouldRefreshVisemes = true;
|
||||
if (avatarDescriptor.VisemeSkinnedMesh != null)
|
||||
{
|
||||
DetermineBlendShapeNames();
|
||||
|
||||
if (avatarDescriptor.VisemeBlendShapes == null || avatarDescriptor.VisemeBlendShapes.Length != (int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count)
|
||||
avatarDescriptor.VisemeBlendShapes = new string[(int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count];
|
||||
for (int i = 0; i < (int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count; ++i)
|
||||
{
|
||||
int current = -1;
|
||||
for (int b = 0; b < blendShapeNames.Count; ++b)
|
||||
if (avatarDescriptor.VisemeBlendShapes[i] == blendShapeNames[b])
|
||||
current = b;
|
||||
|
||||
string title = "Viseme: " + ((VRCSDK2.VRC_AvatarDescriptor.Viseme)i).ToString();
|
||||
int next = EditorGUILayout.Popup(title, current, blendShapeNames.ToArray());
|
||||
if (next >= 0)
|
||||
avatarDescriptor.VisemeBlendShapes[i] = blendShapeNames[next];
|
||||
}
|
||||
|
||||
if (shouldRefreshVisemes)
|
||||
AutoDetectVisemes();
|
||||
}
|
||||
break;
|
||||
}
|
||||
EditorGUILayout.LabelField("Unity Version", avatarDescriptor.unityVersion);
|
||||
}
|
||||
|
||||
void DetermineBlendShapeNames()
|
||||
{
|
||||
if (avatarDescriptor.VisemeSkinnedMesh != null &&
|
||||
avatarDescriptor.VisemeSkinnedMesh != selectedMesh)
|
||||
{
|
||||
blendShapeNames = new List<string>();
|
||||
blendShapeNames.Add("-none-");
|
||||
selectedMesh = avatarDescriptor.VisemeSkinnedMesh;
|
||||
if ((selectedMesh != null) && (selectedMesh.sharedMesh != null))
|
||||
{
|
||||
for (int i = 0; i < selectedMesh.sharedMesh.blendShapeCount; ++i)
|
||||
blendShapeNames.Add(selectedMesh.sharedMesh.GetBlendShapeName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoDetectVisemes()
|
||||
{
|
||||
|
||||
// prioritize strict - but fallback to looser - naming and don't touch user-overrides
|
||||
|
||||
List<string> blendShapes = new List<string>(blendShapeNames);
|
||||
blendShapes.Remove("-none-");
|
||||
|
||||
for (int v = 0; v < avatarDescriptor.VisemeBlendShapes.Length; v++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(avatarDescriptor.VisemeBlendShapes[v]))
|
||||
{
|
||||
string viseme = ((VRCSDK2.VRC_AvatarDescriptor.Viseme)v).ToString().ToLowerInvariant();
|
||||
|
||||
foreach (string s in blendShapes)
|
||||
{
|
||||
if (s.ToLowerInvariant() == "vrc.v_" + viseme)
|
||||
{
|
||||
avatarDescriptor.VisemeBlendShapes[v] = s;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
foreach (string s in blendShapes)
|
||||
{
|
||||
if (s.ToLowerInvariant() == "v_" + viseme)
|
||||
{
|
||||
avatarDescriptor.VisemeBlendShapes[v] = s;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
foreach (string s in blendShapes)
|
||||
{
|
||||
if (s.ToLowerInvariant().EndsWith(viseme))
|
||||
{
|
||||
avatarDescriptor.VisemeBlendShapes[v] = s;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
foreach (string s in blendShapes)
|
||||
{
|
||||
if (s.ToLowerInvariant() == viseme)
|
||||
{
|
||||
avatarDescriptor.VisemeBlendShapes[v] = s;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
foreach (string s in blendShapes)
|
||||
{
|
||||
if (s.ToLowerInvariant().Contains(viseme))
|
||||
{
|
||||
avatarDescriptor.VisemeBlendShapes[v] = s;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
next: { }
|
||||
}
|
||||
}
|
||||
|
||||
shouldRefreshVisemes = false;
|
||||
|
||||
}
|
||||
|
||||
void AutoDetectLipSync()
|
||||
{
|
||||
var smrs = avatarDescriptor.GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
foreach (var smr in smrs)
|
||||
{
|
||||
if (smr.sharedMesh.blendShapeCount > 0)
|
||||
{
|
||||
avatarDescriptor.lipSyncJawBone = null;
|
||||
|
||||
if (smr.sharedMesh.blendShapeCount > 1)
|
||||
{
|
||||
avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.VisemeBlendShape;
|
||||
avatarDescriptor.VisemeSkinnedMesh = smr;
|
||||
shouldRefreshVisemes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBlendShape;
|
||||
avatarDescriptor.VisemeSkinnedMesh = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Animator a = avatarDescriptor.GetComponent<Animator>();
|
||||
if (!a)
|
||||
EditorUtility.DisplayDialog("Ooops", "This avatar has no Animator and can have no lipsync.", "OK");
|
||||
else if (a.GetBoneTransform(HumanBodyBones.Jaw) != null)
|
||||
{
|
||||
avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBone;
|
||||
avatarDescriptor.lipSyncJawBone = avatarDescriptor.GetComponent<Animator>().GetBoneTransform(HumanBodyBones.Jaw);
|
||||
avatarDescriptor.VisemeSkinnedMesh = null;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e83254bb97e84795ac882692ae124ba
|
||||
timeCreated: 1450462624
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_ObjectSpawn))]
|
||||
public class VRCObjectSpawnEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_ObjectSpawn spawn;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (spawn == null)
|
||||
spawn = (VRCSDK2.VRC_ObjectSpawn)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26a75599848adb449b7aceed5090e35c
|
||||
timeCreated: 1463516633
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_ObjectSync))]
|
||||
public class VRCObjectSyncEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_ObjectSync sync;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (sync == null)
|
||||
sync = (VRCSDK2.VRC_ObjectSync)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
sync.SynchronizePhysics = EditorGUILayout.Toggle("Synchronize Physics",sync.SynchronizePhysics);
|
||||
sync.AllowCollisionTransfer = EditorGUILayout.Toggle("Allow Collision Transfer", sync.AllowCollisionTransfer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed4aad2698d3b62408e69b57c7748791
|
||||
timeCreated: 1463516212
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public class VRCPlayerModEditorWindow : EditorWindow {
|
||||
|
||||
public delegate void AddModCallback();
|
||||
public static AddModCallback addModCallback;
|
||||
|
||||
private static VRCSDK2.VRC_PlayerMods myTarget;
|
||||
|
||||
private static VRCSDK2.VRCPlayerModFactory.PlayerModType type;
|
||||
|
||||
public static void Init (VRCSDK2.VRC_PlayerMods target, AddModCallback callback)
|
||||
{
|
||||
// Get existing open window or if none, make a new one:
|
||||
EditorWindow.GetWindow (typeof (VRCPlayerModEditorWindow));
|
||||
addModCallback = callback;
|
||||
myTarget = target;
|
||||
|
||||
type = VRCSDK2.VRCPlayerModFactory.PlayerModType.Jump;
|
||||
}
|
||||
|
||||
void OnGUI ()
|
||||
{
|
||||
type = (VRCSDK2.VRCPlayerModFactory.PlayerModType)EditorGUILayout.EnumPopup("Mods", type);
|
||||
if(GUILayout.Button("Add Mod"))
|
||||
{
|
||||
VRCSDK2.VRCPlayerMod mod = VRCSDK2.VRCPlayerModFactory.Create(type);
|
||||
myTarget.AddMod(mod);
|
||||
addModCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8986a640e24a0754ea0aded12234b808
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_PlayerMods))]
|
||||
public class VRCPlayerModsEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_PlayerMods myTarget;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if(myTarget == null)
|
||||
myTarget = (VRCSDK2.VRC_PlayerMods)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
myTarget.isRoomPlayerMods = EditorGUILayout.Toggle("isRoomPlayerMods", myTarget.isRoomPlayerMods);
|
||||
|
||||
List<VRCSDK2.VRCPlayerMod> playerMods = myTarget.playerMods;
|
||||
for(int i=0; i<playerMods.Count; ++i)
|
||||
{
|
||||
VRCSDK2.VRCPlayerMod mod = playerMods[i];
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
EditorGUILayout.LabelField(mod.name, EditorStyles.boldLabel);
|
||||
if( mod.allowNameEdit )
|
||||
mod.name = EditorGUILayout.TextField( "Mod Name: ", mod.name );
|
||||
for(int j=0; j<mod.properties.Count; ++j)
|
||||
{
|
||||
VRCSDK2.VRCPlayerModProperty prop = mod.properties[j];
|
||||
myTarget.playerMods[i].properties[j] = DrawFieldForProp(prop);
|
||||
}
|
||||
if(GUILayout.Button ("Remove Mod"))
|
||||
{
|
||||
myTarget.RemoveMod(mod);
|
||||
break;
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
if(GUILayout.Button("Add Mods"))
|
||||
{
|
||||
VRCPlayerModEditorWindow.AddModCallback adcb = OnInspectorGUI;
|
||||
VRCPlayerModEditorWindow.Init(myTarget, adcb);
|
||||
}
|
||||
}
|
||||
|
||||
VRCSDK2.VRCPlayerModProperty DrawFieldForProp(VRCSDK2.VRCPlayerModProperty property)
|
||||
{
|
||||
if(property.type.SystemType == typeof(int))
|
||||
{
|
||||
property.intValue = EditorGUILayout.IntField(property.name, property.intValue);
|
||||
}
|
||||
else if(property.type.SystemType == typeof(float))
|
||||
{
|
||||
property.floatValue = EditorGUILayout.FloatField(property.name, property.floatValue);
|
||||
}
|
||||
else if(property.type.SystemType == typeof(string))
|
||||
{
|
||||
property.stringValue = EditorGUILayout.TextField(property.name, property.stringValue);
|
||||
}
|
||||
else if(property.type.SystemType == typeof(bool))
|
||||
{
|
||||
property.boolValue = EditorGUILayout.Toggle(property.name, property.boolValue);
|
||||
}
|
||||
else if(property.type.SystemType == typeof(GameObject))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField( property.name );
|
||||
property.gameObjectValue = (GameObject) EditorGUILayout.ObjectField( property.gameObjectValue, typeof( GameObject ), true );
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if(property.type.SystemType == typeof(KeyCode))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField( property.name );
|
||||
property.keyCodeValue = (KeyCode) EditorGUILayout.EnumPopup( property.keyCodeValue );
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if(property.type.SystemType == typeof(VRCSDK2.VRC_EventHandler.VrcBroadcastType))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField( property.name );
|
||||
property.broadcastValue = (VRCSDK2.VRC_EventHandler.VrcBroadcastType) EditorGUILayout.EnumPopup( property.broadcastValue );
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if(property.type.SystemType == typeof(VRCSDK2.VRCPlayerModFactory.HealthOnDeathAction))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField( property.name );
|
||||
property.onDeathActionValue = (VRCSDK2.VRCPlayerModFactory.HealthOnDeathAction) EditorGUILayout.EnumPopup( property.onDeathActionValue);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if(property.type.SystemType == typeof(RuntimeAnimatorController))
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField( property.name );
|
||||
property.animationController = (RuntimeAnimatorController) EditorGUILayout.ObjectField( property.animationController, typeof( RuntimeAnimatorController ), false );
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 792e7964a56e51f4188e1221751642e9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_Station))]
|
||||
public class VRCPlayerStationEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_Station myTarget;
|
||||
|
||||
SerializedProperty onRemoteEnter;
|
||||
SerializedProperty onRemoteExit;
|
||||
SerializedProperty onLocalEnter;
|
||||
SerializedProperty onLocalExit;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if(myTarget == null)
|
||||
myTarget = (VRCSDK2.VRC_Station)target;
|
||||
onRemoteEnter = serializedObject.FindProperty("OnRemotePlayerEnterStation");
|
||||
onRemoteExit = serializedObject.FindProperty("OnRemotePlayerExitStation");
|
||||
onLocalEnter = serializedObject.FindProperty("OnLocalPlayerEnterStation");
|
||||
onLocalExit = serializedObject.FindProperty("OnLocalPlayerExitStation");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
myTarget.PlayerMobility = (VRC.SDKBase.VRCStation.Mobility)EditorGUILayout.EnumPopup("Player Mobility", myTarget.PlayerMobility);
|
||||
myTarget.canUseStationFromStation = EditorGUILayout.Toggle("Can Use Station From Station", myTarget.canUseStationFromStation);
|
||||
myTarget.animatorController = (RuntimeAnimatorController)EditorGUILayout.ObjectField("Animator Controller", myTarget.animatorController, typeof(RuntimeAnimatorController), false);
|
||||
myTarget.disableStationExit = EditorGUILayout.Toggle("Disable Station Exit", myTarget.disableStationExit);
|
||||
myTarget.seated = EditorGUILayout.Toggle("Seated", myTarget.seated);
|
||||
myTarget.stationEnterPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Enter Location", myTarget.stationEnterPlayerLocation, typeof(Transform), true);
|
||||
myTarget.stationExitPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Exit Location", myTarget.stationExitPlayerLocation, typeof(Transform), true);
|
||||
myTarget.controlsObject = (VRC.SDKBase.VRC_ObjectApi)EditorGUILayout.ObjectField("API Object", myTarget.controlsObject, typeof(VRC.SDKBase.VRC_ObjectApi), false);
|
||||
|
||||
EditorGUILayout.PropertyField(onRemoteEnter, new GUIContent("On Remote Player Enter"));
|
||||
EditorGUILayout.PropertyField(onRemoteExit, new GUIContent("On Remote Player Exit"));
|
||||
EditorGUILayout.PropertyField(onLocalEnter, new GUIContent("On Local Player Enter"));
|
||||
EditorGUILayout.PropertyField(onLocalExit, new GUIContent("On Local Player Exit"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5262a02c32e41e047bdfdfc3b63db8ff
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
|
||||
[CustomEditor (typeof(VRCSDK2.VRC_SceneDescriptor))]
|
||||
public class VRCSceneDescriptorEditor : Editor
|
||||
{
|
||||
VRCSDK2.VRC_SceneDescriptor sceneDescriptor;
|
||||
VRC.Core.PipelineManager pipelineManager;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if(sceneDescriptor == null)
|
||||
sceneDescriptor = (VRCSDK2.VRC_SceneDescriptor)target;
|
||||
|
||||
if(pipelineManager == null)
|
||||
{
|
||||
pipelineManager = sceneDescriptor.GetComponent<VRC.Core.PipelineManager>();
|
||||
if(pipelineManager == null)
|
||||
sceneDescriptor.gameObject.AddComponent<VRC.Core.PipelineManager>();
|
||||
}
|
||||
|
||||
DrawDefaultInspector();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9cbc493bbbc443fb92898aa84d221ec
|
||||
timeCreated: 1450463561
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
//[CustomPropertyDrawer(typeof(VRC_AvatarVariations.VariationCategory))]
|
||||
//public class PropertyDrawer_AvatarVariation_VariationCategory : PropertyDrawer
|
||||
//{
|
||||
// public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
|
||||
// {
|
||||
// //EditorGUILayout.Label("blah");
|
||||
|
||||
// if (property == null)
|
||||
// return;
|
||||
|
||||
// SerializedProperty nameProperty = property.FindPropertyRelative("name");
|
||||
// //SerializedProperty mirrorProperty = property.FindPropertyRelative("mirror");
|
||||
// //SerializedProperty typeProperty = property.FindPropertyRelative("type");
|
||||
// //SerializedProperty valueProperty = null;
|
||||
// //switch (typeProperty.enumValueIndex)
|
||||
// //{
|
||||
// // case (int)VRC_DataStorage.VrcDataType.Bool:
|
||||
// // valueProperty = property.FindPropertyRelative("valueBool");
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataType.Float:
|
||||
// // valueProperty = property.FindPropertyRelative("valueFloat");
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataType.Int:
|
||||
// // valueProperty = property.FindPropertyRelative("valueInt");
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataType.String:
|
||||
// // valueProperty = property.FindPropertyRelative("valueString");
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataType.SerializeObject:
|
||||
// // valueProperty = property.FindPropertyRelative("serializeComponent");
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataType.None:
|
||||
// // case (int)VRC_DataStorage.VrcDataType.SerializeBytes:
|
||||
// // break;
|
||||
// //}
|
||||
|
||||
// EditorGUI.BeginProperty(rect, label, property);
|
||||
|
||||
// int baseWidth = (int)(rect.width / 4);
|
||||
// Rect nameRect = new Rect(rect.x, rect.y, baseWidth, rect.height);
|
||||
// //Rect mirrorRect = new Rect(rect.x + baseWidth, rect.y, baseWidth, rect.height);
|
||||
// //Rect typeRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth, rect.height);
|
||||
// //Rect valueRect = new Rect(rect.x + baseWidth * 3, rect.y, baseWidth, rect.height);
|
||||
// //Rect typeValueRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth * 2, rect.height);
|
||||
|
||||
// EditorGUI.PropertyField(nameRect, nameProperty, GUIContent.none);
|
||||
// //EditorGUI.PropertyField(mirrorRect, mirrorProperty, GUIContent.none);
|
||||
|
||||
// //switch (mirrorProperty.enumValueIndex)
|
||||
// //{
|
||||
// // case (int)VRC_DataStorage.VrcDataMirror.None:
|
||||
// // if (valueProperty == null)
|
||||
// // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
|
||||
// // else
|
||||
// // {
|
||||
// // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeRect, typeProperty, t => true);
|
||||
// // EditorGUI.PropertyField(valueRect, valueProperty, GUIContent.none);
|
||||
// // }
|
||||
// // break;
|
||||
// // case (int)VRC_DataStorage.VrcDataMirror.SerializeComponent:
|
||||
// // typeProperty.enumValueIndex = (int)VRC_DataStorage.VrcDataType.SerializeObject;
|
||||
// // EditorGUI.PropertyField(typeValueRect, valueProperty, GUIContent.none);
|
||||
// // break;
|
||||
// // default:
|
||||
// // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
|
||||
// // break;
|
||||
// //}
|
||||
|
||||
// EditorGUI.EndProperty();
|
||||
// }
|
||||
//}
|
||||
|
||||
//[CustomEditor(typeof(VRC_AvatarVariations))]
|
||||
//public class VRC_AvatarVariationsEditor : Editor
|
||||
//{
|
||||
// SerializedProperty categories;
|
||||
|
||||
// void OnEnable()
|
||||
// {
|
||||
// categories = serializedObject.FindProperty("categories");
|
||||
// }
|
||||
|
||||
// public override void OnInspectorGUI()
|
||||
// {
|
||||
// //serializedObject.Update();
|
||||
// // EditorGUILayout.PropertyField(categories);
|
||||
// //serializedObject.ApplyModifiedProperties();
|
||||
|
||||
|
||||
|
||||
// //if (target == null)
|
||||
// // return;
|
||||
|
||||
// ////var prop = serializedObject.FindProperty("root");
|
||||
// ////EditorGUILayout.PropertyField(prop, new GUIContent("Show Help"));
|
||||
// //VRCSDK2.VRC_AvatarVariations variations = target as VRCSDK2.VRC_AvatarVariations;
|
||||
// //if (variations.categories == null)
|
||||
// // variations.categories = new VRC_AvatarVariations.VariationCategory[0];
|
||||
|
||||
// //foreach ( var vc in variations.categories )
|
||||
// //{
|
||||
// // vc.name = EditorGUILayout.TextField("Variation Name", vc.name);
|
||||
// //// SerializedProperty triggers = triggersProperty.Copy();
|
||||
// //// int triggersLength = triggers.arraySize;
|
||||
|
||||
// //// List<int> to_remove = new List<int>();
|
||||
// //// for (int idx = 0; idx < triggersLength; ++idx)
|
||||
// //// {
|
||||
// //// SerializedProperty triggerProperty = triggers.GetArrayElementAtIndex(idx);
|
||||
// //// }
|
||||
|
||||
// //// EditorGUILayout.LabelField("");
|
||||
// ////// helpProperty = serializedObject.FindProperty("ShowHelp");
|
||||
// ////// EditorGUILayout.PropertyField(helpProperty, new GUIContent("Show Help"));
|
||||
// //}
|
||||
|
||||
// ////EditorGUILayout.
|
||||
|
||||
// DrawDefaultInspector();
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eeda995d0ceac6443a54716996eab52e
|
||||
timeCreated: 1511373338
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(VRCSDK2.VRC_DataStorage.VrcDataElement))]
|
||||
public class CustomDataElementDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (property == null)
|
||||
return;
|
||||
|
||||
SerializedProperty nameProperty = property.FindPropertyRelative("name");
|
||||
SerializedProperty mirrorProperty = property.FindPropertyRelative("mirror");
|
||||
SerializedProperty typeProperty = property.FindPropertyRelative("type");
|
||||
SerializedProperty valueProperty = null;
|
||||
switch (typeProperty.enumValueIndex)
|
||||
{
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Bool:
|
||||
valueProperty = property.FindPropertyRelative("valueBool");
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Float:
|
||||
valueProperty = property.FindPropertyRelative("valueFloat");
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Int:
|
||||
valueProperty = property.FindPropertyRelative("valueInt");
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.String:
|
||||
valueProperty = property.FindPropertyRelative("valueString");
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeObject:
|
||||
valueProperty = property.FindPropertyRelative("serializeComponent");
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.None:
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeBytes:
|
||||
break;
|
||||
}
|
||||
|
||||
EditorGUI.BeginProperty(rect, label, property);
|
||||
|
||||
int baseWidth = (int)(rect.width / 4);
|
||||
Rect nameRect = new Rect(rect.x, rect.y, baseWidth, rect.height);
|
||||
Rect mirrorRect = new Rect(rect.x + baseWidth, rect.y, baseWidth, rect.height);
|
||||
Rect typeRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth, rect.height);
|
||||
Rect valueRect = new Rect(rect.x + baseWidth * 3, rect.y, baseWidth, rect.height);
|
||||
Rect typeValueRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth * 2, rect.height);
|
||||
|
||||
EditorGUI.PropertyField(nameRect, nameProperty, GUIContent.none);
|
||||
EditorGUI.PropertyField(mirrorRect, mirrorProperty, GUIContent.none);
|
||||
|
||||
switch (mirrorProperty.enumValueIndex)
|
||||
{
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataMirror.None:
|
||||
if (valueProperty == null)
|
||||
VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
|
||||
else
|
||||
{
|
||||
VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeRect, typeProperty, t => true);
|
||||
EditorGUI.PropertyField(valueRect, valueProperty, GUIContent.none);
|
||||
}
|
||||
break;
|
||||
case (int)VRCSDK2.VRC_DataStorage.VrcDataMirror.SerializeComponent:
|
||||
typeProperty.enumValueIndex = (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeObject;
|
||||
EditorGUI.PropertyField(typeValueRect, valueProperty, GUIContent.none);
|
||||
break;
|
||||
default:
|
||||
VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
|
||||
break;
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_DataStorage)), CanEditMultipleObjects]
|
||||
public class VRC_DataStorageEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
VRCSDK2.VRC_ObjectSync os = ((VRCSDK2.VRC_DataStorage)target).GetComponent<VRCSDK2.VRC_ObjectSync>();
|
||||
if (os != null && os.SynchronizePhysics)
|
||||
EditorGUILayout.HelpBox("Consider either removing the VRC_ObjectSync or disabling SynchronizePhysics.", MessageType.Warning);
|
||||
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ac7998a36f085844847acbc046d4e27
|
||||
timeCreated: 1478191469
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using VRC.SDKBase;
|
||||
|
||||
[CustomEditor(typeof(VRC_DestructibleStandard))]
|
||||
[CanEditMultipleObjects]
|
||||
public class VRC_DestructibleStandardEditor : Editor
|
||||
{
|
||||
VRC_DestructibleStandard ds;
|
||||
|
||||
SerializedProperty maxHealth;
|
||||
SerializedProperty currentHealth;
|
||||
SerializedProperty healable;
|
||||
SerializedProperty onDamagedTrigger;
|
||||
SerializedProperty onDestroyedTrigger;
|
||||
SerializedProperty onHealedTrigger;
|
||||
SerializedProperty onFullHealedTrigger;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
maxHealth = serializedObject.FindProperty("maxHealth");
|
||||
currentHealth = serializedObject.FindProperty("currentHealth");
|
||||
healable = serializedObject.FindProperty("healable");
|
||||
onDamagedTrigger = serializedObject.FindProperty("onDamagedTrigger");
|
||||
onDestroyedTrigger = serializedObject.FindProperty("onDestructedTrigger");
|
||||
onHealedTrigger = serializedObject.FindProperty("onHealedTrigger");
|
||||
onFullHealedTrigger = serializedObject.FindProperty("onFullHealedTrigger");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
ds = (VRC_DestructibleStandard)target;
|
||||
|
||||
// Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
|
||||
serializedObject.Update ();
|
||||
|
||||
EditorGUILayout.PropertyField(maxHealth, new GUIContent("Max Health"));
|
||||
EditorGUILayout.PropertyField(currentHealth, new GUIContent("Current Health"));
|
||||
EditorGUILayout.PropertyField(healable, new GUIContent("Is Healable"));
|
||||
|
||||
EditorGUILayout.PropertyField(onDamagedTrigger, new GUIContent("On Damaged Trigger"));
|
||||
VRCSDK2.VRC_EditorTools.DrawTriggerActionCallback("On Damaged Action", ds.onDamagedTrigger, ds.onDamagedEvent);
|
||||
|
||||
EditorGUILayout.PropertyField(onDestroyedTrigger, new GUIContent("On Destructed Trigger"));
|
||||
VRCSDK2.VRC_EditorTools.DrawTriggerActionCallback("On Destructed Action", ds.onDestructedTrigger, ds.onDestructedEvent);
|
||||
|
||||
EditorGUILayout.PropertyField(onHealedTrigger, new GUIContent("On Healed Trigger"));
|
||||
VRCSDK2.VRC_EditorTools.DrawTriggerActionCallback("On Healed Action", ds.onHealedTrigger, ds.onHealedEvent);
|
||||
|
||||
EditorGUILayout.PropertyField(onFullHealedTrigger, new GUIContent("On Full Healed Trigger"));
|
||||
VRCSDK2.VRC_EditorTools.DrawTriggerActionCallback("On Full Healed Action", ds.onFullHealedTrigger, ds.onFullHealedEvent);
|
||||
|
||||
// Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI.
|
||||
serializedObject.ApplyModifiedProperties ();
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b63b118c0591b548ba1797e6be4292e
|
||||
timeCreated: 1477161996
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_ObjectSync))]
|
||||
public class VRC_ObjectSyncEditor : Editor {
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
VRCSDK2.VRC_ObjectSync c = ((VRCSDK2.VRC_ObjectSync)target);
|
||||
if ((c.gameObject.GetComponent<Animator>() != null || c.gameObject.GetComponent<Animation>() != null) && c.SynchronizePhysics)
|
||||
EditorGUILayout.HelpBox("If the Animator or Animation moves the root position of this object then it will conflict with physics synchronization.", MessageType.Warning);
|
||||
if (c.GetComponent<VRCSDK2.VRC_DataStorage>() != null && c.SynchronizePhysics)
|
||||
EditorGUILayout.HelpBox("Consider either removing the VRC_DataStorage or disabling SynchronizePhysics.", MessageType.Warning);
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e19a7147a2386554a8e4d6e414f190a2
|
||||
timeCreated: 1504908295
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Build;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_Pickup))]
|
||||
public class VRC_PickupEditor : Editor
|
||||
{
|
||||
private void InspectorField(string propertyName, string humanName)
|
||||
{
|
||||
SerializedProperty propertyField = serializedObject.FindProperty(propertyName);
|
||||
EditorGUILayout.PropertyField(propertyField, new GUIContent(humanName), true);
|
||||
}
|
||||
|
||||
private SerializedProperty momentumTransferMethodProperty;
|
||||
private SerializedProperty disallowTheftProperty;
|
||||
private SerializedProperty exactGunProperty;
|
||||
private SerializedProperty exactGripProperty;
|
||||
private SerializedProperty allowManipulationWhenEquippedProperty;
|
||||
private SerializedProperty orientationProperty;
|
||||
private SerializedProperty autoHoldProperty;
|
||||
private SerializedProperty interactionTextProperty;
|
||||
private SerializedProperty useTextProperty;
|
||||
private SerializedProperty throwVelocityBoostMinSpeedProperty;
|
||||
private SerializedProperty throwVelocityBoostScaleProperty;
|
||||
private SerializedProperty pickupableProperty;
|
||||
private SerializedProperty proximityProperty;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
momentumTransferMethodProperty = serializedObject.FindProperty("MomentumTransferMethod");
|
||||
disallowTheftProperty = serializedObject.FindProperty("DisallowTheft");
|
||||
exactGunProperty = serializedObject.FindProperty("ExactGun");
|
||||
exactGripProperty = serializedObject.FindProperty("ExactGrip");
|
||||
allowManipulationWhenEquippedProperty = serializedObject.FindProperty("allowManipulationWhenEquipped");
|
||||
orientationProperty = serializedObject.FindProperty("orientation");
|
||||
autoHoldProperty = serializedObject.FindProperty("AutoHold");
|
||||
interactionTextProperty = serializedObject.FindProperty("InteractionText");
|
||||
useTextProperty = serializedObject.FindProperty("UseText");
|
||||
throwVelocityBoostMinSpeedProperty = serializedObject.FindProperty("ThrowVelocityBoostMinSpeed");
|
||||
throwVelocityBoostScaleProperty = serializedObject.FindProperty("ThrowVelocityBoostScale");
|
||||
pickupableProperty = serializedObject.FindProperty("pickupable");
|
||||
proximityProperty = serializedObject.FindProperty("proximity");
|
||||
|
||||
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 30));
|
||||
|
||||
EditorGUILayout.PropertyField(momentumTransferMethodProperty, new GUIContent("Momentum Transfer Method"));
|
||||
EditorGUILayout.PropertyField(disallowTheftProperty, new GUIContent("Disallow Theft"));
|
||||
EditorGUILayout.PropertyField(exactGunProperty, new GUIContent("Exact Gun"));
|
||||
EditorGUILayout.PropertyField(exactGripProperty, new GUIContent("Exact Grip"));
|
||||
EditorGUILayout.PropertyField(allowManipulationWhenEquippedProperty, new GUIContent("Allow Manipulation When Equipped"));
|
||||
EditorGUILayout.PropertyField(orientationProperty, new GUIContent("Orientation"));
|
||||
EditorGUILayout.PropertyField(autoHoldProperty, new GUIContent("AutoHold", "If the pickup is supposed to be aligned to the hand (i.e. orientation field is set to Gun or Grip), auto-detect means that it will be Equipped(not dropped when they release trigger), otherwise just hold as a normal pickup."));
|
||||
EditorGUILayout.PropertyField(interactionTextProperty, new GUIContent("Interaction Text","Text displayed when user hovers over the pickup."));
|
||||
if (autoHoldProperty.enumValueIndex != (int)VRCSDK2.VRC_Pickup.AutoHoldMode.No)
|
||||
EditorGUILayout.PropertyField(useTextProperty, new GUIContent("Use Text", "Text to display describing action for clicking button, when this pickup is already being held."));
|
||||
EditorGUILayout.PropertyField(throwVelocityBoostMinSpeedProperty, new GUIContent("Throw Velocity Boost Min Speed"));
|
||||
EditorGUILayout.PropertyField(throwVelocityBoostScaleProperty, new GUIContent("Throw Velocity Boost Scale"));
|
||||
EditorGUILayout.PropertyField(pickupableProperty, new GUIContent("Pickupable"));
|
||||
EditorGUILayout.PropertyField(proximityProperty, new GUIContent("Proximity"));
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aff4e5c0d600c845b29d7b8b7965d68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,106 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_PlayerAudioOverride))]
|
||||
public class VRC_PlayerAudioOverrideEditor : Editor
|
||||
{
|
||||
private bool voShow = true;
|
||||
private bool voAdv = false;
|
||||
private bool avShow = true;
|
||||
private bool avAdv = false;
|
||||
private SerializedProperty prioProperty;
|
||||
private SerializedProperty globalProperty;
|
||||
private SerializedProperty regionProperty;
|
||||
private SerializedProperty voGainProperty;
|
||||
private SerializedProperty voNearProperty;
|
||||
private SerializedProperty voFarProperty;
|
||||
private SerializedProperty voRadiusProperty;
|
||||
private SerializedProperty voDisableLpProperty;
|
||||
private SerializedProperty avGainProperty;
|
||||
private SerializedProperty avNearProperty;
|
||||
private SerializedProperty avFarProperty;
|
||||
private SerializedProperty avRadiusProperty;
|
||||
private SerializedProperty avForceSpatialProperty;
|
||||
private SerializedProperty avAllowCustomProperty;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
globalProperty = serializedObject.FindProperty("global");
|
||||
regionProperty = serializedObject.FindProperty("region");
|
||||
prioProperty = serializedObject.FindProperty("regionPriority");
|
||||
|
||||
voGainProperty = serializedObject.FindProperty("VoiceGain");
|
||||
voNearProperty = serializedObject.FindProperty("VoiceNear");
|
||||
voFarProperty = serializedObject.FindProperty("VoiceFar");
|
||||
voRadiusProperty = serializedObject.FindProperty("VoiceVolumetricRadius");
|
||||
voDisableLpProperty = serializedObject.FindProperty("VoiceDisableLowpass");
|
||||
|
||||
avGainProperty = serializedObject.FindProperty("AvatarGainLimit");
|
||||
avNearProperty = serializedObject.FindProperty("AvatarNearLimit");
|
||||
avFarProperty = serializedObject.FindProperty("AvatarFarLimit");
|
||||
avRadiusProperty = serializedObject.FindProperty("AvatarVolumetricRadiusLimit");
|
||||
avForceSpatialProperty = serializedObject.FindProperty("AvatarForceSpatial");
|
||||
avAllowCustomProperty = serializedObject.FindProperty("AvatarAllowCustomCurve");
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
var ovr = serializedObject.targetObject as VRCSDK2.VRC_PlayerAudioOverride;
|
||||
|
||||
EditorGUILayout.PropertyField(globalProperty, new GUIContent("Global"));
|
||||
if (!ovr.global)
|
||||
{
|
||||
EditorGUILayout.PropertyField(regionProperty, new GUIContent("Region"));
|
||||
EditorGUILayout.PropertyField(prioProperty, new GUIContent("Priority"));
|
||||
}
|
||||
|
||||
voShow = EditorGUILayout.Foldout(voShow, "Voice Settings");
|
||||
|
||||
if (voShow)
|
||||
{
|
||||
EditorGUILayout.PropertyField(voGainProperty, new GUIContent("Gain"));
|
||||
EditorGUILayout.PropertyField(voFarProperty, new GUIContent("Far"));
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
voAdv = EditorGUILayout.Foldout(voAdv, "Advanced Options");
|
||||
if (voAdv)
|
||||
{
|
||||
EditorGUILayout.PropertyField(voNearProperty, new GUIContent("Near"));
|
||||
EditorGUILayout.PropertyField(voRadiusProperty, new GUIContent("Volumetric Radius"));
|
||||
EditorGUILayout.PropertyField(voDisableLpProperty, new GUIContent("Disable Lowpass Filter"));
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
avShow = EditorGUILayout.Foldout(avShow, "Avatar Audio Limits");
|
||||
|
||||
if (avShow)
|
||||
{
|
||||
EditorGUILayout.PropertyField(avGainProperty, new GUIContent("Gain Limit"));
|
||||
EditorGUILayout.PropertyField(avFarProperty, new GUIContent("Far Limit"));
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
avAdv = EditorGUILayout.Foldout(avAdv, "Advanced Options");
|
||||
if (avAdv)
|
||||
{
|
||||
EditorGUILayout.PropertyField(avNearProperty, new GUIContent("Near Limit"));
|
||||
EditorGUILayout.PropertyField(avRadiusProperty, new GUIContent("Volumetric Radius Limit"));
|
||||
EditorGUILayout.PropertyField(avForceSpatialProperty, new GUIContent("Force Spatial"));
|
||||
EditorGUILayout.PropertyField(avAllowCustomProperty, new GUIContent("Allow Custom Curve"));
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c545625e0bf93045ac1c5864141c5c1
|
||||
timeCreated: 1474315179
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_SpatialAudioSource))]
|
||||
public class VRC_SpatialAudioSourceEditor : Editor
|
||||
{
|
||||
private bool showAdvancedOptions = false;
|
||||
private SerializedProperty gainProperty;
|
||||
private SerializedProperty nearProperty;
|
||||
private SerializedProperty farProperty;
|
||||
private SerializedProperty volRadiusProperty;
|
||||
private SerializedProperty enableSpatialProperty;
|
||||
private SerializedProperty useCurveProperty;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
gainProperty = serializedObject.FindProperty("Gain");
|
||||
nearProperty = serializedObject.FindProperty("Near");
|
||||
farProperty = serializedObject.FindProperty("Far");
|
||||
volRadiusProperty = serializedObject.FindProperty("VolumetricRadius");
|
||||
enableSpatialProperty = serializedObject.FindProperty("EnableSpatialization");
|
||||
useCurveProperty = serializedObject.FindProperty("UseAudioSourceVolumeCurve");
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
VRCSDK2.VRC_SpatialAudioSource target = serializedObject.targetObject as VRCSDK2.VRC_SpatialAudioSource;
|
||||
AudioSource source = target.GetComponent<AudioSource>();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.PropertyField(gainProperty, new GUIContent("Gain"));
|
||||
EditorGUILayout.PropertyField(farProperty, new GUIContent("Far"));
|
||||
showAdvancedOptions = EditorGUILayout.Foldout(showAdvancedOptions, "Advanced Options");
|
||||
bool enableSp = enableSpatialProperty.boolValue;
|
||||
if (showAdvancedOptions)
|
||||
{
|
||||
EditorGUILayout.PropertyField(nearProperty, new GUIContent("Near"));
|
||||
EditorGUILayout.PropertyField(volRadiusProperty, new GUIContent("Volumetric Radius"));
|
||||
EditorGUILayout.PropertyField(enableSpatialProperty, new GUIContent("Enable Spatialization"));
|
||||
if (enableSp)
|
||||
EditorGUILayout.PropertyField(useCurveProperty, new GUIContent("Use AudioSource Volume Curve"));
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (source != null)
|
||||
source.spatialize = enableSp;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d2d4cba733f5eb4ba170368e67710d2
|
||||
timeCreated: 1474315179
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,104 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
|
||||
[CustomPropertyDrawer(typeof(VRCSDK2.VRC_SyncVideoPlayer.VideoEntry))]
|
||||
public class CustomVideoEntryDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty source = property.FindPropertyRelative("Source");
|
||||
SerializedProperty ratio = property.FindPropertyRelative("AspectRatio");
|
||||
SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
|
||||
SerializedProperty clip = property.FindPropertyRelative("VideoClip");
|
||||
SerializedProperty url = property.FindPropertyRelative("URL");
|
||||
|
||||
return EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ EditorGUI.GetPropertyHeight(ratio, new GUIContent("Aspect Ratio"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ Mathf.Max(EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true), EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true)) + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty source = property.FindPropertyRelative("Source");
|
||||
SerializedProperty ratio = property.FindPropertyRelative("AspectRatio");
|
||||
SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
|
||||
SerializedProperty clip = property.FindPropertyRelative("VideoClip");
|
||||
SerializedProperty url = property.FindPropertyRelative("URL");
|
||||
|
||||
EditorGUI.BeginProperty(rect, label, property);
|
||||
float x = rect.x;
|
||||
float y = rect.y;
|
||||
float w = rect.width;
|
||||
float h = EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
VRCSDK2.VRC_EditorTools.FilteredEnumPopup<UnityEngine.Video.VideoSource>(new Rect(x, y, w, h), source, (e) => e == UnityEngine.Video.VideoSource.Url);
|
||||
y += h;
|
||||
|
||||
if (source.enumValueIndex == (int)UnityEngine.Video.VideoSource.Url)
|
||||
{
|
||||
h = EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), url);
|
||||
y += h;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), clip);
|
||||
y += h;
|
||||
}
|
||||
|
||||
h = EditorGUI.GetPropertyHeight(ratio, new GUIContent("AspectRatio"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), ratio);
|
||||
y += h;
|
||||
|
||||
h = EditorGUI.GetPropertyHeight(ratio, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), speed);
|
||||
if (speed.floatValue == 0f)
|
||||
speed.floatValue = 1f;
|
||||
y += h;
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_SyncVideoPlayer))]
|
||||
public class SyncVideoPlayerEditor : Editor
|
||||
{
|
||||
ReorderableList sourceList;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
SerializedProperty searchRoot = serializedObject.FindProperty("VideoSearchRoot");
|
||||
EditorGUILayout.PropertyField(searchRoot);
|
||||
SerializedProperty maxQual = serializedObject.FindProperty("MaxStreamQuality");
|
||||
EditorGUILayout.PropertyField(maxQual);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
sourceList.DoLayoutList();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SerializedProperty videos = serializedObject.FindProperty("Videos");
|
||||
sourceList = new ReorderableList(serializedObject, videos);
|
||||
sourceList.drawElementCallback += (Rect rect, int index, bool active, bool focused) =>
|
||||
{
|
||||
EditorGUI.PropertyField(rect, serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index));
|
||||
};
|
||||
sourceList.elementHeightCallback += (int index) =>
|
||||
{
|
||||
SerializedProperty element = serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index);
|
||||
return EditorGUI.GetPropertyHeight(element);
|
||||
};
|
||||
sourceList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Videos");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae0e74693b7899f47bd98864f94b9311
|
||||
timeCreated: 1499468412
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,116 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
|
||||
[CustomPropertyDrawer(typeof(VRCSDK2.VRC_SyncVideoStream.VideoEntry))]
|
||||
public class CustomVideoStreamEntryDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty source = property.FindPropertyRelative("Source");
|
||||
SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
|
||||
SerializedProperty clip = property.FindPropertyRelative("VideoClip");
|
||||
SerializedProperty url = property.FindPropertyRelative("URL");
|
||||
SerializedProperty live = property.FindPropertyRelative("SyncType");
|
||||
SerializedProperty sync = property.FindPropertyRelative("SyncMinutes");
|
||||
|
||||
return EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ Mathf.Max(EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true), EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true)) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ EditorGUI.GetPropertyHeight(live, new GUIContent("SyncType"), true) + EditorGUIUtility.standardVerticalSpacing
|
||||
+ EditorGUI.GetPropertyHeight(sync, new GUIContent("SyncMinutes"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty source = property.FindPropertyRelative("Source");
|
||||
SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
|
||||
SerializedProperty clip = property.FindPropertyRelative("VideoClip");
|
||||
SerializedProperty url = property.FindPropertyRelative("URL");
|
||||
SerializedProperty live = property.FindPropertyRelative("SyncType");
|
||||
SerializedProperty sync = property.FindPropertyRelative("SyncMinutes");
|
||||
|
||||
EditorGUI.BeginProperty(rect, label, property);
|
||||
float x = rect.x;
|
||||
float y = rect.y;
|
||||
float w = rect.width;
|
||||
float h = EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
VRCSDK2.VRC_EditorTools.FilteredEnumPopup<UnityEngine.Video.VideoSource>(new Rect(x, y, w, h), source, (e) => e == UnityEngine.Video.VideoSource.Url);
|
||||
y += h;
|
||||
|
||||
if (source.enumValueIndex == (int)UnityEngine.Video.VideoSource.Url)
|
||||
{
|
||||
h = EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), url);
|
||||
y += h;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), clip);
|
||||
y += h;
|
||||
}
|
||||
|
||||
h = EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), speed);
|
||||
if (speed.floatValue == 0f)
|
||||
speed.floatValue = 1f;
|
||||
y += h;
|
||||
|
||||
h = EditorGUI.GetPropertyHeight(live, new GUIContent("SyncType"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), live);
|
||||
y += h;
|
||||
|
||||
h = EditorGUI.GetPropertyHeight(sync, new GUIContent("SyncMinutes"), true) + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(new Rect(x, y, w, h), sync);
|
||||
if (sync.floatValue < 1f)
|
||||
sync.floatValue = 0;
|
||||
y += h;
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_SyncVideoStream))]
|
||||
public class SyncVideoStreamEditor : Editor
|
||||
{
|
||||
ReorderableList sourceList;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
SerializedProperty searchRoot = serializedObject.FindProperty("VideoSearchRoot");
|
||||
EditorGUILayout.PropertyField(searchRoot);
|
||||
SerializedProperty maxQual = serializedObject.FindProperty("MaxStreamQuality");
|
||||
EditorGUILayout.PropertyField(maxQual);
|
||||
SerializedProperty autoStart = serializedObject.FindProperty("AutoStart");
|
||||
EditorGUILayout.PropertyField(autoStart);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
sourceList.DoLayoutList();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SerializedProperty videos = serializedObject.FindProperty("Videos");
|
||||
sourceList = new ReorderableList(serializedObject, videos);
|
||||
sourceList.drawElementCallback += (Rect rect, int index, bool active, bool focused) =>
|
||||
{
|
||||
EditorGUI.PropertyField(rect, serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index));
|
||||
};
|
||||
sourceList.elementHeightCallback += (int index) =>
|
||||
{
|
||||
SerializedProperty element = serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index);
|
||||
return EditorGUI.GetPropertyHeight(element);
|
||||
};
|
||||
sourceList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Videos");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f9dccfed0b072f49a307b3f20a7e768
|
||||
timeCreated: 1528745185
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3aecd666943878944a811acb9db2ace7
|
||||
timeCreated: 1474315179
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,216 @@
|
||||
#if VRC_SDK_VRCSDK2
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Build;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRCSDK2.VRC_WebPanel))]
|
||||
public class VRC_WebPanelEditor : Editor
|
||||
{
|
||||
private void InspectorField(string propertyName, string humanName)
|
||||
{
|
||||
SerializedProperty propertyField = serializedObject.FindProperty(propertyName);
|
||||
EditorGUILayout.PropertyField(propertyField, new GUIContent(humanName), true);
|
||||
}
|
||||
|
||||
bool showFiles = false;
|
||||
System.Collections.Generic.List<string> directories = null;
|
||||
System.Collections.Generic.List<string> files = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.HelpBox("Do not play any videos with Web Panels, use VRC_SyncVideoPlayer instead!", MessageType.Error);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("proximity", "Proximity for Interactivity");
|
||||
EditorGUILayout.Space();
|
||||
|
||||
VRCSDK2.VRC_WebPanel web = (VRCSDK2.VRC_WebPanel)target;
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
InspectorField("webRoot", "Web Root");
|
||||
InspectorField("defaultUrl", "URI");
|
||||
|
||||
showFiles = web.webData != null && EditorGUILayout.Foldout(showFiles, web.webData.Count.ToString() + " files imported");
|
||||
if (showFiles)
|
||||
foreach (var file in web.webData)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(file.path);
|
||||
EditorGUILayout.LabelField(file.data.Length.ToString());
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializedProperty webRoot = serializedObject.FindProperty("webRoot");
|
||||
RenderDirectoryList(serializedObject, "webRoot", "Path To Web Content");
|
||||
|
||||
if (string.IsNullOrEmpty(webRoot.stringValue))
|
||||
{
|
||||
InspectorField("defaultUrl", "Start URI");
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderWebRootSelector(serializedObject, "defaultUrl", "Start Page");
|
||||
|
||||
if (VRCSettings.Get().DisplayHelpBoxes)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Javascript API bindings are called with engine.call('methodName', ...), which returns a promise-like object.", MessageType.Info);
|
||||
EditorGUILayout.HelpBox("Javascript may call ListBindings() to discover available API bindings.", MessageType.Info);
|
||||
EditorGUILayout.HelpBox("Javascript may listen for the 'onBindingsReady' event to execute script when the page is fully loaded and API bindings are available.", MessageType.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("cookiesEnabled", "Enable Cookies");
|
||||
|
||||
InspectorField("interactive", "Is Interactive");
|
||||
|
||||
InspectorField("localOnly", "Only Visible Locally");
|
||||
|
||||
if (!web.localOnly)
|
||||
{
|
||||
InspectorField("syncURI", "Synchronize URI");
|
||||
InspectorField("syncInput", "Synchronize Mouse Position");
|
||||
}
|
||||
|
||||
InspectorField("transparent", "Transparent Background");
|
||||
|
||||
InspectorField("autoFormSubmit", "Input should Submit Forms");
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("station", "Interaction Station");
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("cursor", "Mouse Cursor Object");
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("resolutionWidth", "Resolution Width");
|
||||
InspectorField("resolutionHeight", "Resolution Height");
|
||||
InspectorField("displayRegion", "Display Region");
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
InspectorField("extraVideoScreens", "Duplicate Screens");
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void AddSubDirectories(ref System.Collections.Generic.List<string> l, string root)
|
||||
{
|
||||
if (!Directory.Exists(root))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!root.StartsWith(Application.dataPath + Path.DirectorySeparatorChar + "VRCSDK")
|
||||
|| root == Application.dataPath + Path.DirectorySeparatorChar + "VRCSDK" + Path.DirectorySeparatorChar + "Examples" + Path.DirectorySeparatorChar + "Sample Assets" + Path.DirectorySeparatorChar + "WebRoot")
|
||||
l.Add(root.Substring(Application.dataPath.Length));
|
||||
|
||||
string[] subdirectories = Directory.GetDirectories(root);
|
||||
foreach (string dir in subdirectories)
|
||||
AddSubDirectories(ref l, dir);
|
||||
}
|
||||
|
||||
private void RenderDirectoryList(SerializedObject obj, string propertyName, string humanName)
|
||||
{
|
||||
if (directories == null)
|
||||
{
|
||||
directories = new System.Collections.Generic.List<string>();
|
||||
directories.Add("No Web Content Directory");
|
||||
|
||||
AddSubDirectories(ref directories, Application.dataPath + Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
SerializedProperty target = serializedObject.FindProperty(propertyName);
|
||||
|
||||
int selectedIdx = target.stringValue == null ? 0 : directories.IndexOf(target.stringValue);
|
||||
if (selectedIdx < 0 || selectedIdx >= directories.Count)
|
||||
selectedIdx = 0;
|
||||
|
||||
selectedIdx = EditorGUILayout.Popup(humanName, selectedIdx, directories.ToArray());
|
||||
if (selectedIdx > 0 && selectedIdx < directories.Count)
|
||||
target.stringValue = directories[selectedIdx];
|
||||
else
|
||||
target.stringValue = null;
|
||||
}
|
||||
|
||||
private void AddSubDirectoryFiles(ref System.Collections.Generic.List<string> l, string root)
|
||||
{
|
||||
if (!Directory.Exists(root))
|
||||
return;
|
||||
|
||||
string[] files = Directory.GetFiles(root);
|
||||
foreach (string file in files.Where(f => f.ToLower().EndsWith(".html") || f.ToLower().EndsWith(".htm")))
|
||||
l.Add(file.Substring(Application.dataPath.Length));
|
||||
|
||||
string[] subdirectories = Directory.GetDirectories(root);
|
||||
foreach (string dir in subdirectories)
|
||||
AddSubDirectoryFiles(ref l, dir);
|
||||
}
|
||||
|
||||
private void RenderWebRootSelector(SerializedObject obj, string propertyName, string humanName)
|
||||
{
|
||||
SerializedProperty webRoot = obj.FindProperty("webRoot");
|
||||
SerializedProperty target = serializedObject.FindProperty(propertyName);
|
||||
|
||||
if (files == null)
|
||||
{
|
||||
files = new System.Collections.Generic.List<string>();
|
||||
|
||||
AddSubDirectoryFiles(ref files, Application.dataPath + webRoot.stringValue);
|
||||
if (files.Count == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("No suitable html files found in Web Content path.", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int selectedIdx = 0;
|
||||
|
||||
try
|
||||
{
|
||||
System.Uri uri = string.IsNullOrEmpty(target.stringValue) ? null : new Uri(target.stringValue);
|
||||
|
||||
selectedIdx = uri == null ? 0 : files.IndexOf(uri.AbsolutePath.Replace('/', System.IO.Path.DirectorySeparatorChar));
|
||||
if (selectedIdx < 0 || selectedIdx >= files.Count)
|
||||
selectedIdx = 0;
|
||||
}
|
||||
catch { }
|
||||
|
||||
selectedIdx = EditorGUILayout.Popup(humanName, selectedIdx, files.ToArray());
|
||||
if (selectedIdx >= 0 && selectedIdx < files.Count)
|
||||
{
|
||||
System.UriBuilder builder = new UriBuilder()
|
||||
{
|
||||
Scheme = "file",
|
||||
Path = files[selectedIdx].Replace(System.IO.Path.DirectorySeparatorChar, '/'),
|
||||
Host = ""
|
||||
};
|
||||
target.stringValue = builder.Uri.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d09b36020f697be4d9a0f5a6a48cfa83
|
||||
timeCreated: 1457992191
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
#if UNITY_EDITOR && VRC_SDK_VRCSDK2
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRC_YouTubeSync))]
|
||||
public class VRC_YouTubeSyncEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("This component is deprecated, please use the VRC_SyncVideoPlayer component instead.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 764e26c1ca28e2e45a30c778c1955a47
|
||||
timeCreated: 1474675311
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92a4896241003fe4a8fc71eeb5c7268d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
#if VRC_SDK_VRCSDK3
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[CustomEditor(typeof(VRC.SDK3.Components.VRCDestructibleUdon))]
|
||||
public class VRCDestructibleUdonEditor : Editor
|
||||
{
|
||||
VRC.SDK3.Components.VRCDestructibleUdon myTarget;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (myTarget == null)
|
||||
myTarget = (VRC.SDK3.Components.VRCDestructibleUdon)target;
|
||||
}
|
||||
|
||||
string[] UdonMethods = null;
|
||||
string[] UdonVariables = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var udon = myTarget.GetComponent<VRC.Udon.UdonBehaviour>();
|
||||
if (udon != null)
|
||||
{
|
||||
#if VRC_CLIENT
|
||||
myTarget.UdonMethodApplyDamage = EditorGUILayout.TextField("On Apply Damage", myTarget.UdonMethodApplyDamage);
|
||||
myTarget.UdonMethodApplyHealing= EditorGUILayout.TextField("On Apply Healing", myTarget.UdonMethodApplyHealing);
|
||||
myTarget.UdonVariableCurrentHealth= EditorGUILayout.TextField("Current Health Variable", myTarget.UdonVariableCurrentHealth);
|
||||
myTarget.UdonVariableMaxHealth = EditorGUILayout.TextField("On Max Health Variable", myTarget.UdonVariableMaxHealth);
|
||||
#else
|
||||
List<string> methods = new List<string>(udon.GetPrograms());
|
||||
methods.Insert(0, "-none-");
|
||||
myTarget.UdonMethodApplyDamage = DrawUdonProgramPicker("On Apply Damage", myTarget.UdonMethodApplyDamage, methods);
|
||||
myTarget.UdonMethodApplyHealing = DrawUdonProgramPicker("On Apply Healing", myTarget.UdonMethodApplyHealing, methods);
|
||||
List<string> variables = new List<string>(udon.publicVariables.VariableSymbols);
|
||||
variables.Insert(0, "-none-");
|
||||
myTarget.UdonVariableCurrentHealth = DrawUdonProgramPicker("Current Health Variable", myTarget.UdonVariableCurrentHealth, variables);
|
||||
myTarget.UdonVariableMaxHealth = DrawUdonProgramPicker("Max Health Variable", myTarget.UdonVariableMaxHealth, variables);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
string DrawUdonProgramPicker(string title, string current, List<string> choices)
|
||||
{
|
||||
int index = choices.IndexOf(current);
|
||||
if (index == -1)
|
||||
index = 0;
|
||||
int value = EditorGUILayout.Popup(title, index, choices.ToArray());
|
||||
if (value != 0)
|
||||
return choices[value];
|
||||
return current;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d57b23c04034119448f23c5fdbc57662
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
#if VRC_SDK_VRCSDK3
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[CustomEditor(typeof(VRC.SDK3.Components.VRCStation))]
|
||||
public class VRCPlayerStationEditor3 : Editor
|
||||
{
|
||||
VRC.SDK3.Components.VRCStation myTarget;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if(myTarget == null)
|
||||
myTarget = (VRC.SDK3.Components.VRCStation)target;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
myTarget.PlayerMobility = (VRC.SDKBase.VRCStation.Mobility)EditorGUILayout.EnumPopup("Player Mobility", myTarget.PlayerMobility);
|
||||
myTarget.canUseStationFromStation = EditorGUILayout.Toggle("Can Use Station From Station", myTarget.canUseStationFromStation);
|
||||
myTarget.animatorController = (RuntimeAnimatorController) EditorGUILayout.ObjectField("Animator Controller", myTarget.animatorController, typeof(RuntimeAnimatorController), false );
|
||||
myTarget.disableStationExit = EditorGUILayout.Toggle("Disable Station Exit", myTarget.disableStationExit );
|
||||
myTarget.seated = EditorGUILayout.Toggle("Seated", myTarget.seated);
|
||||
myTarget.stationEnterPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Enter Location", myTarget.stationEnterPlayerLocation, typeof(Transform), true);
|
||||
myTarget.stationExitPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Exit Location", myTarget.stationExitPlayerLocation, typeof(Transform), true);
|
||||
myTarget.controlsObject = (VRC.SDKBase.VRC_ObjectApi)EditorGUILayout.ObjectField("API Object", myTarget.controlsObject, typeof(VRC.SDKBase.VRC_ObjectApi), false);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8901d07a685ca424492a3cabff506184
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
#if VRC_SDK_VRCSDK3
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor (typeof(VRC.SDK3.Components.VRCSceneDescriptor))]
|
||||
public class VRCSceneDescriptorEditor3 : Editor
|
||||
{
|
||||
VRC.SDK3.Components.VRCSceneDescriptor sceneDescriptor;
|
||||
VRC.Core.PipelineManager pipelineManager;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if(sceneDescriptor == null)
|
||||
sceneDescriptor = (VRC.SDK3.Components.VRCSceneDescriptor)target;
|
||||
|
||||
if(pipelineManager == null)
|
||||
{
|
||||
pipelineManager = sceneDescriptor.GetComponent<VRC.Core.PipelineManager>();
|
||||
if(pipelineManager == null)
|
||||
sceneDescriptor.gameObject.AddComponent<VRC.Core.PipelineManager>();
|
||||
}
|
||||
|
||||
DrawDefaultInspector();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b2b9ac625bc5b04c887ff9ee9b5fdbe
|
||||
timeCreated: 1450463561
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
#if VRC_SDK_VRCSDK3
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRCSDK2
|
||||
{
|
||||
[CustomEditor(typeof(VRC.SDK3.Components.VRCPickup))]
|
||||
public class VRC_PickupEditor3 : Editor
|
||||
{
|
||||
private void InspectorField(string propertyName, string humanName)
|
||||
{
|
||||
SerializedProperty propertyField = serializedObject.FindProperty(propertyName);
|
||||
EditorGUILayout.PropertyField(propertyField, new GUIContent(humanName), true);
|
||||
}
|
||||
|
||||
private SerializedProperty momentumTransferMethodProperty;
|
||||
private SerializedProperty disallowTheftProperty;
|
||||
private SerializedProperty exactGunProperty;
|
||||
private SerializedProperty exactGripProperty;
|
||||
private SerializedProperty allowManipulationWhenEquippedProperty;
|
||||
private SerializedProperty orientationProperty;
|
||||
private SerializedProperty autoHoldProperty;
|
||||
private SerializedProperty interactionTextProperty;
|
||||
private SerializedProperty useTextProperty;
|
||||
private SerializedProperty throwVelocityBoostMinSpeedProperty;
|
||||
private SerializedProperty throwVelocityBoostScaleProperty;
|
||||
private SerializedProperty pickupableProperty;
|
||||
private SerializedProperty proximityProperty;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
momentumTransferMethodProperty = serializedObject.FindProperty("MomentumTransferMethod");
|
||||
disallowTheftProperty = serializedObject.FindProperty("DisallowTheft");
|
||||
exactGunProperty = serializedObject.FindProperty("ExactGun");
|
||||
exactGripProperty = serializedObject.FindProperty("ExactGrip");
|
||||
allowManipulationWhenEquippedProperty = serializedObject.FindProperty("allowManipulationWhenEquipped");
|
||||
orientationProperty = serializedObject.FindProperty("orientation");
|
||||
autoHoldProperty = serializedObject.FindProperty("AutoHold");
|
||||
interactionTextProperty = serializedObject.FindProperty("InteractionText");
|
||||
useTextProperty = serializedObject.FindProperty("UseText");
|
||||
throwVelocityBoostMinSpeedProperty = serializedObject.FindProperty("ThrowVelocityBoostMinSpeed");
|
||||
throwVelocityBoostScaleProperty = serializedObject.FindProperty("ThrowVelocityBoostScale");
|
||||
pickupableProperty = serializedObject.FindProperty("pickupable");
|
||||
proximityProperty = serializedObject.FindProperty("proximity");
|
||||
|
||||
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 30));
|
||||
|
||||
EditorGUILayout.PropertyField(momentumTransferMethodProperty, new GUIContent("Momentum Transfer Method"));
|
||||
EditorGUILayout.PropertyField(disallowTheftProperty, new GUIContent("Disallow Theft"));
|
||||
EditorGUILayout.PropertyField(exactGunProperty, new GUIContent("Exact Gun"));
|
||||
EditorGUILayout.PropertyField(exactGripProperty, new GUIContent("Exact Grip"));
|
||||
EditorGUILayout.PropertyField(allowManipulationWhenEquippedProperty, new GUIContent("Allow Manipulation When Equipped"));
|
||||
EditorGUILayout.PropertyField(orientationProperty, new GUIContent("Orientation"));
|
||||
EditorGUILayout.PropertyField(autoHoldProperty, new GUIContent("AutoHold", "If the pickup is supposed to be aligned to the hand (i.e. orientation field is set to Gun or Grip), auto-detect means that it will be Equipped(not dropped when they release trigger), otherwise just hold as a normal pickup."));
|
||||
EditorGUILayout.PropertyField(interactionTextProperty, new GUIContent("Interaction Text","Text displayed when user hovers over the pickup."));
|
||||
if (autoHoldProperty.enumValueIndex != (int)VRC.SDK3.Components.VRCPickup.AutoHoldMode.No)
|
||||
EditorGUILayout.PropertyField(useTextProperty, new GUIContent("Use Text", "Text to display describing action for clicking button, when this pickup is already being held."));
|
||||
EditorGUILayout.PropertyField(throwVelocityBoostMinSpeedProperty, new GUIContent("Throw Velocity Boost Min Speed"));
|
||||
EditorGUILayout.PropertyField(throwVelocityBoostScaleProperty, new GUIContent("Throw Velocity Boost Scale"));
|
||||
EditorGUILayout.PropertyField(pickupableProperty, new GUIContent("Pickupable"));
|
||||
EditorGUILayout.PropertyField(proximityProperty, new GUIContent("Proximity"));
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8cc4c1876b26174fbaeb062178a6bda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
#if VRC_SDK_VRCSDK3
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace VRC.SDK3.Editor
|
||||
{
|
||||
[CustomEditor(typeof(VRC.SDK3.Components.VRCSpatialAudioSource))]
|
||||
public class VRC_SpatialAudioSourceEditor3 : UnityEditor.Editor
|
||||
{
|
||||
private bool showAdvancedOptions = false;
|
||||
private SerializedProperty gainProperty;
|
||||
private SerializedProperty nearProperty;
|
||||
private SerializedProperty farProperty;
|
||||
private SerializedProperty volRadiusProperty;
|
||||
private SerializedProperty enableSpatialProperty;
|
||||
private SerializedProperty useCurveProperty;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
gainProperty = serializedObject.FindProperty("Gain");
|
||||
nearProperty = serializedObject.FindProperty("Near");
|
||||
farProperty = serializedObject.FindProperty("Far");
|
||||
volRadiusProperty = serializedObject.FindProperty("VolumetricRadius");
|
||||
enableSpatialProperty = serializedObject.FindProperty("EnableSpatialization");
|
||||
useCurveProperty = serializedObject.FindProperty("UseAudioSourceVolumeCurve");
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
VRC.SDKBase.VRC_SpatialAudioSource target = serializedObject.targetObject as VRC.SDKBase.VRC_SpatialAudioSource;
|
||||
AudioSource source = target.GetComponent<AudioSource>();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.PropertyField(gainProperty, new GUIContent("Gain"));
|
||||
EditorGUILayout.PropertyField(farProperty, new GUIContent("Far"));
|
||||
showAdvancedOptions = EditorGUILayout.Foldout(showAdvancedOptions, "Advanced Options");
|
||||
bool enableSp = enableSpatialProperty.boolValue;
|
||||
if (showAdvancedOptions)
|
||||
{
|
||||
EditorGUILayout.PropertyField(nearProperty, new GUIContent("Near"));
|
||||
EditorGUILayout.PropertyField(volRadiusProperty, new GUIContent("Volumetric Radius"));
|
||||
EditorGUILayout.PropertyField(enableSpatialProperty, new GUIContent("Enable Spatialization"));
|
||||
if (enableSp)
|
||||
EditorGUILayout.PropertyField(useCurveProperty, new GUIContent("Use AudioSource Volume Curve"));
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (source != null)
|
||||
source.spatialize = enableSp;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f8f999a8e1ebee4588f94a8a618d7c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a7071a2aea77fb48bfbe2492a2f911e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
public interface IVRCSdkControlPanelBuilder
|
||||
{
|
||||
void ShowSettingsOptions();
|
||||
bool IsValidBuilder(out string message);
|
||||
void ShowBuilder();
|
||||
void RegisterBuilder(VRCSdkControlPanel baseBuilder);
|
||||
void SelectAllComponents();
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 310a760e312f2984e85eece367bab19a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,246 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC.Core;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
public static VRCSdkControlPanel window;
|
||||
|
||||
[MenuItem("VRChat SDK/Show Control Panel", false, 600)]
|
||||
static void ShowControlPanel()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
VRC.Core.API.SetOnlineMode(true, "vrchat");
|
||||
ConfigManager.RemoteConfig.Init(() => ShowControlPanel());
|
||||
return;
|
||||
}
|
||||
|
||||
window = (VRCSdkControlPanel)EditorWindow.GetWindow(typeof(VRCSdkControlPanel));
|
||||
window.titleContent.text = "VRChat SDK";
|
||||
window.minSize = new Vector2(SdkWindowWidth + 4, 600);
|
||||
window.maxSize = new Vector2(SdkWindowWidth + 4, 2000);
|
||||
window.Init();
|
||||
window.Show();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
public static GUIStyle titleGuiStyle;
|
||||
public static GUIStyle boxGuiStyle;
|
||||
public static GUIStyle infoGuiStyle;
|
||||
public static GUIStyle listButtonStyleEven;
|
||||
public static GUIStyle listButtonStyleOdd;
|
||||
public static GUIStyle listButtonStyleSelected;
|
||||
public static GUIStyle scrollViewSeparatorStyle;
|
||||
public static GUIStyle searchBarStyle;
|
||||
|
||||
void InitializeStyles()
|
||||
{
|
||||
titleGuiStyle = new GUIStyle();
|
||||
titleGuiStyle.fontSize = 15;
|
||||
titleGuiStyle.fontStyle = FontStyle.BoldAndItalic;
|
||||
titleGuiStyle.alignment = TextAnchor.MiddleCenter;
|
||||
titleGuiStyle.wordWrap = true;
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
titleGuiStyle.normal.textColor = Color.white;
|
||||
else
|
||||
titleGuiStyle.normal.textColor = Color.black;
|
||||
|
||||
boxGuiStyle = new GUIStyle();
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
boxGuiStyle.normal.background = CreateBackgroundColorImage(new Color(0.3f, 0.3f, 0.3f));
|
||||
boxGuiStyle.normal.textColor = Color.white;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxGuiStyle.normal.background = CreateBackgroundColorImage(new Color(0.85f, 0.85f, 0.85f));
|
||||
boxGuiStyle.normal.textColor = Color.black;
|
||||
}
|
||||
|
||||
infoGuiStyle = new GUIStyle();
|
||||
infoGuiStyle.wordWrap = true; ;
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
infoGuiStyle.normal.textColor = Color.white;
|
||||
else
|
||||
infoGuiStyle.normal.textColor = Color.black;
|
||||
infoGuiStyle.margin = new RectOffset(10, 10, 10, 10);
|
||||
|
||||
listButtonStyleEven = new GUIStyle();
|
||||
listButtonStyleEven.margin = new RectOffset(0, 0, 0, 0);
|
||||
listButtonStyleEven.border = new RectOffset(0, 0, 0, 0);
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
listButtonStyleEven.normal.textColor = new Color(0.8f, 0.8f, 0.8f);
|
||||
listButtonStyleEven.normal.background = CreateBackgroundColorImage(new Color(0.540f, 0.540f, 0.54f));
|
||||
}
|
||||
else
|
||||
{
|
||||
listButtonStyleEven.normal.textColor = Color.black;
|
||||
listButtonStyleEven.normal.background = CreateBackgroundColorImage(new Color(0.85f, 0.85f, 0.85f));
|
||||
}
|
||||
|
||||
listButtonStyleOdd = new GUIStyle();
|
||||
listButtonStyleOdd.margin = new RectOffset(0, 0, 0, 0);
|
||||
listButtonStyleOdd.border = new RectOffset(0, 0, 0, 0);
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
listButtonStyleOdd.normal.textColor = new Color(0.8f, 0.8f, 0.8f);
|
||||
//listButtonStyleOdd.normal.background = CreateBackgroundColorImage(new Color(0.50f, 0.50f, 0.50f));
|
||||
}
|
||||
else
|
||||
{
|
||||
listButtonStyleOdd.normal.textColor = Color.black;
|
||||
listButtonStyleOdd.normal.background = CreateBackgroundColorImage(new Color(0.90f, 0.90f, 0.90f));
|
||||
}
|
||||
|
||||
listButtonStyleSelected = new GUIStyle();
|
||||
listButtonStyleSelected.normal.textColor = Color.white;
|
||||
listButtonStyleSelected.margin = new RectOffset(0, 0, 0, 0);
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
{
|
||||
listButtonStyleSelected.normal.textColor = new Color(0.8f, 0.8f, 0.8f);
|
||||
listButtonStyleSelected.normal.background = CreateBackgroundColorImage(new Color(0.4f, 0.4f, 0.4f));
|
||||
}
|
||||
else
|
||||
{
|
||||
listButtonStyleSelected.normal.textColor = Color.black;
|
||||
listButtonStyleSelected.normal.background = CreateBackgroundColorImage(new Color(0.75f, 0.75f, 0.75f));
|
||||
}
|
||||
|
||||
scrollViewSeparatorStyle = new GUIStyle("Toolbar");
|
||||
scrollViewSeparatorStyle.fixedWidth = SdkWindowWidth + 10;
|
||||
scrollViewSeparatorStyle.fixedHeight = 4;
|
||||
scrollViewSeparatorStyle.margin.top = 1;
|
||||
|
||||
searchBarStyle = new GUIStyle("Toolbar");
|
||||
searchBarStyle.fixedWidth = SdkWindowWidth;
|
||||
searchBarStyle.fixedHeight = 23;
|
||||
searchBarStyle.padding.top = 3;
|
||||
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
InitializeStyles();
|
||||
ResetIssues();
|
||||
InitAccount();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
OnEnableAccount();
|
||||
AssemblyReloadEvents.afterAssemblyReload += BuilderAssemblyReload;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
AssemblyReloadEvents.afterAssemblyReload -= BuilderAssemblyReload;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
AccountDestroy();
|
||||
}
|
||||
|
||||
public const int SdkWindowWidth = 518;
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
window = (VRCSdkControlPanel)EditorWindow.GetWindow(typeof(VRCSdkControlPanel));
|
||||
InitializeStyles();
|
||||
}
|
||||
|
||||
if (_bannerImage == null)
|
||||
_bannerImage = AssetDatabase.LoadAssetAtPath("Assets/VRCSDK/Dependencies/VRChat/SdkGraphics/SDK_Panel_Banner.png", typeof(Texture2D)) as Texture2D;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Box(_bannerImage);
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
GUILayout.Space(20);
|
||||
EditorGUILayout.LabelField("Unity Application is running ...\nStop it to access the Control Panel", titleGuiStyle, GUILayout.Width(SdkWindowWidth));
|
||||
GUI.enabled = true;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EnvConfig.SetActiveSDKDefines();
|
||||
|
||||
#if VRC_SDK_VRCSDK2
|
||||
VRCSettings.Get().activeWindowPanel = GUILayout.Toolbar(VRCSettings.Get().activeWindowPanel, new string[] { "Authentication", "Builder", "Content Manager", "Settings" }, GUILayout.Width(SdkWindowWidth));
|
||||
int showPanel = VRCSettings.Get().activeWindowPanel;
|
||||
#elif VRC_SDK_VRCSDK3
|
||||
VRC.SDK3.Editor.VRCSettings.Get().activeWindowPanel = GUILayout.Toolbar(VRC.SDK3.Editor.VRCSettings.Get().activeWindowPanel, new string[] { "Authentication", "Builder", "Content Manager", "Settings" }, GUILayout.Width(SdkWindowWidth));
|
||||
int showPanel = VRC.SDK3.Editor.VRCSettings.Get().activeWindowPanel;
|
||||
#else
|
||||
int showPanel = 0;
|
||||
#endif
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (APIUser.IsLoggedInWithCredentials == false && showPanel != 3)
|
||||
showPanel = 0;
|
||||
|
||||
switch (showPanel)
|
||||
{
|
||||
case 1:
|
||||
ShowBuilders();
|
||||
break;
|
||||
case 2:
|
||||
ShowContent();
|
||||
break;
|
||||
case 3:
|
||||
ShowSettings();
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
ShowAccount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[UnityEditor.Callbacks.PostProcessScene]
|
||||
static void OnPostProcessScene()
|
||||
{
|
||||
if (window != null)
|
||||
window.Reset();
|
||||
}
|
||||
|
||||
private void OnFocus()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
ResetIssues();
|
||||
// style backgrounds may be nulled on scene load. detect if so has happened
|
||||
if((boxGuiStyle != null) && (boxGuiStyle.normal.background == null))
|
||||
InitializeStyles();
|
||||
}
|
||||
|
||||
[UnityEditor.Callbacks.DidReloadScripts(int.MaxValue)]
|
||||
static void DidReloadScripts()
|
||||
{
|
||||
RefreshApiUrlSetting();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20b4cdbdda9655947aab6f8f2c90690f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,594 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using VRC.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
static bool isInitialized = false;
|
||||
static string clientInstallPath;
|
||||
static bool signingIn = false;
|
||||
static string error = null;
|
||||
|
||||
public static bool FutureProofPublishEnabled { get { return UnityEditor.EditorPrefs.GetBool("futureProofPublish", DefaultFutureProofPublishEnabled); } }
|
||||
//public static bool DefaultFutureProofPublishEnabled { get { return !SDKClientUtilities.IsInternalSDK(); } }
|
||||
public static bool DefaultFutureProofPublishEnabled { get { return true; } }
|
||||
|
||||
static string storedUsername
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("sdk#username"))
|
||||
return EditorPrefs.GetString("sdk#username");
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("sdk#username", value);
|
||||
if (string.IsNullOrEmpty(value))
|
||||
EditorPrefs.DeleteKey("sdk#username");
|
||||
}
|
||||
}
|
||||
|
||||
static string storedPassword
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorPrefs.HasKey("sdk#password"))
|
||||
return EditorPrefs.GetString("sdk#password");
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
EditorPrefs.SetString("sdk#password", value);
|
||||
if (string.IsNullOrEmpty(value))
|
||||
EditorPrefs.DeleteKey("sdk#password");
|
||||
}
|
||||
}
|
||||
|
||||
static string _username = null;
|
||||
static string _password = null;
|
||||
|
||||
static string username
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_username))
|
||||
return _username;
|
||||
else
|
||||
_username = storedUsername;
|
||||
return _username;
|
||||
}
|
||||
set
|
||||
{
|
||||
_username = value;
|
||||
}
|
||||
}
|
||||
|
||||
static string password
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_password))
|
||||
return _password;
|
||||
else
|
||||
_password = storedPassword;
|
||||
return _password;
|
||||
}
|
||||
set
|
||||
{
|
||||
_password = value;
|
||||
}
|
||||
}
|
||||
|
||||
static ApiServerEnvironment serverEnvironment
|
||||
{
|
||||
get
|
||||
{
|
||||
ApiServerEnvironment env = ApiServerEnvironment.Release;
|
||||
try
|
||||
{
|
||||
env = (ApiServerEnvironment)System.Enum.Parse(typeof(ApiServerEnvironment), UnityEditor.EditorPrefs.GetString("VRC_ApiServerEnvironment", env.ToString()));
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("Invalid server environment name - " + e.ToString());
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
set
|
||||
{
|
||||
UnityEditor.EditorPrefs.SetString("VRC_ApiServerEnvironment", value.ToString());
|
||||
|
||||
API.SetApiUrlFromEnvironment(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnableAccount()
|
||||
{
|
||||
entered2faCodeIsInvalid = false;
|
||||
warningIconGraphic = Resources.Load("2FAIcons/SDK_Warning_Triangle_icon") as Texture2D;
|
||||
}
|
||||
|
||||
public static void RefreshApiUrlSetting()
|
||||
{
|
||||
// this forces the static api url variable to be reset from the server environment set in editor prefs.
|
||||
// needed because the static variable states get cleared when entering / exiting play mode
|
||||
ApiServerEnvironment env = serverEnvironment;
|
||||
serverEnvironment = env;
|
||||
}
|
||||
|
||||
public static void InitAccount()
|
||||
{
|
||||
if (isInitialized)
|
||||
return;
|
||||
|
||||
if (!APIUser.IsLoggedInWithCredentials && ApiCredentials.Load())
|
||||
APIUser.FetchCurrentUser((c) => AnalyticsSDK.LoggedInUserChanged(c.Model as APIUser), null);
|
||||
|
||||
clientInstallPath = SDKClientUtilities.GetSavedVRCInstallPath();
|
||||
if (string.IsNullOrEmpty(clientInstallPath))
|
||||
clientInstallPath = SDKClientUtilities.LoadRegistryVRCInstallPath();
|
||||
|
||||
signingIn = false;
|
||||
isInitialized = true;
|
||||
|
||||
ClearContent();
|
||||
}
|
||||
|
||||
public static bool OnShowStatus()
|
||||
{
|
||||
API.SetOnlineMode(true);
|
||||
|
||||
SignIn(false);
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
if (APIUser.IsLoggedInWithCredentials)
|
||||
{
|
||||
OnCreatorStatusGUI();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
return APIUser.IsLoggedInWithCredentials;
|
||||
}
|
||||
|
||||
static bool OnAccountGUI()
|
||||
{
|
||||
const int ACCOUNT_LOGIN_BORDER_SPACING = 20;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Space(ACCOUNT_LOGIN_BORDER_SPACING);
|
||||
GUILayout.BeginVertical("Account", "window", GUILayout.Height(150), GUILayout.Width(340));
|
||||
|
||||
if (signingIn)
|
||||
{
|
||||
EditorGUILayout.LabelField("Signing in as " + username + ".");
|
||||
}
|
||||
else if (APIUser.IsLoggedInWithCredentials)
|
||||
{
|
||||
if (Status != "Connected")
|
||||
EditorGUILayout.LabelField(Status);
|
||||
|
||||
OnCreatorStatusGUI();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("");
|
||||
|
||||
if (GUILayout.Button("Logout"))
|
||||
{
|
||||
storedUsername = username = null;
|
||||
storedPassword = password = null;
|
||||
|
||||
VRC.Tools.ClearCookies();
|
||||
APIUser.Logout();
|
||||
ClearContent();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
InitAccount();
|
||||
|
||||
ApiServerEnvironment newEnv = ApiServerEnvironment.Release;
|
||||
#if VRC_SDK_VRCSDK2
|
||||
if (VRCSettings.Get().DisplayAdvancedSettings)
|
||||
newEnv = (ApiServerEnvironment)EditorGUILayout.EnumPopup("Use API", serverEnvironment);
|
||||
#elif VRC_SDK_VRCSDK3
|
||||
if (VRC.SDK3.Editor.VRCSettings.Get().DisplayAdvancedSettings)
|
||||
newEnv = (ApiServerEnvironment)EditorGUILayout.EnumPopup("Use API", serverEnvironment);
|
||||
#endif
|
||||
if (serverEnvironment != newEnv)
|
||||
serverEnvironment = newEnv;
|
||||
|
||||
username = EditorGUILayout.TextField("Username", username);
|
||||
password = EditorGUILayout.PasswordField("Password", password);
|
||||
|
||||
if (GUILayout.Button("Sign In"))
|
||||
SignIn(true);
|
||||
if (GUILayout.Button("Sign up"))
|
||||
Application.OpenURL("http://vrchat.com/register");
|
||||
}
|
||||
|
||||
if (showTwoFactorAuthenticationEntry)
|
||||
{
|
||||
OnTwoFactorAuthenticationGUI();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(ACCOUNT_LOGIN_BORDER_SPACING);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return !signingIn;
|
||||
}
|
||||
|
||||
static void OnCreatorStatusGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Logged in as:", APIUser.CurrentUser.displayName);
|
||||
|
||||
//if (SDKClientUtilities.IsInternalSDK())
|
||||
// EditorGUILayout.LabelField("Developer Status: ", APIUser.CurrentUser.developerType.ToString());
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
EditorGUILayout.LabelField("World Creator Status: ", APIUser.CurrentUser.canPublishWorlds ? "Allowed to publish worlds" : "Not yet allowed to publish worlds");
|
||||
EditorGUILayout.LabelField("Avatar Creator Status: ", APIUser.CurrentUser.canPublishAvatars ? "Allowed to publish avatars" : "Not yet allowed to publish avatars");
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
if (!APIUser.CurrentUser.canPublishAllContent)
|
||||
{
|
||||
if (GUILayout.Button("More Info..."))
|
||||
{
|
||||
VRCSdkControlPanel.ShowContentPublishPermissionsDialog();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void ShowAccount()
|
||||
{
|
||||
if (VRC.Core.ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
if (VRC.Core.ConfigManager.RemoteConfig.HasKey("sdkUnityVersion"))
|
||||
{
|
||||
string sdkUnityVersion = VRC.Core.ConfigManager.RemoteConfig.GetString("sdkUnityVersion");
|
||||
if (string.IsNullOrEmpty(sdkUnityVersion))
|
||||
EditorGUILayout.LabelField("Could not fetch remote config.");
|
||||
else if (Application.unityVersion != sdkUnityVersion)
|
||||
{
|
||||
EditorGUILayout.LabelField("Unity Version", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("Wrong Unity version. Please use " + sdkUnityVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VRC.Core.API.SetOnlineMode(true, "vrchat");
|
||||
VRC.Core.ConfigManager.RemoteConfig.Init();
|
||||
}
|
||||
|
||||
OnAccountGUI();
|
||||
}
|
||||
|
||||
|
||||
private const string TWO_FACTOR_AUTHENTICATION_HELP_URL = "https://docs.vrchat.com/docs/setup-2fa";
|
||||
|
||||
private const string ENTER_2FA_CODE_TITLE_STRING = "Enter a numeric code from your authenticator app (or one of your saved recovery codes).";
|
||||
private const string ENTER_2FA_CODE_LABEL_STRING = "Code:";
|
||||
|
||||
private const string CHECKING_2FA_CODE_STRING = "Checking code...";
|
||||
private const string ENTER_2FA_CODE_INVALID_CODE_STRING = "Invalid Code";
|
||||
|
||||
private const string ENTER_2FA_CODE_VERIFY_STRING = "Verify";
|
||||
private const string ENTER_2FA_CODE_CANCEL_STRING = "Cancel";
|
||||
private const string ENTER_2FA_CODE_HELP_STRING = "Help";
|
||||
|
||||
private const int WARNING_ICON_SIZE = 60;
|
||||
private const int WARNING_FONT_HEIGHT = 18;
|
||||
|
||||
static private Texture2D warningIconGraphic;
|
||||
|
||||
static bool entered2faCodeIsInvalid;
|
||||
static bool authorizationCodeWasVerified;
|
||||
|
||||
static private int previousAuthenticationCodeLength = 0;
|
||||
static bool checkingCode;
|
||||
static string authenticationCode = "";
|
||||
|
||||
static System.Action onAuthenticationVerifiedAction;
|
||||
|
||||
static bool _showTwoFactorAuthenticationEntry = false;
|
||||
|
||||
static bool showTwoFactorAuthenticationEntry
|
||||
{
|
||||
get
|
||||
{
|
||||
return _showTwoFactorAuthenticationEntry;
|
||||
}
|
||||
set
|
||||
{
|
||||
_showTwoFactorAuthenticationEntry = value;
|
||||
authenticationCode = "";
|
||||
if (!_showTwoFactorAuthenticationEntry && !authorizationCodeWasVerified)
|
||||
Logout();
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsValidAuthenticationCodeFormat()
|
||||
{
|
||||
bool isValid2faAuthenticationCode = false;
|
||||
|
||||
if (!string.IsNullOrEmpty(authenticationCode))
|
||||
{
|
||||
// check if the input is a valid 6-digit numberic code (ignoring spaces)
|
||||
Regex rx = new Regex(@"^(\s*\d\s*){6}$", RegexOptions.Compiled);
|
||||
MatchCollection matches6DigitCode = rx.Matches(authenticationCode);
|
||||
isValid2faAuthenticationCode = (matches6DigitCode.Count == 1);
|
||||
}
|
||||
|
||||
return isValid2faAuthenticationCode;
|
||||
}
|
||||
|
||||
static bool IsValidRecoveryCodeFormat()
|
||||
{
|
||||
bool isValid2faRecoveryCode = false;
|
||||
|
||||
if (!string.IsNullOrEmpty(authenticationCode))
|
||||
{
|
||||
// check if the input is a valid 8-digit alpha-numberic code (format xxxx-xxxx) "-" is optional & ignore any spaces
|
||||
// OTP codes also exclude the letters i,l,o and the digit 1 to prevent any confusion
|
||||
Regex rx = new Regex(@"^(\s*[a-hj-km-np-zA-HJ-KM-NP-Z02-9]\s*){4}-?(\s*[a-hj-km-np-zA-HJ-KM-NP-Z02-9]\s*){4}$", RegexOptions.Compiled);
|
||||
MatchCollection matchesRecoveryCode = rx.Matches(authenticationCode);
|
||||
isValid2faRecoveryCode = (matchesRecoveryCode.Count == 1);
|
||||
}
|
||||
|
||||
return isValid2faRecoveryCode;
|
||||
}
|
||||
|
||||
static void OnTwoFactorAuthenticationGUI()
|
||||
{
|
||||
const int ENTER_2FA_CODE_BORDER_SIZE = 20;
|
||||
const int ENTER_2FA_CODE_BUTTON_WIDTH = 260;
|
||||
const int ENTER_2FA_CODE_VERIFY_BUTTON_WIDTH = ENTER_2FA_CODE_BUTTON_WIDTH / 2;
|
||||
const int ENTER_2FA_CODE_ENTRY_REGION_WIDTH = 130;
|
||||
const int ENTER_2FA_CODE_MIN_WINDOW_WIDTH = ENTER_2FA_CODE_VERIFY_BUTTON_WIDTH + ENTER_2FA_CODE_ENTRY_REGION_WIDTH + (ENTER_2FA_CODE_BORDER_SIZE * 3);
|
||||
|
||||
bool isValidAuthenticationCode = IsValidAuthenticationCodeFormat();
|
||||
|
||||
|
||||
// Invalid code text
|
||||
if (entered2faCodeIsInvalid)
|
||||
{
|
||||
GUIStyle s = new GUIStyle(EditorStyles.label);
|
||||
s.alignment = TextAnchor.UpperLeft;
|
||||
s.normal.textColor = Color.red;
|
||||
s.fontSize = WARNING_FONT_HEIGHT;
|
||||
s.padding = new RectOffset(0, 0, (WARNING_ICON_SIZE - s.fontSize) / 2, 0);
|
||||
s.fixedHeight = WARNING_ICON_SIZE;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
var textDimensions = s.CalcSize(new GUIContent(ENTER_2FA_CODE_INVALID_CODE_STRING));
|
||||
GUILayout.Label(new GUIContent(warningIconGraphic), GUILayout.Width(WARNING_ICON_SIZE), GUILayout.Height(WARNING_ICON_SIZE));
|
||||
EditorGUILayout.LabelField(ENTER_2FA_CODE_INVALID_CODE_STRING, s, GUILayout.Width(textDimensions.x));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if (checkingCode)
|
||||
{
|
||||
// Display checking code message
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUIStyle s = new GUIStyle(EditorStyles.label);
|
||||
s.alignment = TextAnchor.MiddleCenter;
|
||||
s.fixedHeight = WARNING_ICON_SIZE;
|
||||
EditorGUILayout.LabelField(CHECKING_2FA_CODE_STRING, s, GUILayout.Height(WARNING_ICON_SIZE));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(ENTER_2FA_CODE_BORDER_SIZE);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUIStyle titleStyle = new GUIStyle(EditorStyles.label);
|
||||
titleStyle.alignment = TextAnchor.MiddleCenter;
|
||||
titleStyle.wordWrap = true;
|
||||
EditorGUILayout.LabelField(ENTER_2FA_CODE_TITLE_STRING, titleStyle, GUILayout.Width(ENTER_2FA_CODE_MIN_WINDOW_WIDTH - (2 * ENTER_2FA_CODE_BORDER_SIZE)), GUILayout.Height(WARNING_ICON_SIZE), GUILayout.ExpandHeight(true));
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Space(ENTER_2FA_CODE_BORDER_SIZE);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(ENTER_2FA_CODE_BORDER_SIZE);
|
||||
GUILayout.FlexibleSpace();
|
||||
Vector2 size = EditorStyles.boldLabel.CalcSize(new GUIContent(ENTER_2FA_CODE_LABEL_STRING));
|
||||
EditorGUILayout.LabelField(ENTER_2FA_CODE_LABEL_STRING, EditorStyles.boldLabel, GUILayout.MaxWidth(size.x));
|
||||
authenticationCode = EditorGUILayout.TextField(authenticationCode);
|
||||
|
||||
// Verify 2FA code button
|
||||
if (GUILayout.Button(ENTER_2FA_CODE_VERIFY_STRING, GUILayout.Width(ENTER_2FA_CODE_VERIFY_BUTTON_WIDTH)))
|
||||
{
|
||||
checkingCode = true;
|
||||
APIUser.VerifyTwoFactorAuthCode(authenticationCode, isValidAuthenticationCode ? API2FA.TIME_BASED_ONE_TIME_PASSWORD_AUTHENTICATION : API2FA.ONE_TIME_PASSWORD_AUTHENTICATION, username, password,
|
||||
delegate
|
||||
{
|
||||
// valid 2FA code submitted
|
||||
entered2faCodeIsInvalid = false;
|
||||
authorizationCodeWasVerified = true;
|
||||
checkingCode = false;
|
||||
showTwoFactorAuthenticationEntry = false;
|
||||
if (null != onAuthenticationVerifiedAction)
|
||||
onAuthenticationVerifiedAction();
|
||||
},
|
||||
delegate
|
||||
{
|
||||
entered2faCodeIsInvalid = true;
|
||||
checkingCode = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Space(ENTER_2FA_CODE_BORDER_SIZE);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
// after user has entered an invalid code causing the invalid code message to be displayed,
|
||||
// edit the code will change it's length meaning it is invalid format, so we can clear the invalid code setting until they resubmit
|
||||
if (previousAuthenticationCodeLength != authenticationCode.Length)
|
||||
{
|
||||
previousAuthenticationCodeLength = authenticationCode.Length;
|
||||
entered2faCodeIsInvalid = false;
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Space(ENTER_2FA_CODE_BORDER_SIZE);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
// Two-Factor Authentication Help button
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(ENTER_2FA_CODE_HELP_STRING))
|
||||
{
|
||||
Application.OpenURL(TWO_FACTOR_AUTHENTICATION_HELP_URL);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// Cancel button
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(ENTER_2FA_CODE_CANCEL_STRING))
|
||||
{
|
||||
showTwoFactorAuthenticationEntry = false;
|
||||
Logout();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static string Status
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!APIUser.IsLoggedInWithCredentials)
|
||||
return error == null ? "Please log in." : "Error in authenticating: " + error;
|
||||
if (signingIn)
|
||||
return "Logging in.";
|
||||
else
|
||||
{
|
||||
if( serverEnvironment == ApiServerEnvironment.Dev )
|
||||
return "Connected to " + serverEnvironment.ToString();
|
||||
return "Connected";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnAuthenticationCompleted()
|
||||
{
|
||||
AttemptLogin();
|
||||
}
|
||||
|
||||
private static void AttemptLogin()
|
||||
{
|
||||
APIUser.Login(username, password,
|
||||
delegate (ApiModelContainer<APIUser> c)
|
||||
{
|
||||
APIUser user = c.Model as APIUser;
|
||||
if (c.Cookies.ContainsKey("auth"))
|
||||
ApiCredentials.Set(user.username, username, "vrchat", c.Cookies["auth"]);
|
||||
else
|
||||
ApiCredentials.SetHumanName(user.username);
|
||||
signingIn = false;
|
||||
error = null;
|
||||
storedUsername = username;
|
||||
storedPassword = password;
|
||||
AnalyticsSDK.LoggedInUserChanged(user);
|
||||
|
||||
if (!APIUser.CurrentUser.canPublishAllContent)
|
||||
{
|
||||
if (UnityEditor.SessionState.GetString("HasShownContentPublishPermissionsDialogForUser", "") != user.id)
|
||||
{
|
||||
UnityEditor.SessionState.SetString("HasShownContentPublishPermissionsDialogForUser", user.id);
|
||||
VRCSdkControlPanel.ShowContentPublishPermissionsDialog();
|
||||
}
|
||||
}
|
||||
},
|
||||
delegate (ApiModelContainer<APIUser> c)
|
||||
{
|
||||
Logout();
|
||||
error = c.Error;
|
||||
VRC.Core.Logger.Log("Error logging in: " + error);
|
||||
},
|
||||
delegate (ApiModelContainer<API2FA> c)
|
||||
{
|
||||
if (c.Cookies.ContainsKey("auth"))
|
||||
ApiCredentials.Set(username, username, "vrchat", c.Cookies["auth"]);
|
||||
showTwoFactorAuthenticationEntry = true;
|
||||
onAuthenticationVerifiedAction = OnAuthenticationCompleted;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static object syncObject = new object();
|
||||
private static void SignIn(bool explicitAttempt)
|
||||
{
|
||||
lock (syncObject)
|
||||
{
|
||||
if (signingIn
|
||||
|| APIUser.IsLoggedInWithCredentials
|
||||
|| (!explicitAttempt && string.IsNullOrEmpty(storedUsername))
|
||||
|| (!explicitAttempt && string.IsNullOrEmpty(storedPassword)))
|
||||
return;
|
||||
|
||||
signingIn = true;
|
||||
}
|
||||
|
||||
InitAccount();
|
||||
|
||||
AttemptLogin();
|
||||
}
|
||||
|
||||
public static void Logout()
|
||||
{
|
||||
signingIn = false;
|
||||
storedUsername = null;
|
||||
storedPassword = null;
|
||||
VRC.Tools.ClearCookies();
|
||||
APIUser.Logout();
|
||||
}
|
||||
|
||||
private void AccountDestroy()
|
||||
{
|
||||
signingIn = false;
|
||||
isInitialized = false;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5066cd5c1cc208143a1253cac821714a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,639 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using VRCSDK2.Validation.Performance;
|
||||
using Object = UnityEngine.Object;
|
||||
using VRC.SDK3.Editor;
|
||||
using VRC.SDKBase.Editor;
|
||||
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
public static System.Action _EnableSpatialization = null; // assigned in AutoAddONSPAudioSourceComponents
|
||||
|
||||
public const string AVATAR_OPTIMIZATION_TIPS_URL = "https://docs.vrchat.com/docs/avatar-optimizing-tips";
|
||||
public const string AVATAR_RIG_REQUIREMENTS_URL = "https://docs.vrchat.com/docs/rig-requirements";
|
||||
|
||||
const string kCantPublishContent = "Before you can upload avatars or worlds, you will need to spend some time in VRChat.";
|
||||
const string kCantPublishAvatars = "Before you can upload avatars, you will need to spend some time in VRChat.";
|
||||
const string kCantPublishWorlds = "Before you can upload worlds, you will need to spend some time in VRChat.";
|
||||
private const string FIX_ISSUES_TO_BUILD_OR_TEST_WARNING_STRING = "You must address the above issues before you can build or test this content!";
|
||||
|
||||
static Texture _perfIcon_Excellent;
|
||||
static Texture _perfIcon_Good;
|
||||
static Texture _perfIcon_Medium;
|
||||
static Texture _perfIcon_Poor;
|
||||
static Texture _perfIcon_VeryPoor;
|
||||
static Texture _bannerImage;
|
||||
|
||||
public void ResetIssues()
|
||||
{
|
||||
GUIErrors.Clear();
|
||||
GUIInfos.Clear();
|
||||
GUIWarnings.Clear();
|
||||
GUILinks.Clear();
|
||||
GUIStats.Clear();
|
||||
CheckedForIssues = false;
|
||||
}
|
||||
|
||||
public bool CheckedForIssues { get; set; } = false;
|
||||
|
||||
class Issue
|
||||
{
|
||||
public string issueText;
|
||||
public System.Action showThisIssue;
|
||||
public System.Action fixThisIssue;
|
||||
public PerformanceRating performanceRating;
|
||||
|
||||
public Issue(string text, System.Action show, System.Action fix, PerformanceRating rating = PerformanceRating.None)
|
||||
{
|
||||
issueText = text;
|
||||
showThisIssue = show;
|
||||
fixThisIssue = fix;
|
||||
performanceRating = rating;
|
||||
}
|
||||
|
||||
public class Equality : IEqualityComparer<Issue>, IComparer<Issue>
|
||||
{
|
||||
public bool Equals(Issue b1, Issue b2)
|
||||
{
|
||||
return (b1.issueText == b2.issueText);
|
||||
}
|
||||
public int Compare(Issue b1, Issue b2)
|
||||
{
|
||||
return string.Compare(b1.issueText, b2.issueText);
|
||||
}
|
||||
public int GetHashCode(Issue bx)
|
||||
{
|
||||
return bx.issueText.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<Object, List<Issue>> GUIErrors = new Dictionary<Object, List<Issue>>();
|
||||
Dictionary<Object, List<Issue>> GUIWarnings = new Dictionary<Object, List<Issue>>();
|
||||
Dictionary<Object, List<Issue>> GUIInfos = new Dictionary<Object, List<Issue>>();
|
||||
Dictionary<Object, List<Issue>> GUILinks = new Dictionary<Object, List<Issue>>();
|
||||
Dictionary<Object, List<Issue>> GUIStats = new Dictionary<Object, List<Issue>>();
|
||||
|
||||
public bool NoGuiErrorsOrIssues()
|
||||
{
|
||||
return GUIErrors.Count == 0 && CheckedForIssues;
|
||||
}
|
||||
|
||||
void AddToReport(Dictionary<Object, List<Issue>> report, Object subject, string output, System.Action show, System.Action fix)
|
||||
{
|
||||
if (subject == null)
|
||||
subject = this;
|
||||
if (!report.ContainsKey(subject))
|
||||
report.Add(subject, new List<Issue>());
|
||||
|
||||
var issue = new Issue(output, show, fix);
|
||||
if (!report[subject].Contains(issue, new Issue.Equality()))
|
||||
{
|
||||
report[subject].Add(issue);
|
||||
report[subject].Sort(new Issue.Equality());
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderAssemblyReload()
|
||||
{
|
||||
ResetIssues();
|
||||
}
|
||||
|
||||
public void OnGUIError(Object subject, string output, System.Action show, System.Action fix)
|
||||
{
|
||||
AddToReport(GUIErrors, subject, output, show, fix);
|
||||
}
|
||||
|
||||
public void OnGUIWarning(Object subject, string output, System.Action show, System.Action fix)
|
||||
{
|
||||
AddToReport(GUIWarnings, subject, output, show, fix);
|
||||
}
|
||||
|
||||
public void OnGUIInformation(Object subject, string output)
|
||||
{
|
||||
AddToReport(GUIInfos, subject, output, null, null);
|
||||
}
|
||||
|
||||
public void OnGUILink(Object subject, string output, string link)
|
||||
{
|
||||
AddToReport(GUILinks, subject, output + "\n" + link, null, null);
|
||||
}
|
||||
|
||||
public void OnGUIStat(Object subject, string output, PerformanceRating rating, System.Action show, System.Action fix)
|
||||
{
|
||||
if (subject == null)
|
||||
subject = this;
|
||||
if (!GUIStats.ContainsKey(subject))
|
||||
GUIStats.Add(subject, new List<Issue>());
|
||||
GUIStats[subject].Add(new Issue(output, show, fix, rating));
|
||||
}
|
||||
|
||||
public int triggerLineMode
|
||||
{
|
||||
get { return EditorPrefs.GetInt("VRC.SDKBase_triggerLineMode", 0); }
|
||||
set { EditorPrefs.SetInt("VRC.SDKBase_triggerLineMode", value); }
|
||||
}
|
||||
|
||||
private void ShowSettingsOptionsForBuilders()
|
||||
{
|
||||
if (_sdkBuilders == null)
|
||||
{
|
||||
PopulateSdkBuilders();
|
||||
}
|
||||
for (int i = 0; i < _sdkBuilders.Length; i++)
|
||||
{
|
||||
IVRCSdkControlPanelBuilder builder = _sdkBuilders[i];
|
||||
builder.ShowSettingsOptions();
|
||||
if (i < _sdkBuilders.Length - 1)
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IVRCSdkControlPanelBuilder[] _sdkBuilders;
|
||||
|
||||
private static List<Type> GetSdkBuilderTypesFromAttribute()
|
||||
{
|
||||
Type sdkBuilderInterfaceType = typeof(IVRCSdkControlPanelBuilder);
|
||||
Type sdkBuilderAttributeType = typeof(VRCSdkControlPanelBuilderAttribute);
|
||||
|
||||
List<Type> moduleTypesFromAttribute = new List<Type>();
|
||||
foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
VRCSdkControlPanelBuilderAttribute[] sdkBuilderAttributes;
|
||||
try
|
||||
{
|
||||
sdkBuilderAttributes = (VRCSdkControlPanelBuilderAttribute[])assembly.GetCustomAttributes(sdkBuilderAttributeType, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
sdkBuilderAttributes = new VRCSdkControlPanelBuilderAttribute[0];
|
||||
}
|
||||
|
||||
foreach(VRCSdkControlPanelBuilderAttribute udonWrapperModuleAttribute in sdkBuilderAttributes)
|
||||
{
|
||||
if(udonWrapperModuleAttribute == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!sdkBuilderInterfaceType.IsAssignableFrom(udonWrapperModuleAttribute.Type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
moduleTypesFromAttribute.Add(udonWrapperModuleAttribute.Type);
|
||||
}
|
||||
}
|
||||
|
||||
return moduleTypesFromAttribute;
|
||||
}
|
||||
|
||||
private void PopulateSdkBuilders()
|
||||
{
|
||||
if (_sdkBuilders != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<IVRCSdkControlPanelBuilder> builders = new List<IVRCSdkControlPanelBuilder>();
|
||||
foreach (Type type in GetSdkBuilderTypesFromAttribute())
|
||||
{
|
||||
IVRCSdkControlPanelBuilder builder = (IVRCSdkControlPanelBuilder)Activator.CreateInstance(type);
|
||||
builder.RegisterBuilder(this);
|
||||
builders.Add(builder);
|
||||
}
|
||||
_sdkBuilders = builders.ToArray();
|
||||
}
|
||||
|
||||
void ShowBuilders()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
if (VRC.Core.ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
string sdkUnityVersion = VRC.Core.ConfigManager.RemoteConfig.GetString("sdkUnityVersion");
|
||||
if (Application.unityVersion != sdkUnityVersion)
|
||||
{
|
||||
OnGUIWarning(null, "You are not using the recommended Unity version for the VRChat SDK. Content built with this version may not work correctly. Please use Unity " + sdkUnityVersion,
|
||||
null,
|
||||
() => { Application.OpenURL("https://unity3d.com/get-unity/download/archive"); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK2) && VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK3))
|
||||
{
|
||||
List<Component> sdk2Components = VRCSdk3Analysis.GetSDKInScene(VRCSdk3Analysis.SdkVersion.VRCSDK2);
|
||||
List<Component> sdk3Components = VRCSdk3Analysis.GetSDKInScene(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
if (sdk2Components.Count > 0 && sdk3Components.Count > 0)
|
||||
{
|
||||
OnGUIError(null,
|
||||
"This scene contains components from the VRChat SDK version 2 and version 3. Version two elements will have to be replaced with their version 3 counterparts to build with SDK3 and UDON.",
|
||||
() => { Selection.objects = sdk2Components.ToArray(); },
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Lightmapping.giWorkflowMode == Lightmapping.GIWorkflowMode.Iterative)
|
||||
{
|
||||
OnGUIWarning(null,
|
||||
"Automatic lightmap generation is enabled, which may stall the Unity build process. Before building and uploading, consider turning off 'Auto Generate' at the bottom of the Lighting Window.",
|
||||
() =>
|
||||
{
|
||||
EditorWindow lightingWindow = GetLightingWindow();
|
||||
if (lightingWindow)
|
||||
{
|
||||
lightingWindow.Show();
|
||||
lightingWindow.Focus();
|
||||
}
|
||||
},
|
||||
() =>
|
||||
{
|
||||
Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;
|
||||
EditorWindow lightingWindow = GetLightingWindow();
|
||||
if (!lightingWindow) return;
|
||||
lightingWindow.Repaint();
|
||||
Focus();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
PopulateSdkBuilders();
|
||||
IVRCSdkControlPanelBuilder selectedBuilder = null;
|
||||
string errorMessage = null;
|
||||
foreach (IVRCSdkControlPanelBuilder sdkBuilder in _sdkBuilders)
|
||||
{
|
||||
if (!sdkBuilder.IsValidBuilder(out string message))
|
||||
{
|
||||
if (selectedBuilder == null)
|
||||
{
|
||||
errorMessage = message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedBuilder == null)
|
||||
{
|
||||
selectedBuilder = sdkBuilder;
|
||||
errorMessage = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage =
|
||||
"A Unity scene cannot contain a VRChat Scene Descriptor and also contain VRChat Avatar Descriptors";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectedBuilder == null)
|
||||
{
|
||||
#if VRC_SDK_VRCSDK2
|
||||
EditorGUILayout.LabelField("A VRC_SceneDescriptor or VRC_AvatarDescriptor\nis required to build VRChat SDK Content", titleGuiStyle, GUILayout.Width(SdkWindowWidth));
|
||||
#elif VRC_SDK_VRCSDK3
|
||||
EditorGUILayout.LabelField("A VRCSceneDescriptor or VRCAvatarDescriptor\nis required to build VRChat SDK Content", titleGuiStyle, GUILayout.Width(SdkWindowWidth));
|
||||
#endif
|
||||
}
|
||||
else if (errorMessage != null)
|
||||
{
|
||||
OnGUIError(null,
|
||||
errorMessage,
|
||||
() => {
|
||||
foreach (IVRCSdkControlPanelBuilder builder in _sdkBuilders)
|
||||
{
|
||||
builder.SelectAllComponents();
|
||||
} },
|
||||
null
|
||||
);
|
||||
OnGUIShowIssues();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedBuilder.ShowBuilder();
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.Used) return;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public bool showLayerHelp = false;
|
||||
|
||||
bool ShouldShowLightmapWarning
|
||||
{
|
||||
get
|
||||
{
|
||||
const string GraphicsSettingsAssetPath = "ProjectSettings/GraphicsSettings.asset";
|
||||
SerializedObject graphicsManager = new SerializedObject(UnityEditor.AssetDatabase.LoadAllAssetsAtPath(GraphicsSettingsAssetPath)[0]);
|
||||
SerializedProperty lightmapStripping = graphicsManager.FindProperty("m_LightmapStripping");
|
||||
return lightmapStripping.enumValueIndex == 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShouldShowFogWarning
|
||||
{
|
||||
get
|
||||
{
|
||||
const string GraphicsSettingsAssetPath = "ProjectSettings/GraphicsSettings.asset";
|
||||
SerializedObject graphicsManager = new SerializedObject(UnityEditor.AssetDatabase.LoadAllAssetsAtPath(GraphicsSettingsAssetPath)[0]);
|
||||
SerializedProperty lightmapStripping = graphicsManager.FindProperty("m_FogStripping");
|
||||
return lightmapStripping.enumValueIndex == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIssueBox(MessageType msgType, Texture icon, string message, System.Action show, System.Action fix)
|
||||
{
|
||||
bool haveButtons = ((show != null) || (fix != null));
|
||||
|
||||
GUIStyle style = new GUIStyle("HelpBox");
|
||||
style.fixedWidth = (haveButtons ? (SdkWindowWidth - 90) : SdkWindowWidth);
|
||||
float minHeight = 40;
|
||||
|
||||
try
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (icon != null)
|
||||
{
|
||||
GUIContent c = new GUIContent(message, icon);
|
||||
float height = style.CalcHeight(c, style.fixedWidth);
|
||||
GUILayout.Box(c, style, GUILayout.MinHeight(Mathf.Max(minHeight, height)));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIContent c = new GUIContent(message);
|
||||
float height = style.CalcHeight(c, style.fixedWidth);
|
||||
Rect rt = GUILayoutUtility.GetRect(c, style, GUILayout.MinHeight(Mathf.Max(minHeight, height)));
|
||||
EditorGUI.HelpBox(rt, message, msgType); // note: EditorGUILayout resulted in uneven button layout in this case
|
||||
}
|
||||
|
||||
if (haveButtons)
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
float buttonHeight = ((show == null || fix == null) ? minHeight : (minHeight * 0.5f));
|
||||
if ((show != null) && GUILayout.Button("Select", GUILayout.Height(buttonHeight)))
|
||||
show();
|
||||
if ((fix != null) && GUILayout.Button("Auto Fix", GUILayout.Height(buttonHeight)))
|
||||
{
|
||||
fix();
|
||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
|
||||
CheckedForIssues = false;
|
||||
Repaint();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// mutes 'ArgumentException: Getting control 0's position in a group with only 0 controls when doing repaint'
|
||||
}
|
||||
}
|
||||
|
||||
public void OnGuiFixIssuesToBuildOrTest()
|
||||
{
|
||||
GUIStyle s = new GUIStyle(EditorStyles.label) { alignment = TextAnchor.MiddleCenter };
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.BeginVertical(boxGuiStyle, GUILayout.Height(WARNING_ICON_SIZE), GUILayout.Width(SdkWindowWidth));
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
var textDimensions = s.CalcSize(new GUIContent(FIX_ISSUES_TO_BUILD_OR_TEST_WARNING_STRING));
|
||||
GUILayout.Label(new GUIContent(warningIconGraphic), GUILayout.Width(WARNING_ICON_SIZE), GUILayout.Height(WARNING_ICON_SIZE));
|
||||
EditorGUILayout.LabelField(FIX_ISSUES_TO_BUILD_OR_TEST_WARNING_STRING, s, GUILayout.Width(textDimensions.x), GUILayout.Height(WARNING_ICON_SIZE));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
public void OnGUIShowIssues(Object subject = null)
|
||||
{
|
||||
if (subject == null)
|
||||
subject = this;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
GUIStyle style = GUI.skin.GetStyle("HelpBox");
|
||||
|
||||
if (GUIErrors.ContainsKey(subject))
|
||||
foreach (Issue error in GUIErrors[subject].Where(s => !string.IsNullOrEmpty(s.issueText)))
|
||||
DrawIssueBox(MessageType.Error, null, error.issueText, error.showThisIssue, error.fixThisIssue);
|
||||
if (GUIWarnings.ContainsKey(subject))
|
||||
foreach (Issue error in GUIWarnings[subject].Where(s => !string.IsNullOrEmpty(s.issueText)))
|
||||
DrawIssueBox(MessageType.Warning, null, error.issueText, error.showThisIssue, error.fixThisIssue);
|
||||
|
||||
if (GUIStats.ContainsKey(subject))
|
||||
{
|
||||
foreach (var kvp in GUIStats[subject].Where(k => k.performanceRating == PerformanceRating.VeryPoor))
|
||||
DrawIssueBox(MessageType.Warning, GetPerformanceIconForRating(kvp.performanceRating), kvp.issueText, kvp.showThisIssue, kvp.fixThisIssue);
|
||||
|
||||
foreach (var kvp in GUIStats[subject].Where(k => k.performanceRating == PerformanceRating.Poor))
|
||||
DrawIssueBox(MessageType.Warning, GetPerformanceIconForRating(kvp.performanceRating), kvp.issueText, kvp.showThisIssue, kvp.fixThisIssue);
|
||||
|
||||
foreach (var kvp in GUIStats[subject].Where(k => k.performanceRating == PerformanceRating.Medium))
|
||||
DrawIssueBox(MessageType.Warning, GetPerformanceIconForRating(kvp.performanceRating), kvp.issueText, kvp.showThisIssue, kvp.fixThisIssue);
|
||||
|
||||
foreach (var kvp in GUIStats[subject].Where(k => k.performanceRating == PerformanceRating.Good || k.performanceRating == PerformanceRating.Excellent))
|
||||
DrawIssueBox(MessageType.Warning, GetPerformanceIconForRating(kvp.performanceRating), kvp.issueText, kvp.showThisIssue, kvp.fixThisIssue);
|
||||
}
|
||||
|
||||
if (GUIInfos.ContainsKey(subject))
|
||||
foreach (Issue error in GUIInfos[subject].Where(s => !string.IsNullOrEmpty(s.issueText)))
|
||||
EditorGUILayout.HelpBox(error.issueText, MessageType.Info);
|
||||
if (GUILinks.ContainsKey(subject))
|
||||
{
|
||||
EditorGUILayout.BeginVertical(style);
|
||||
foreach (Issue error in GUILinks[subject].Where(s => !string.IsNullOrEmpty(s.issueText)))
|
||||
{
|
||||
var s = error.issueText.Split('\n');
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label(s[0]);
|
||||
if (GUILayout.Button("Open Link", GUILayout.Width(100)))
|
||||
Application.OpenURL(s[1]);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorUtility.SetDirty(subject);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
|
||||
private Texture GetPerformanceIconForRating(PerformanceRating value)
|
||||
{
|
||||
if (_perfIcon_Excellent == null)
|
||||
_perfIcon_Excellent = Resources.Load<Texture>("PerformanceIcons/Perf_Great_32");
|
||||
if (_perfIcon_Good == null)
|
||||
_perfIcon_Good = Resources.Load<Texture>("PerformanceIcons/Perf_Good_32");
|
||||
if (_perfIcon_Medium == null)
|
||||
_perfIcon_Medium = Resources.Load<Texture>("PerformanceIcons/Perf_Medium_32");
|
||||
if (_perfIcon_Poor == null)
|
||||
_perfIcon_Poor = Resources.Load<Texture>("PerformanceIcons/Perf_Poor_32");
|
||||
if (_perfIcon_VeryPoor == null)
|
||||
_perfIcon_VeryPoor = Resources.Load<Texture>("PerformanceIcons/Perf_Horrible_32");
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case PerformanceRating.Excellent:
|
||||
return _perfIcon_Excellent;
|
||||
case PerformanceRating.Good:
|
||||
return _perfIcon_Good;
|
||||
case PerformanceRating.Medium:
|
||||
return _perfIcon_Medium;
|
||||
case PerformanceRating.Poor:
|
||||
return _perfIcon_Poor;
|
||||
case PerformanceRating.None:
|
||||
case PerformanceRating.VeryPoor:
|
||||
return _perfIcon_VeryPoor;
|
||||
}
|
||||
|
||||
return _perfIcon_Excellent;
|
||||
}
|
||||
|
||||
Texture2D CreateBackgroundColorImage(UnityEngine.Color color)
|
||||
{
|
||||
int w = 4, h = 4;
|
||||
Texture2D back = new Texture2D(w, h);
|
||||
UnityEngine.Color[] buffer = new UnityEngine.Color[w * h];
|
||||
for (int i = 0; i < w; ++i)
|
||||
for (int j = 0; j < h; ++j)
|
||||
buffer[i + w * j] = color;
|
||||
back.SetPixels(buffer);
|
||||
back.Apply(false);
|
||||
return back;
|
||||
}
|
||||
|
||||
public static void DrawContentInfo(string name, string version, string description, string capacity, string releaseStatus, List<string> tags)
|
||||
{
|
||||
EditorGUILayout.LabelField("Name: " + name);
|
||||
EditorGUILayout.LabelField("Version: " + version.ToString());
|
||||
EditorGUILayout.LabelField("Description: " + description);
|
||||
if (capacity != null)
|
||||
EditorGUILayout.LabelField("Capacity: " + capacity);
|
||||
EditorGUILayout.LabelField("Release: " + releaseStatus);
|
||||
if (tags != null)
|
||||
{
|
||||
string tagString = "";
|
||||
for (int i = 0; i < tags.Count; i++)
|
||||
{
|
||||
if (i != 0) tagString += ", ";
|
||||
tagString += tags[i];
|
||||
}
|
||||
EditorGUILayout.LabelField("Tags: " + tagString);
|
||||
|
||||
}
|
||||
}
|
||||
public static void DrawContentPlatformSupport(VRC.Core.ApiModel m)
|
||||
{
|
||||
if (m.supportedPlatforms == VRC.Core.ApiModel.SupportedPlatforms.StandaloneWindows || m.supportedPlatforms == VRC.Core.ApiModel.SupportedPlatforms.All)
|
||||
EditorGUILayout.LabelField("Windows Support: YES");
|
||||
else
|
||||
EditorGUILayout.LabelField("Windows Support: NO");
|
||||
|
||||
if (m.supportedPlatforms == VRC.Core.ApiModel.SupportedPlatforms.Android || m.supportedPlatforms == VRC.Core.ApiModel.SupportedPlatforms.All)
|
||||
EditorGUILayout.LabelField("Android Support: YES");
|
||||
else
|
||||
EditorGUILayout.LabelField("Android Support: NO");
|
||||
}
|
||||
|
||||
public static void DrawBuildTargetSwitcher()
|
||||
{
|
||||
EditorGUILayout.LabelField("Active Build Target: " + EditorUserBuildSettings.activeBuildTarget);
|
||||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64 && GUILayout.Button("Switch Build Target to Android"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Build Target Switcher", "Are you sure you want to switch your build target to Android? This could take a while.", "Confirm", "Cancel"))
|
||||
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(BuildTargetGroup.Android, BuildTarget.Android);
|
||||
}
|
||||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android && GUILayout.Button("Switch Build Target to Windows"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Build Target Switcher", "Are you sure you want to switch your build target to Windows? This could take a while.", "Confirm", "Cancel"))
|
||||
EditorUserBuildSettings.SwitchActiveBuildTargetAsync(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetBuildAndPublishButtonString()
|
||||
{
|
||||
string buildButtonString = "Build & Publish for UNSUPPORTED";
|
||||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64)
|
||||
buildButtonString = "Build & Publish for Windows";
|
||||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
|
||||
buildButtonString = "Build & Publish for Android";
|
||||
|
||||
return buildButtonString;
|
||||
}
|
||||
|
||||
public static Object[] GetSubstanceObjects(GameObject obj = null, bool earlyOut = false)
|
||||
{
|
||||
// if 'obj' is null we check entire scene
|
||||
// if 'earlyOut' is true we only return 1st object (to detect if substances are present)
|
||||
|
||||
List<Object> objects = new List<Object>();
|
||||
if (obj == null) return objects.Count < 1 ? null : objects.ToArray();
|
||||
Renderer[] renderers = obj ? obj.GetComponentsInChildren<Renderer>(true) : FindObjectsOfType<Renderer>();
|
||||
|
||||
if (renderers == null || renderers.Length < 1)
|
||||
return null;
|
||||
foreach (Renderer r in renderers)
|
||||
{
|
||||
if (r.sharedMaterials.Length < 1)
|
||||
continue;
|
||||
foreach (Material m in r.sharedMaterials)
|
||||
{
|
||||
if (!m)
|
||||
continue;
|
||||
string path = AssetDatabase.GetAssetPath(m);
|
||||
if (string.IsNullOrEmpty(path))
|
||||
continue;
|
||||
if (path.EndsWith(".sbsar", true, System.Globalization.CultureInfo.InvariantCulture))
|
||||
{
|
||||
objects.Add(r.gameObject);
|
||||
if (earlyOut)
|
||||
return objects.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objects.Count < 1 ? null : objects.ToArray();
|
||||
}
|
||||
|
||||
public static bool HasSubstances(GameObject obj = null)
|
||||
{
|
||||
return (GetSubstanceObjects(obj, true) != null);
|
||||
}
|
||||
|
||||
EditorWindow GetLightingWindow()
|
||||
{
|
||||
var editorAsm = typeof(UnityEditor.Editor).Assembly;
|
||||
return EditorWindow.GetWindow(editorAsm.GetType("UnityEditor.LightingWindow"));
|
||||
}
|
||||
|
||||
public static void ShowContentPublishPermissionsDialog()
|
||||
{
|
||||
if (!VRC.Core.ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
VRC.Core.ConfigManager.RemoteConfig.Init(() => ShowContentPublishPermissionsDialog());
|
||||
return;
|
||||
}
|
||||
|
||||
string message = VRC.Core.ConfigManager.RemoteConfig.GetString("sdkNotAllowedToPublishMessage");
|
||||
int result = UnityEditor.EditorUtility.DisplayDialogComplex("VRChat SDK", message, "Developer FAQ", "VRChat Discord", "OK");
|
||||
if (result == 0)
|
||||
{
|
||||
ShowDeveloperFAQ();
|
||||
}
|
||||
if (result == 1)
|
||||
{
|
||||
ShowVRChatDiscord();
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c73e735ee0380241b186a8993fa56bf
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRC.SDKBase.Editor
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
[MeansImplicitUse]
|
||||
public class VRCSdkControlPanelBuilderAttribute : Attribute
|
||||
{
|
||||
public Type Type { get; }
|
||||
public VRCSdkControlPanelBuilderAttribute(Type type)
|
||||
{
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c768b42ca9a2f2b48afeb1fa03d5e1bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,682 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Networking;
|
||||
using VRC.Core;
|
||||
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
const int PageLimit = 20;
|
||||
|
||||
static List<ApiAvatar> uploadedAvatars = null;
|
||||
static List<ApiWorld> uploadedWorlds = null;
|
||||
static List<ApiAvatar> testAvatars = null;
|
||||
|
||||
public static Dictionary<string, Texture2D> ImageCache = new Dictionary<string, Texture2D>();
|
||||
|
||||
static List<string> justDeletedContents;
|
||||
static List<ApiAvatar> justUpdatedAvatars;
|
||||
|
||||
static EditorCoroutine fetchingAvatars = null, fetchingWorlds = null;
|
||||
|
||||
private static string searchString = "";
|
||||
private static bool WorldsToggle = true;
|
||||
private static bool AvatarsToggle = true;
|
||||
private static bool TestAvatarsToggle = true;
|
||||
|
||||
const int SCROLLBAR_RESERVED_REGION_WIDTH = 50;
|
||||
|
||||
const int WORLD_DESCRIPTION_FIELD_WIDTH = 140;
|
||||
const int WORLD_IMAGE_BUTTON_WIDTH = 100;
|
||||
const int WORLD_IMAGE_BUTTON_HEIGHT = 100;
|
||||
const int WORLD_RELEASE_STATUS_FIELD_WIDTH = 150;
|
||||
const int COPY_WORLD_ID_BUTTON_WIDTH = 75;
|
||||
const int DELETE_WORLD_BUTTON_WIDTH = 75;
|
||||
const int WORLD_ALL_INFORMATION_MAX_WIDTH = WORLD_DESCRIPTION_FIELD_WIDTH + WORLD_IMAGE_BUTTON_WIDTH + WORLD_RELEASE_STATUS_FIELD_WIDTH + COPY_WORLD_ID_BUTTON_WIDTH + DELETE_WORLD_BUTTON_WIDTH + SCROLLBAR_RESERVED_REGION_WIDTH;
|
||||
const int WORLD_REDUCED_INFORMATION_MAX_WIDTH = WORLD_DESCRIPTION_FIELD_WIDTH + WORLD_IMAGE_BUTTON_WIDTH + WORLD_RELEASE_STATUS_FIELD_WIDTH + SCROLLBAR_RESERVED_REGION_WIDTH;
|
||||
|
||||
const int AVATAR_DESCRIPTION_FIELD_WIDTH = 140;
|
||||
const int AVATAR_IMAGE_BUTTON_WIDTH = WORLD_IMAGE_BUTTON_WIDTH;
|
||||
const int AVATAR_IMAGE_BUTTON_HEIGHT = WORLD_IMAGE_BUTTON_HEIGHT;
|
||||
const int AVATAR_RELEASE_STATUS_FIELD_WIDTH = 150;
|
||||
const int SET_AVATAR_STATUS_BUTTON_WIDTH = 100;
|
||||
const int COPY_AVATAR_ID_BUTTON_WIDTH = COPY_WORLD_ID_BUTTON_WIDTH;
|
||||
const int DELETE_AVATAR_BUTTON_WIDTH = DELETE_WORLD_BUTTON_WIDTH;
|
||||
const int AVATAR_ALL_INFORMATION_MAX_WIDTH = AVATAR_DESCRIPTION_FIELD_WIDTH + AVATAR_IMAGE_BUTTON_WIDTH + AVATAR_RELEASE_STATUS_FIELD_WIDTH + SET_AVATAR_STATUS_BUTTON_WIDTH + COPY_AVATAR_ID_BUTTON_WIDTH + DELETE_AVATAR_BUTTON_WIDTH + SCROLLBAR_RESERVED_REGION_WIDTH;
|
||||
const int AVATAR_REDUCED_INFORMATION_MAX_WIDTH = AVATAR_DESCRIPTION_FIELD_WIDTH + AVATAR_IMAGE_BUTTON_WIDTH + AVATAR_RELEASE_STATUS_FIELD_WIDTH + SCROLLBAR_RESERVED_REGION_WIDTH;
|
||||
|
||||
const int MAX_ALL_INFORMATION_WIDTH = WORLD_ALL_INFORMATION_MAX_WIDTH > AVATAR_ALL_INFORMATION_MAX_WIDTH ? WORLD_ALL_INFORMATION_MAX_WIDTH : AVATAR_ALL_INFORMATION_MAX_WIDTH;
|
||||
const int MAX_REDUCED_INFORMATION_WIDTH = WORLD_REDUCED_INFORMATION_MAX_WIDTH > AVATAR_REDUCED_INFORMATION_MAX_WIDTH ? WORLD_REDUCED_INFORMATION_MAX_WIDTH : AVATAR_REDUCED_INFORMATION_MAX_WIDTH;
|
||||
|
||||
public static void ClearContent()
|
||||
{
|
||||
if (uploadedWorlds != null)
|
||||
uploadedWorlds = null;
|
||||
if (uploadedAvatars != null)
|
||||
uploadedAvatars = null;
|
||||
if (testAvatars != null)
|
||||
testAvatars = null;
|
||||
ImageCache.Clear();
|
||||
}
|
||||
|
||||
IEnumerator FetchUploadedData()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
ConfigManager.RemoteConfig.Init();
|
||||
|
||||
if (!APIUser.IsLoggedInWithCredentials)
|
||||
yield break;
|
||||
|
||||
ApiCache.ClearResponseCache();
|
||||
VRCCachedWWW.ClearOld();
|
||||
|
||||
if (fetchingAvatars == null)
|
||||
fetchingAvatars = EditorCoroutine.Start(() => FetchAvatars());
|
||||
if (fetchingWorlds == null)
|
||||
fetchingWorlds = EditorCoroutine.Start(() => FetchWorlds());
|
||||
FetchTestAvatars();
|
||||
}
|
||||
|
||||
private static void FetchAvatars(int offset = 0)
|
||||
{
|
||||
ApiAvatar.FetchList(
|
||||
delegate (IEnumerable<ApiAvatar> obj)
|
||||
{
|
||||
if (obj.FirstOrDefault() != null)
|
||||
fetchingAvatars = EditorCoroutine.Start(() =>
|
||||
{
|
||||
var l = obj.ToList();
|
||||
int count = l.Count;
|
||||
SetupAvatarData(l);
|
||||
FetchAvatars(offset + count);
|
||||
});
|
||||
else
|
||||
{
|
||||
fetchingAvatars = null;
|
||||
foreach (ApiAvatar a in uploadedAvatars)
|
||||
DownloadImage(a.id, a.thumbnailImageUrl);
|
||||
}
|
||||
},
|
||||
delegate (string obj)
|
||||
{
|
||||
Debug.LogError("Error fetching your uploaded avatars:\n" + obj);
|
||||
fetchingAvatars = null;
|
||||
},
|
||||
ApiAvatar.Owner.Mine,
|
||||
ApiAvatar.ReleaseStatus.All,
|
||||
null,
|
||||
PageLimit,
|
||||
offset,
|
||||
ApiAvatar.SortHeading.None,
|
||||
ApiAvatar.SortOrder.Descending,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private static void FetchTestAvatars()
|
||||
{
|
||||
#if VRC_SDK_VRCSDK3
|
||||
string sdkAvatarFolder = VRC.SDK3.Editor.VRC_SdkBuilder.GetKnownFolderPath(VRC.SDK3.Editor.VRC_SdkBuilder.LocalLowGUID) + "/VRChat/vrchat/Avatars/";
|
||||
string[] sdkavatars = Directory.GetFiles(sdkAvatarFolder);
|
||||
string filename = "";
|
||||
List<ApiAvatar> avatars = new List<ApiAvatar>();
|
||||
foreach(string sdkap in sdkavatars)
|
||||
{
|
||||
if(Path.GetExtension(sdkap) != ".vrca")
|
||||
continue;
|
||||
|
||||
filename = Path.GetFileNameWithoutExtension(sdkap);
|
||||
ApiAvatar sdka = API.FromCacheOrNew<ApiAvatar>("local:sdk_" + filename);
|
||||
sdka.assetUrl = sdkap;
|
||||
sdka.name = filename;
|
||||
sdka.releaseStatus = "public";
|
||||
ApiAvatar.AddLocal(sdka);
|
||||
avatars.Add(sdka);
|
||||
}
|
||||
|
||||
testAvatars = avatars;
|
||||
#else
|
||||
testAvatars = new List<ApiAvatar>();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void FetchWorlds(int offset = 0)
|
||||
{
|
||||
ApiWorld.FetchList(
|
||||
delegate (IEnumerable<ApiWorld> obj)
|
||||
{
|
||||
if (obj.FirstOrDefault() != null)
|
||||
fetchingWorlds = EditorCoroutine.Start(() =>
|
||||
{
|
||||
var l = obj.ToList();
|
||||
int count = l.Count;
|
||||
SetupWorldData(l);
|
||||
FetchWorlds(offset + count);
|
||||
});
|
||||
else
|
||||
{
|
||||
fetchingWorlds = null;
|
||||
|
||||
foreach (ApiWorld w in uploadedWorlds)
|
||||
DownloadImage(w.id, w.thumbnailImageUrl);
|
||||
}
|
||||
},
|
||||
delegate (string obj)
|
||||
{
|
||||
Debug.LogError("Error fetching your uploaded worlds:\n" + obj);
|
||||
fetchingWorlds = null;
|
||||
},
|
||||
ApiWorld.SortHeading.Updated,
|
||||
ApiWorld.SortOwnership.Mine,
|
||||
ApiWorld.SortOrder.Descending,
|
||||
offset,
|
||||
PageLimit,
|
||||
"",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"",
|
||||
ApiWorld.ReleaseStatus.All,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false);
|
||||
}
|
||||
|
||||
static void SetupWorldData(List<ApiWorld> worlds)
|
||||
{
|
||||
if (worlds == null || uploadedWorlds == null)
|
||||
return;
|
||||
|
||||
worlds.RemoveAll(w => w == null || w.name == null || uploadedWorlds.Any(w2 => w2.id == w.id));
|
||||
|
||||
if (worlds.Count > 0)
|
||||
{
|
||||
uploadedWorlds.AddRange(worlds);
|
||||
uploadedWorlds.Sort((w1, w2) => w1.name.CompareTo(w2.name));
|
||||
}
|
||||
}
|
||||
|
||||
static void SetupAvatarData(List<ApiAvatar> avatars)
|
||||
{
|
||||
if (avatars == null || uploadedAvatars == null )
|
||||
return;
|
||||
|
||||
avatars.RemoveAll(a => a == null || uploadedAvatars.Any(a2 => a2.id == a.id));
|
||||
foreach(var avatar in avatars)
|
||||
{
|
||||
if (string.IsNullOrEmpty(avatar.name))
|
||||
avatar.name = "(unnamed)";
|
||||
}
|
||||
|
||||
if (avatars.Count > 0)
|
||||
{
|
||||
uploadedAvatars.AddRange(avatars);
|
||||
uploadedAvatars.Sort((w1, w2) => w1.name.CompareTo(w2.name));
|
||||
}
|
||||
}
|
||||
|
||||
static void DownloadImage(string id, string url)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
return;
|
||||
if (ImageCache.ContainsKey(id) && ImageCache[id] != null)
|
||||
return;
|
||||
|
||||
System.Action<Texture2D> onDone = (texture) =>
|
||||
{
|
||||
if (texture != null)
|
||||
{
|
||||
ImageCache[id] = texture;
|
||||
}
|
||||
else if (ImageCache.ContainsKey(id))
|
||||
ImageCache.Remove(id);
|
||||
};
|
||||
EditorCoroutine.Start(VRCCachedWWW.Get(url, (onDone)));
|
||||
}
|
||||
|
||||
Vector2 contentScrollPos;
|
||||
|
||||
bool OnGUIUserInfo()
|
||||
{
|
||||
bool updatedContent = false;
|
||||
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
ConfigManager.RemoteConfig.Init();
|
||||
|
||||
if (APIUser.IsLoggedInWithCredentials && uploadedWorlds != null && uploadedAvatars != null && testAvatars != null)
|
||||
{
|
||||
|
||||
bool expandedLayout = false; // (position.width > MAX_ALL_INFORMATION_WIDTH); // uncomment for future wide layouts
|
||||
|
||||
if (!expandedLayout)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.BeginVertical(searchBarStyle);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
float searchFieldShrinkOffset = 30f;
|
||||
GUILayoutOption layoutOption = (expandedLayout ? GUILayout.Width(position.width - searchFieldShrinkOffset) : GUILayout.Width(SdkWindowWidth - searchFieldShrinkOffset));
|
||||
searchString = EditorGUILayout.TextField(searchString, GUI.skin.FindStyle("SearchTextField"), layoutOption);
|
||||
GUIStyle searchButtonStyle = searchString == string.Empty
|
||||
? GUI.skin.FindStyle("SearchCancelButtonEmpty")
|
||||
: GUI.skin.FindStyle("SearchCancelButton");
|
||||
if (GUILayout.Button(string.Empty, searchButtonStyle))
|
||||
{
|
||||
searchString = string.Empty;
|
||||
GUI.FocusControl(null);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (!expandedLayout)
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
|
||||
layoutOption = (expandedLayout ? GUILayout.Width(position.width) : GUILayout.Width(SdkWindowWidth));
|
||||
contentScrollPos = EditorGUILayout.BeginScrollView(contentScrollPos, layoutOption);
|
||||
|
||||
GUIStyle descriptionStyle = new GUIStyle(EditorStyles.wordWrappedLabel);
|
||||
descriptionStyle.wordWrap = true;
|
||||
|
||||
if (uploadedWorlds.Count > 0)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("WORLDS", EditorStyles.boldLabel, GUILayout.ExpandWidth(false), GUILayout.Width(58));
|
||||
WorldsToggle = EditorGUILayout.Foldout(WorldsToggle, new GUIContent(""));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (WorldsToggle)
|
||||
{
|
||||
|
||||
List<ApiWorld> tmpWorlds = new List<ApiWorld>();
|
||||
|
||||
if (uploadedWorlds.Count > 0)
|
||||
tmpWorlds = new List<ApiWorld>(uploadedWorlds);
|
||||
|
||||
foreach (ApiWorld w in tmpWorlds)
|
||||
{
|
||||
if (justDeletedContents != null && justDeletedContents.Contains(w.id))
|
||||
{
|
||||
uploadedWorlds.Remove(w);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!w.name.ToLowerInvariant().Contains(searchString.ToLowerInvariant()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
EditorGUILayout.BeginHorizontal(GUILayout.Width(WORLD_IMAGE_BUTTON_WIDTH));
|
||||
|
||||
if (ImageCache.ContainsKey(w.id))
|
||||
{
|
||||
if (GUILayout.Button(ImageCache[w.id], GUILayout.Height(WORLD_IMAGE_BUTTON_HEIGHT),
|
||||
GUILayout.Width(WORLD_IMAGE_BUTTON_WIDTH)))
|
||||
{
|
||||
Application.OpenURL(w.imageUrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("", GUILayout.Height(WORLD_IMAGE_BUTTON_HEIGHT),
|
||||
GUILayout.Width(WORLD_IMAGE_BUTTON_WIDTH)))
|
||||
{
|
||||
Application.OpenURL(w.imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (expandedLayout)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(w.name, descriptionStyle,
|
||||
GUILayout.Width(position.width - MAX_ALL_INFORMATION_WIDTH +
|
||||
WORLD_DESCRIPTION_FIELD_WIDTH));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.BeginVertical();
|
||||
EditorGUILayout.LabelField(w.name, descriptionStyle);
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Release Status: " + w.releaseStatus,
|
||||
GUILayout.Width(WORLD_RELEASE_STATUS_FIELD_WIDTH));
|
||||
if (GUILayout.Button("Copy ID", GUILayout.Width(COPY_WORLD_ID_BUTTON_WIDTH)))
|
||||
{
|
||||
TextEditor te = new TextEditor();
|
||||
te.text = w.id;
|
||||
te.SelectAll();
|
||||
te.Copy();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Delete", GUILayout.Width(DELETE_WORLD_BUTTON_WIDTH)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete " + w.name + "?",
|
||||
"Are you sure you want to delete " + w.name + "? This cannot be undone.", "Delete",
|
||||
"Cancel"))
|
||||
{
|
||||
foreach (VRC.Core.PipelineManager pm in FindObjectsOfType<VRC.Core.PipelineManager>()
|
||||
.Where(pm => pm.blueprintId == w.id))
|
||||
{
|
||||
pm.blueprintId = "";
|
||||
pm.completedSDKPipeline = false;
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(pm);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(pm.gameObject.scene);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(pm.gameObject.scene);
|
||||
}
|
||||
|
||||
API.Delete<ApiWorld>(w.id);
|
||||
uploadedWorlds.RemoveAll(world => world.id == w.id);
|
||||
if (ImageCache.ContainsKey(w.id))
|
||||
ImageCache.Remove(w.id);
|
||||
|
||||
if (justDeletedContents == null) justDeletedContents = new List<string>();
|
||||
justDeletedContents.Add(w.id);
|
||||
updatedContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (expandedLayout)
|
||||
EditorGUILayout.EndHorizontal();
|
||||
else
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadedAvatars.Count > 0)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("AVATARS", EditorStyles.boldLabel, GUILayout.ExpandWidth(false), GUILayout.Width(65));
|
||||
AvatarsToggle = EditorGUILayout.Foldout(AvatarsToggle, new GUIContent(""));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (AvatarsToggle)
|
||||
{
|
||||
|
||||
List<ApiAvatar> tmpAvatars = new List<ApiAvatar>();
|
||||
|
||||
if (uploadedAvatars.Count > 0)
|
||||
tmpAvatars = new List<ApiAvatar>(uploadedAvatars);
|
||||
|
||||
if (justUpdatedAvatars != null)
|
||||
{
|
||||
foreach (ApiAvatar a in justUpdatedAvatars)
|
||||
{
|
||||
int index = tmpAvatars.FindIndex((av) => av.id == a.id);
|
||||
if (index != -1)
|
||||
tmpAvatars[index] = a;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ApiAvatar a in tmpAvatars)
|
||||
{
|
||||
if (justDeletedContents != null && justDeletedContents.Contains(a.id))
|
||||
{
|
||||
uploadedAvatars.Remove(a);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!a.name.ToLowerInvariant().Contains(searchString.ToLowerInvariant()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
EditorGUILayout.BeginHorizontal(GUILayout.Width(AVATAR_DESCRIPTION_FIELD_WIDTH));
|
||||
if (ImageCache.ContainsKey(a.id))
|
||||
{
|
||||
if (GUILayout.Button(ImageCache[a.id], GUILayout.Height(AVATAR_IMAGE_BUTTON_HEIGHT),
|
||||
GUILayout.Width(AVATAR_IMAGE_BUTTON_WIDTH)))
|
||||
{
|
||||
Application.OpenURL(a.imageUrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("", GUILayout.Height(AVATAR_IMAGE_BUTTON_HEIGHT),
|
||||
GUILayout.Width(AVATAR_IMAGE_BUTTON_WIDTH)))
|
||||
{
|
||||
Application.OpenURL(a.imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (expandedLayout)
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
else
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.LabelField(a.name, descriptionStyle,
|
||||
GUILayout.Width(expandedLayout
|
||||
? position.width - MAX_ALL_INFORMATION_WIDTH + AVATAR_DESCRIPTION_FIELD_WIDTH
|
||||
: AVATAR_DESCRIPTION_FIELD_WIDTH));
|
||||
EditorGUILayout.LabelField("Release Status: " + a.releaseStatus,
|
||||
GUILayout.Width(AVATAR_RELEASE_STATUS_FIELD_WIDTH));
|
||||
|
||||
string oppositeReleaseStatus = a.releaseStatus == "public" ? "private" : "public";
|
||||
if (GUILayout.Button("Make " + oppositeReleaseStatus,
|
||||
GUILayout.Width(SET_AVATAR_STATUS_BUTTON_WIDTH)))
|
||||
{
|
||||
a.releaseStatus = oppositeReleaseStatus;
|
||||
|
||||
a.SaveReleaseStatus((c) =>
|
||||
{
|
||||
ApiAvatar savedBP = (ApiAvatar) c.Model;
|
||||
|
||||
if (justUpdatedAvatars == null) justUpdatedAvatars = new List<ApiAvatar>();
|
||||
justUpdatedAvatars.Add(savedBP);
|
||||
|
||||
},
|
||||
(c) =>
|
||||
{
|
||||
Debug.LogError(c.Error);
|
||||
EditorUtility.DisplayDialog("Avatar Updated",
|
||||
"Failed to change avatar release status", "OK");
|
||||
});
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Copy ID", GUILayout.Width(COPY_AVATAR_ID_BUTTON_WIDTH)))
|
||||
{
|
||||
TextEditor te = new TextEditor();
|
||||
te.text = a.id;
|
||||
te.SelectAll();
|
||||
te.Copy();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Delete", GUILayout.Width(DELETE_AVATAR_BUTTON_WIDTH)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete " + a.name + "?",
|
||||
"Are you sure you want to delete " + a.name + "? This cannot be undone.", "Delete",
|
||||
"Cancel"))
|
||||
{
|
||||
foreach (VRC.Core.PipelineManager pm in FindObjectsOfType<VRC.Core.PipelineManager>()
|
||||
.Where(pm => pm.blueprintId == a.id))
|
||||
{
|
||||
pm.blueprintId = "";
|
||||
pm.completedSDKPipeline = false;
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(pm);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(pm.gameObject.scene);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(pm.gameObject.scene);
|
||||
}
|
||||
|
||||
API.Delete<ApiAvatar>(a.id);
|
||||
uploadedAvatars.RemoveAll(avatar => avatar.id == a.id);
|
||||
if (ImageCache.ContainsKey(a.id))
|
||||
ImageCache.Remove(a.id);
|
||||
|
||||
if (justDeletedContents == null) justDeletedContents = new List<string>();
|
||||
justDeletedContents.Add(a.id);
|
||||
updatedContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (expandedLayout)
|
||||
EditorGUILayout.EndHorizontal();
|
||||
else
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (testAvatars.Count > 0)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Test Avatars", EditorStyles.boldLabel, GUILayout.ExpandWidth(false), GUILayout.Width(100));
|
||||
TestAvatarsToggle = EditorGUILayout.Foldout(TestAvatarsToggle, new GUIContent(""));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (TestAvatarsToggle)
|
||||
{
|
||||
List<ApiAvatar> tmpAvatars = new List<ApiAvatar>();
|
||||
|
||||
if (testAvatars.Count > 0)
|
||||
tmpAvatars = new List<ApiAvatar>(testAvatars);
|
||||
|
||||
foreach (ApiAvatar a in tmpAvatars)
|
||||
{
|
||||
if (!a.name.ToLowerInvariant().Contains(searchString.ToLowerInvariant()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
|
||||
if (expandedLayout)
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
else
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.LabelField(a.name, descriptionStyle,
|
||||
GUILayout.Width(expandedLayout
|
||||
? position.width - MAX_ALL_INFORMATION_WIDTH + AVATAR_DESCRIPTION_FIELD_WIDTH
|
||||
: AVATAR_DESCRIPTION_FIELD_WIDTH));
|
||||
|
||||
if (GUILayout.Button("Delete", GUILayout.Width(DELETE_AVATAR_BUTTON_WIDTH)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete " + a.name + "?",
|
||||
"Are you sure you want to delete " + a.name + "? This cannot be undone.", "Delete",
|
||||
"Cancel"))
|
||||
{
|
||||
API.Delete<ApiAvatar>(a.id);
|
||||
testAvatars.RemoveAll(avatar => avatar.id == a.id);
|
||||
File.Delete(a.assetUrl);
|
||||
|
||||
updatedContent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (expandedLayout)
|
||||
EditorGUILayout.EndHorizontal();
|
||||
else
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
if (!expandedLayout)
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
if ((updatedContent) && (null != window)) window.Reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowContent()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
if (uploadedWorlds == null || uploadedAvatars == null || testAvatars == null)
|
||||
{
|
||||
if (uploadedWorlds == null)
|
||||
uploadedWorlds = new List<ApiWorld>();
|
||||
if (uploadedAvatars == null)
|
||||
uploadedAvatars = new List<ApiAvatar>();
|
||||
if (testAvatars == null)
|
||||
testAvatars = new List<ApiAvatar>();
|
||||
|
||||
EditorCoroutine.Start(FetchUploadedData());
|
||||
}
|
||||
|
||||
if( fetchingWorlds != null || fetchingAvatars != null )
|
||||
{
|
||||
GUILayout.BeginVertical(boxGuiStyle, GUILayout.Width(SdkWindowWidth));
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Fetching Records", titleGuiStyle);
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.BeginVertical(boxGuiStyle, GUILayout.Width(SdkWindowWidth));
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Fetch updated records from the VRChat server");
|
||||
if( GUILayout.Button("Fetch") )
|
||||
{
|
||||
ClearContent();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
OnGUIUserInfo();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7333cdb3df19724b84b4a1b05093fe0
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRC;
|
||||
using VRC.Core;
|
||||
using VRC.SDKBase;
|
||||
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
[MenuItem("VRChat SDK/Help/Developer FAQ")]
|
||||
public static void ShowDeveloperFAQ()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
ConfigManager.RemoteConfig.Init(() => ShowDeveloperFAQ());
|
||||
return;
|
||||
}
|
||||
|
||||
Application.OpenURL(ConfigManager.RemoteConfig.GetString("sdkDeveloperFaqUrl"));
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Help/VRChat Discord")]
|
||||
public static void ShowVRChatDiscord()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
ConfigManager.RemoteConfig.Init(() => ShowVRChatDiscord());
|
||||
return;
|
||||
}
|
||||
|
||||
Application.OpenURL(ConfigManager.RemoteConfig.GetString("sdkDiscordUrl"));
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Help/Avatar Optimization Tips")]
|
||||
public static void ShowAvatarOptimizationTips()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
ConfigManager.RemoteConfig.Init(() => ShowAvatarOptimizationTips());
|
||||
return;
|
||||
}
|
||||
|
||||
Application.OpenURL(AVATAR_OPTIMIZATION_TIPS_URL);
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Help/Avatar Rig Requirements")]
|
||||
public static void ShowAvatarRigRequirements()
|
||||
{
|
||||
if (!ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
ConfigManager.RemoteConfig.Init(() => ShowAvatarRigRequirements());
|
||||
return;
|
||||
}
|
||||
|
||||
Application.OpenURL(AVATAR_RIG_REQUIREMENTS_URL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3507a74e4b8cfd469afac127fa5f4e5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,265 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using VRC.Core;
|
||||
|
||||
public partial class VRCSdkControlPanel : EditorWindow
|
||||
{
|
||||
bool UseDevApi
|
||||
{
|
||||
get
|
||||
{
|
||||
return VRC.Core.API.GetApiUrl() == VRC.Core.API.devApiUrl;
|
||||
}
|
||||
}
|
||||
|
||||
string clientVersionDate;
|
||||
string sdkVersionDate;
|
||||
Vector2 settingsScroll;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
GetClientSdkVersionInformation();
|
||||
}
|
||||
|
||||
public void GetClientSdkVersionInformation()
|
||||
{
|
||||
clientVersionDate = VRC.Core.SDKClientUtilities.GetTestClientVersionDate();
|
||||
sdkVersionDate = VRC.Core.SDKClientUtilities.GetSDKVersionDate();
|
||||
}
|
||||
|
||||
public void OnConfigurationChanged()
|
||||
{
|
||||
GetClientSdkVersionInformation();
|
||||
}
|
||||
|
||||
void ShowSettings()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
settingsScroll = EditorGUILayout.BeginScrollView(settingsScroll, GUILayout.Width(SdkWindowWidth));
|
||||
|
||||
EditorGUILayout.BeginVertical(boxGuiStyle);
|
||||
EditorGUILayout.LabelField("Developer", EditorStyles.boldLabel);
|
||||
#if VRC_SDK_VRCSDK2
|
||||
VRCSettings.Get().DisplayAdvancedSettings = EditorGUILayout.ToggleLeft("Show Extra Options on build page and account page", VRCSettings.Get().DisplayAdvancedSettings);
|
||||
bool prevDisplayHelpBoxes = VRCSettings.Get().DisplayHelpBoxes;
|
||||
VRCSettings.Get().DisplayHelpBoxes = EditorGUILayout.ToggleLeft("Show Help Boxes on SDK components", VRCSettings.Get().DisplayHelpBoxes);
|
||||
if (VRCSettings.Get().DisplayHelpBoxes != prevDisplayHelpBoxes)
|
||||
#elif VRC_SDK_VRCSDK3
|
||||
VRC.SDK3.Editor.VRCSettings.Get().DisplayAdvancedSettings = EditorGUILayout.ToggleLeft("Show Extra Options on build page and account page", VRC.SDK3.Editor.VRCSettings.Get().DisplayAdvancedSettings);
|
||||
bool prevDisplayHelpBoxes = VRC.SDK3.Editor.VRCSettings.Get().DisplayHelpBoxes;
|
||||
VRC.SDK3.Editor.VRCSettings.Get().DisplayHelpBoxes = EditorGUILayout.ToggleLeft("Show Help Boxes on SDK components", VRC.SDK3.Editor.VRCSettings.Get().DisplayHelpBoxes);
|
||||
if (VRC.SDK3.Editor.VRCSettings.Get().DisplayHelpBoxes != prevDisplayHelpBoxes)
|
||||
#endif
|
||||
{
|
||||
Editor[] editors = (Editor[])Resources.FindObjectsOfTypeAll<Editor>();
|
||||
for (int i = 0; i < editors.Length; i++)
|
||||
{
|
||||
editors[i].Repaint();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
ShowSdk23CompatibilitySettings();
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
ShowSettingsOptionsForBuilders();
|
||||
|
||||
|
||||
// debugging
|
||||
if (APIUser.CurrentUser != null && APIUser.CurrentUser.hasSuperPowers)
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.BeginVertical(boxGuiStyle);
|
||||
|
||||
EditorGUILayout.LabelField("Logging", EditorStyles.boldLabel);
|
||||
|
||||
// API logging
|
||||
{
|
||||
bool isLoggingEnabled = UnityEditor.EditorPrefs.GetBool("apiLoggingEnabled");
|
||||
bool enableLogging = EditorGUILayout.ToggleLeft("API Logging Enabled", isLoggingEnabled);
|
||||
if (enableLogging != isLoggingEnabled)
|
||||
{
|
||||
if (enableLogging)
|
||||
VRC.Core.Logger.AddDebugLevel(DebugLevel.API);
|
||||
else
|
||||
VRC.Core.Logger.RemoveDebugLevel(DebugLevel.API);
|
||||
|
||||
UnityEditor.EditorPrefs.SetBool("apiLoggingEnabled", enableLogging);
|
||||
}
|
||||
}
|
||||
|
||||
// All logging
|
||||
{
|
||||
bool isLoggingEnabled = UnityEditor.EditorPrefs.GetBool("allLoggingEnabled");
|
||||
bool enableLogging = EditorGUILayout.ToggleLeft("All Logging Enabled", isLoggingEnabled);
|
||||
if (enableLogging != isLoggingEnabled)
|
||||
{
|
||||
if (enableLogging)
|
||||
VRC.Core.Logger.AddDebugLevel(DebugLevel.All);
|
||||
else
|
||||
VRC.Core.Logger.RemoveDebugLevel(DebugLevel.All);
|
||||
|
||||
UnityEditor.EditorPrefs.SetBool("allLoggingEnabled", enableLogging);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UnityEditor.EditorPrefs.GetBool("apiLoggingEnabled"))
|
||||
UnityEditor.EditorPrefs.SetBool("apiLoggingEnabled", false);
|
||||
if (UnityEditor.EditorPrefs.GetBool("allLoggingEnabled"))
|
||||
UnityEditor.EditorPrefs.SetBool("allLoggingEnabled", false);
|
||||
}
|
||||
|
||||
// Future proof upload
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.BeginVertical(boxGuiStyle);
|
||||
|
||||
EditorGUILayout.LabelField("Publish", EditorStyles.boldLabel);
|
||||
bool futureProofPublish = UnityEditor.EditorPrefs.GetBool("futureProofPublish", DefaultFutureProofPublishEnabled);
|
||||
|
||||
futureProofPublish = EditorGUILayout.ToggleLeft("Future Proof Publish", futureProofPublish);
|
||||
|
||||
if (UnityEditor.EditorPrefs.GetBool("futureProofPublish", DefaultFutureProofPublishEnabled) != futureProofPublish)
|
||||
{
|
||||
UnityEditor.EditorPrefs.SetBool("futureProofPublish", futureProofPublish);
|
||||
}
|
||||
EditorGUILayout.LabelField("Client Version Date", clientVersionDate);
|
||||
EditorGUILayout.LabelField("SDK Version Date", sdkVersionDate);
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
|
||||
if (APIUser.CurrentUser != null)
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.BeginVertical(boxGuiStyle);
|
||||
|
||||
// custom vrchat install location
|
||||
OnVRCInstallPathGUI();
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void OnVRCInstallPathGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("VRChat Client", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("Installed Client Path: ", clientInstallPath);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Label("");
|
||||
if (GUILayout.Button("Edit"))
|
||||
{
|
||||
string initPath = "";
|
||||
if (!string.IsNullOrEmpty(clientInstallPath))
|
||||
initPath = clientInstallPath;
|
||||
|
||||
clientInstallPath = EditorUtility.OpenFilePanel("Choose VRC Client Exe", initPath, "exe");
|
||||
SDKClientUtilities.SetVRCInstallPath(clientInstallPath);
|
||||
window.OnConfigurationChanged();
|
||||
}
|
||||
if (GUILayout.Button("Revert to Default"))
|
||||
{
|
||||
clientInstallPath = SDKClientUtilities.LoadRegistryVRCInstallPath();
|
||||
window.OnConfigurationChanged();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
|
||||
static void ShowSdk23CompatibilitySettings()
|
||||
{
|
||||
return;
|
||||
|
||||
// EditorGUILayout.BeginVertical(boxGuiStyle);
|
||||
// EditorGUILayout.LabelField("VRCSDK2 & VRCSDK3 Compatibility", EditorStyles.boldLabel);
|
||||
|
||||
//#if !VRC_CLIENT
|
||||
// bool sdk2Present = VRCSdk3Analysis.GetSDKInScene(VRCSdk3Analysis.SdkVersion.VRCSDK2).Count > 0;
|
||||
// bool sdk3Present = VRCSdk3Analysis.GetSDKInScene(VRCSdk3Analysis.SdkVersion.VRCSDK3).Count > 0;
|
||||
// bool sdk2DllActive = VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK2);
|
||||
// bool sdk3DllActive = VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
|
||||
// if ( sdk2DllActive && sdk3DllActive)
|
||||
// {
|
||||
// GUILayout.TextArea("You have not yet configured this project for development with VRCSDK2 and Triggers or VRCSDK3 and Udon. ");
|
||||
// if (sdk2Present && sdk3Present)
|
||||
// {
|
||||
// GUILayout.TextArea("This scene contains both SDK2 and SDK3 elements. " +
|
||||
// "Please modify this scene to contain only one type or the other before completing your configuration.");
|
||||
// }
|
||||
// else if (sdk2Present)
|
||||
// {
|
||||
// GUILayout.TextArea("This scene contains SDK2 scripts. " +
|
||||
// "Check below to configure this project for use with VRCSDK2 or remove your VRCSDK2 scripts to upgrade to VRCSDK3");
|
||||
// bool downgrade = EditorGUILayout.ToggleLeft("Configure for use with VRCSDK2 and Triggers", false);
|
||||
// if (downgrade)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK2);
|
||||
// }
|
||||
// else if (sdk3Present)
|
||||
// {
|
||||
// GUILayout.TextArea("This scene contains only SDK3 scripts and it ready to upgrade. " +
|
||||
// "Click below to get started.");
|
||||
// bool upgrade = EditorGUILayout.ToggleLeft("Configure for use with VRCSDK3 and Udon - Let's Rock!", false);
|
||||
// if (upgrade)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GUILayout.TextArea("This scene is a blank slate. " +
|
||||
// "Click below to get started.");
|
||||
// bool upgrade = EditorGUILayout.ToggleLeft("Configure for use with VRCSDK3 and Udon - Let's Rock!", false);
|
||||
// if (upgrade)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
// }
|
||||
// }
|
||||
// else if (sdk2DllActive)
|
||||
// {
|
||||
// GUILayout.TextArea("This project has been configured to be built with VRCSDK2. " +
|
||||
// "To upgrade, VRCSDK3 must be enabled here.");
|
||||
// bool upgrade = EditorGUILayout.ToggleLeft("VRCSDK3 Scripts can be used", false);
|
||||
// if (upgrade)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
// }
|
||||
// else if (sdk3DllActive)
|
||||
// {
|
||||
// GUILayout.TextArea("This project has been configured to be built with VRCSDK3. " +
|
||||
// "Congratulations, you're ready to go. " +
|
||||
// "You can still downgrade by activating VRCSDK2 here.");
|
||||
// bool downgrade = EditorGUILayout.ToggleLeft("VRCSDK2 Scripts can be used", false);
|
||||
// if (downgrade)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK2);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GUILayout.TextArea("Somehow you have disabled both VRCSDK2 and VRCSDK3. Oops. " +
|
||||
// "Click here to begin development with VRCSDK3.");
|
||||
// bool begin = EditorGUILayout.ToggleLeft("VRCSDK3 Scripts can be used", false);
|
||||
// if (begin)
|
||||
// VRCSdk3Analysis.SetSdkVersionActive(VRCSdk3Analysis.SdkVersion.VRCSDK3);
|
||||
// }
|
||||
//#else
|
||||
// GUILayout.TextArea("I think you're in the main VRChat project. " +
|
||||
// "You should not be enabling or disabling SDKs from here.");
|
||||
//#endif
|
||||
|
||||
// EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8357b9b7ef2416946ae86f465a64c0e0
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+1048
File diff suppressed because it is too large.
Load diff
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2a720a30f1043247af7742fdfd0b8e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,773 @@
|
||||
#define ENV_SET_INCLUDED_SHADERS
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine.Rendering;
|
||||
using VRCSDK2.Validation.Performance.Stats;
|
||||
|
||||
/// <summary>
|
||||
/// Setup up SDK env on editor launch
|
||||
/// </summary>
|
||||
[InitializeOnLoad]
|
||||
public class EnvConfig
|
||||
{
|
||||
static BuildTarget[] relevantBuildTargets = new BuildTarget[] {
|
||||
BuildTarget.Android, BuildTarget.iOS,
|
||||
BuildTarget.StandaloneLinux64,
|
||||
BuildTarget.StandaloneWindows, BuildTarget.StandaloneWindows64,
|
||||
BuildTarget.StandaloneOSX
|
||||
};
|
||||
|
||||
#if !VRC_CLIENT
|
||||
static BuildTarget[] allowedBuildtargets = new BuildTarget[]
|
||||
{
|
||||
BuildTarget.StandaloneWindows64,
|
||||
BuildTarget.Android
|
||||
};
|
||||
#endif
|
||||
|
||||
static System.Collections.Generic.Dictionary<BuildTarget, UnityEngine.Rendering.GraphicsDeviceType[]> allowedGraphicsAPIs = new System.Collections.Generic.Dictionary<BuildTarget, UnityEngine.Rendering.GraphicsDeviceType[]>()
|
||||
{
|
||||
{ BuildTarget.Android, new [] { GraphicsDeviceType.OpenGLES3, /* GraphicsDeviceType.Vulkan */ }},
|
||||
{ BuildTarget.iOS, null },
|
||||
{ BuildTarget.StandaloneLinux64, null },
|
||||
{ BuildTarget.StandaloneWindows, new UnityEngine.Rendering.GraphicsDeviceType[] { UnityEngine.Rendering.GraphicsDeviceType.Direct3D11 } },
|
||||
{ BuildTarget.StandaloneWindows64, new UnityEngine.Rendering.GraphicsDeviceType[] { UnityEngine.Rendering.GraphicsDeviceType.Direct3D11 } },
|
||||
{ BuildTarget.StandaloneOSX, null }
|
||||
};
|
||||
|
||||
#if ENV_SET_INCLUDED_SHADERS && VRC_CLIENT
|
||||
static string[] ensureTheseShadersAreAvailable = new string[]
|
||||
{
|
||||
"Hidden/CubeBlend",
|
||||
"Hidden/CubeBlur",
|
||||
"Hidden/CubeCopy",
|
||||
"Hidden/VideoDecode",
|
||||
"Legacy Shaders/Bumped Diffuse",
|
||||
"Legacy Shaders/Bumped Specular",
|
||||
"Legacy Shaders/Decal",
|
||||
"Legacy Shaders/Diffuse Detail",
|
||||
"Legacy Shaders/Diffuse Fast",
|
||||
"Legacy Shaders/Diffuse",
|
||||
"Legacy Shaders/Diffuse",
|
||||
"Legacy Shaders/Lightmapped/Diffuse",
|
||||
"Legacy Shaders/Lightmapped/Specular",
|
||||
"Legacy Shaders/Lightmapped/VertexLit",
|
||||
"Legacy Shaders/Parallax Diffuse",
|
||||
"Legacy Shaders/Parallax Specular",
|
||||
"Legacy Shaders/Reflective/Bumped Diffuse",
|
||||
"Legacy Shaders/Reflective/Bumped Specular",
|
||||
"Legacy Shaders/Reflective/Bumped Unlit",
|
||||
"Legacy Shaders/Reflective/Bumped VertexLit",
|
||||
"Legacy Shaders/Reflective/Diffuse",
|
||||
"Legacy Shaders/Reflective/Parallax Diffuse",
|
||||
"Legacy Shaders/Reflective/Parallax Specular",
|
||||
"Legacy Shaders/Reflective/Specular",
|
||||
"Legacy Shaders/Reflective/VertexLit",
|
||||
"Legacy Shaders/Self-Illumin/Bumped Diffuse",
|
||||
"Legacy Shaders/Self-Illumin/Bumped Specular",
|
||||
"Legacy Shaders/Self-Illumin/Diffuse",
|
||||
"Legacy Shaders/Self-Illumin/Parallax Diffuse",
|
||||
"Legacy Shaders/Self-Illumin/Parallax Specular",
|
||||
"Legacy Shaders/Self-Illumin/Specular",
|
||||
"Legacy Shaders/Self-Illumin/VertexLit",
|
||||
"Legacy Shaders/Specular",
|
||||
"Legacy Shaders/Transparent/Bumped Diffuse",
|
||||
"Legacy Shaders/Transparent/Bumped Specular",
|
||||
"Legacy Shaders/Transparent/Cutout/Bumped Diffuse",
|
||||
"Legacy Shaders/Transparent/Cutout/Bumped Specular",
|
||||
"Legacy Shaders/Transparent/Cutout/Diffuse",
|
||||
"Legacy Shaders/Transparent/Cutout/Soft Edge Unlit",
|
||||
"Legacy Shaders/Transparent/Cutout/Specular",
|
||||
"Legacy Shaders/Transparent/Cutout/VertexLit",
|
||||
"Legacy Shaders/Transparent/Diffuse",
|
||||
"Legacy Shaders/Transparent/Parallax Diffuse",
|
||||
"Legacy Shaders/Transparent/Parallax Specular",
|
||||
"Legacy Shaders/Transparent/Specular",
|
||||
"Legacy Shaders/Transparent/VertexLit",
|
||||
"Legacy Shaders/VertexLit",
|
||||
"Mobile/Particles/Additive",
|
||||
"Mobile/Particles/Alpha Blended",
|
||||
"Mobile/Particles/Multiply",
|
||||
"Mobile/Particles/VertexLit Blended",
|
||||
"Mobile/Skybox",
|
||||
"Nature/Terrain/Diffuse",
|
||||
"Nature/Terrain/Specular",
|
||||
"Nature/Terrain/Standard",
|
||||
"Particles/Additive (Soft)",
|
||||
"Particles/Additive",
|
||||
"Particles/Alpha Blended Premultiply",
|
||||
"Particles/Alpha Blended",
|
||||
"Particles/Anim Alpha Blended",
|
||||
"Particles/Multiply (Double)",
|
||||
"Particles/Multiply",
|
||||
"Particles/VertexLit Blended",
|
||||
"Particles/~Additive-Multiply",
|
||||
"Skybox/Cubemap",
|
||||
"Skybox/Procedural",
|
||||
"Skybox/6 Sided",
|
||||
"Sprites/Default",
|
||||
"Sprites/Diffuse",
|
||||
"UI/Default",
|
||||
"VRChat/UI/Unlit/WebPanelTransparent",
|
||||
"Toon/Lit",
|
||||
"Toon/Lit (Double)",
|
||||
"Toon/Lit Cutout",
|
||||
"Toon/Lit Cutout (Double)",
|
||||
"Toon/Lit Outline",
|
||||
"VRChat/Mobile/Diffuse",
|
||||
"Video/RealtimeEmissiveGamma",
|
||||
"VRChat/Mobile/Bumped Uniform Diffuse",
|
||||
"VRChat/Mobile/Bumped Uniform Specular",
|
||||
"VRChat/Mobile/Toon Lit",
|
||||
"VRChat/Mobile/MatCap Lit",
|
||||
"VRChat/Mobile/Skybox",
|
||||
"VRChat/Mobile/Lightmapped",
|
||||
"VRChat/PC/Toon Lit",
|
||||
"VRChat/PC/Toon Lit (Double)",
|
||||
"VRChat/PC/Toon Lit Cutout",
|
||||
"VRChat/PC/Toon Lit Cutout (Double)",
|
||||
"Unlit/Color",
|
||||
"Unlit/Transparent",
|
||||
"Unlit/Transparent Cutout",
|
||||
"Unlit/Texture",
|
||||
"MatCap/Vertex/Textured Lit",
|
||||
};
|
||||
#endif
|
||||
|
||||
private static bool _requestConfigureSettings = true;
|
||||
|
||||
static EnvConfig()
|
||||
{
|
||||
EditorApplication.update += EditorUpdate;
|
||||
}
|
||||
|
||||
static void EditorUpdate()
|
||||
{
|
||||
if (_requestConfigureSettings)
|
||||
{
|
||||
if (ConfigureSettings())
|
||||
{
|
||||
_requestConfigureSettings = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RequestConfigureSettings()
|
||||
{
|
||||
_requestConfigureSettings = true;
|
||||
}
|
||||
|
||||
[UnityEditor.Callbacks.DidReloadScripts(int.MaxValue)]
|
||||
static void DidReloadScripts()
|
||||
{
|
||||
RequestConfigureSettings();
|
||||
}
|
||||
|
||||
public static bool ConfigureSettings()
|
||||
{
|
||||
CheckForFirstInit();
|
||||
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode || EditorApplication.isUpdating)
|
||||
return false;
|
||||
|
||||
ConfigurePlayerSettings();
|
||||
|
||||
if (!VRC.Core.ConfigManager.RemoteConfig.IsInitialized())
|
||||
{
|
||||
VRC.Core.API.SetOnlineMode(true, "vrchat");
|
||||
VRC.Core.ConfigManager.RemoteConfig.Init();
|
||||
}
|
||||
|
||||
LoadEditorResources();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SetDLLPlatforms(string dllName, bool active)
|
||||
{
|
||||
string[] assetGuids = AssetDatabase.FindAssets(dllName);
|
||||
|
||||
foreach (string guid in assetGuids)
|
||||
{
|
||||
string dllPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (string.IsNullOrEmpty(dllPath) || dllPath.ToLower().EndsWith(".dll") == false)
|
||||
return;
|
||||
|
||||
PluginImporter importer = AssetImporter.GetAtPath(dllPath) as PluginImporter;
|
||||
|
||||
bool allCorrect = true;
|
||||
if (importer.GetCompatibleWithAnyPlatform() != active)
|
||||
{
|
||||
allCorrect = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (importer.GetCompatibleWithAnyPlatform())
|
||||
{
|
||||
if (importer.GetExcludeEditorFromAnyPlatform() != !active ||
|
||||
importer.GetExcludeFromAnyPlatform(BuildTarget.StandaloneWindows) != !active)
|
||||
{
|
||||
allCorrect = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (importer.GetCompatibleWithEditor() != active ||
|
||||
importer.GetCompatibleWithPlatform(BuildTarget.StandaloneWindows) != active)
|
||||
{
|
||||
allCorrect = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (allCorrect == false)
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
importer.SetCompatibleWithAnyPlatform(true);
|
||||
importer.SetExcludeEditorFromAnyPlatform(false);
|
||||
importer.SetExcludeFromAnyPlatform(BuildTarget.Android, false);
|
||||
importer.SetExcludeFromAnyPlatform(BuildTarget.StandaloneWindows, false);
|
||||
importer.SetExcludeFromAnyPlatform(BuildTarget.StandaloneWindows64, false);
|
||||
importer.SetExcludeFromAnyPlatform(BuildTarget.StandaloneLinux64, false);
|
||||
importer.SetExcludeFromAnyPlatform(BuildTarget.StandaloneOSX, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
importer.SetCompatibleWithAnyPlatform(false);
|
||||
importer.SetCompatibleWithEditor(false);
|
||||
importer.SetCompatibleWithPlatform(BuildTarget.Android, false);
|
||||
importer.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false);
|
||||
importer.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false);
|
||||
importer.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false);
|
||||
importer.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false);
|
||||
}
|
||||
importer.SaveAndReimport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Utilities/Force Configure Player Settings")]
|
||||
public static void ConfigurePlayerSettings()
|
||||
{
|
||||
VRC.Core.Logger.Log("Setting required PlayerSettings...", VRC.Core.DebugLevel.All);
|
||||
|
||||
SetBuildTarget();
|
||||
|
||||
// Needed for Microsoft.CSharp namespace in DLLMaker
|
||||
// Doesn't seem to work though
|
||||
if (PlayerSettings.GetApiCompatibilityLevel(EditorUserBuildSettings.selectedBuildTargetGroup) != ApiCompatibilityLevel.NET_4_6)
|
||||
PlayerSettings.SetApiCompatibilityLevel(EditorUserBuildSettings.selectedBuildTargetGroup, ApiCompatibilityLevel.NET_4_6);
|
||||
|
||||
if (!PlayerSettings.runInBackground)
|
||||
PlayerSettings.runInBackground = true;
|
||||
|
||||
#if !VRC_CLIENT
|
||||
SetDLLPlatforms("VRCCore-Standalone", false);
|
||||
SetDLLPlatforms("VRCCore-Editor", true);
|
||||
#endif
|
||||
|
||||
SetDefaultGraphicsAPIs();
|
||||
SetGraphicsSettings();
|
||||
SetAudioSettings();
|
||||
SetPlayerSettings();
|
||||
|
||||
#if VRC_CLIENT
|
||||
PlatformSwitcher.RefreshRequiredPackages(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
#else
|
||||
// SDK
|
||||
|
||||
// default to steam runtime in sdk (shouldn't matter)
|
||||
SetVRSDKs(EditorUserBuildSettings.selectedBuildTargetGroup, new string[] { "None", "OpenVR", "Oculus" });
|
||||
|
||||
VRC.Core.AnalyticsSDK.Initialize(VRC.Core.SDKClientUtilities.GetSDKVersionDate());
|
||||
#endif
|
||||
|
||||
#if VRC_CLIENT
|
||||
// VRCLog should handle disk writing
|
||||
PlayerSettings.usePlayerLog = false;
|
||||
foreach (LogType logType in Enum.GetValues(typeof(LogType)).Cast<LogType>())
|
||||
{
|
||||
switch(logType)
|
||||
{
|
||||
case LogType.Assert:
|
||||
case LogType.Exception:
|
||||
{
|
||||
PlayerSettings.SetStackTraceLogType(logType, StackTraceLogType.ScriptOnly);
|
||||
break;
|
||||
}
|
||||
case LogType.Error:
|
||||
case LogType.Warning:
|
||||
case LogType.Log:
|
||||
{
|
||||
PlayerSettings.SetStackTraceLogType(logType, StackTraceLogType.None);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void EnableBatching(bool enable)
|
||||
{
|
||||
PlayerSettings[] playerSettings = Resources.FindObjectsOfTypeAll<PlayerSettings>();
|
||||
if (playerSettings == null)
|
||||
return;
|
||||
|
||||
SerializedObject playerSettingsSerializedObject = new SerializedObject(playerSettings);
|
||||
SerializedProperty batchingSettings = playerSettingsSerializedObject.FindProperty("m_BuildTargetBatching");
|
||||
if (batchingSettings == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < batchingSettings.arraySize; i++)
|
||||
{
|
||||
SerializedProperty batchingArrayValue = batchingSettings.GetArrayElementAtIndex(i);
|
||||
if (batchingArrayValue == null)
|
||||
continue;
|
||||
|
||||
IEnumerator batchingEnumerator = batchingArrayValue.GetEnumerator();
|
||||
if (batchingEnumerator == null)
|
||||
continue;
|
||||
|
||||
while (batchingEnumerator.MoveNext())
|
||||
{
|
||||
SerializedProperty property = (SerializedProperty)batchingEnumerator.Current;
|
||||
|
||||
if (property != null && property.name == "m_BuildTarget")
|
||||
{
|
||||
// only change setting on "Standalone" entry
|
||||
if (property.stringValue != "Standalone")
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (property != null && property.name == "m_StaticBatching")
|
||||
{
|
||||
property.boolValue = enable;
|
||||
}
|
||||
|
||||
if (property != null && property.name == "m_DynamicBatching")
|
||||
{
|
||||
property.boolValue = enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playerSettingsSerializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
public static void SetVRSDKs(BuildTargetGroup buildTargetGroup, string[] sdkNames)
|
||||
{
|
||||
VRC.Core.Logger.Log("Setting virtual reality SDKs in PlayerSettings: ", VRC.Core.DebugLevel.All);
|
||||
if (sdkNames != null)
|
||||
{
|
||||
foreach (string s in sdkNames)
|
||||
VRC.Core.Logger.Log("- " + s, VRC.Core.DebugLevel.All);
|
||||
}
|
||||
|
||||
PlayerSettings.SetVirtualRealitySDKs(buildTargetGroup, sdkNames);
|
||||
}
|
||||
|
||||
public static bool CheckForFirstInit()
|
||||
{
|
||||
bool firstLaunch = UnityEditor.SessionState.GetBool("EnvConfigFirstLaunch", true);
|
||||
if (firstLaunch)
|
||||
UnityEditor.SessionState.SetBool("EnvConfigFirstLaunch", false);
|
||||
|
||||
return firstLaunch;
|
||||
}
|
||||
|
||||
static void SetDefaultGraphicsAPIs()
|
||||
{
|
||||
VRC.Core.Logger.Log("Setting Graphics APIs", VRC.Core.DebugLevel.All);
|
||||
foreach (BuildTarget target in relevantBuildTargets)
|
||||
{
|
||||
var apis = allowedGraphicsAPIs[target];
|
||||
if (apis == null)
|
||||
SetGraphicsAPIs(target, true);
|
||||
else
|
||||
SetGraphicsAPIs(target, false, apis);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetGraphicsAPIs(BuildTarget platform, bool auto, UnityEngine.Rendering.GraphicsDeviceType[] allowedTypes = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (auto != PlayerSettings.GetUseDefaultGraphicsAPIs(platform))
|
||||
PlayerSettings.SetUseDefaultGraphicsAPIs(platform, auto);
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
UnityEngine.Rendering.GraphicsDeviceType[] graphicsAPIs = PlayerSettings.GetGraphicsAPIs(platform);
|
||||
if (((allowedTypes == null || allowedTypes.Length == 0) &&
|
||||
(graphicsAPIs != null || graphicsAPIs.Length != 0))
|
||||
|| !allowedTypes.SequenceEqual(graphicsAPIs))
|
||||
{
|
||||
if (allowedTypes == null)
|
||||
{
|
||||
allowedTypes = PlayerSettings.GetGraphicsAPIs(platform);
|
||||
}
|
||||
PlayerSettings.SetGraphicsAPIs(platform, allowedTypes);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
static void SetGraphicsSettings()
|
||||
{
|
||||
VRC.Core.Logger.Log("Setting Graphics Settings", VRC.Core.DebugLevel.All);
|
||||
|
||||
const string GraphicsSettingsAssetPath = "ProjectSettings/GraphicsSettings.asset";
|
||||
SerializedObject graphicsManager = new SerializedObject(UnityEditor.AssetDatabase.LoadAllAssetsAtPath(GraphicsSettingsAssetPath)[0]);
|
||||
|
||||
SerializedProperty deferred = graphicsManager.FindProperty("m_Deferred.m_Mode");
|
||||
deferred.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty deferredReflections = graphicsManager.FindProperty("m_DeferredReflections.m_Mode");
|
||||
deferredReflections.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty screenSpaceShadows = graphicsManager.FindProperty("m_ScreenSpaceShadows.m_Mode");
|
||||
screenSpaceShadows.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty legacyDeferred = graphicsManager.FindProperty("m_LegacyDeferred.m_Mode");
|
||||
legacyDeferred.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty depthNormals = graphicsManager.FindProperty("m_DepthNormals.m_Mode");
|
||||
depthNormals.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty motionVectors = graphicsManager.FindProperty("m_MotionVectors.m_Mode");
|
||||
motionVectors.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty lightHalo = graphicsManager.FindProperty("m_LightHalo.m_Mode");
|
||||
lightHalo.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty lensFlare = graphicsManager.FindProperty("m_LensFlare.m_Mode");
|
||||
lensFlare.enumValueIndex = 1;
|
||||
|
||||
#if ENV_SET_INCLUDED_SHADERS && VRC_CLIENT
|
||||
SerializedProperty alwaysIncluded = graphicsManager.FindProperty("m_AlwaysIncludedShaders");
|
||||
alwaysIncluded.arraySize = 0; // clear GraphicsSettings->Always Included Shaders - these cause a +5s app startup time increase on Quest.
|
||||
// include Shader objects as resources instead
|
||||
|
||||
#if ENV_SEARCH_FOR_SHADERS
|
||||
Resources.LoadAll("", typeof(Shader));
|
||||
System.Collections.Generic.List<Shader> foundShaders = Resources.FindObjectsOfTypeAll<Shader>()
|
||||
.Where(s => { string name = s.name.ToLower(); return 0 == (s.hideFlags & HideFlags.DontSave); })
|
||||
.GroupBy(s => s.name)
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
#else
|
||||
System.Collections.Generic.List<Shader> foundShaders = new System.Collections.Generic.List<Shader>();
|
||||
#endif
|
||||
|
||||
for (int shaderIdx = 0; shaderIdx < ensureTheseShadersAreAvailable.Length; ++shaderIdx)
|
||||
{
|
||||
if (foundShaders.Any(s => s.name == ensureTheseShadersAreAvailable[shaderIdx]))
|
||||
continue;
|
||||
Shader namedShader = Shader.Find(ensureTheseShadersAreAvailable[shaderIdx]);
|
||||
if (namedShader != null)
|
||||
foundShaders.Add(namedShader);
|
||||
}
|
||||
|
||||
foundShaders.Sort((s1, s2) => s1.name.CompareTo(s2.name));
|
||||
|
||||
// populate Resources list of "always included shaders"
|
||||
ShaderAssetList alwaysIncludedShaders = AssetDatabase.LoadAssetAtPath<ShaderAssetList>("Assets/Resources/AlwaysIncludedShaders.asset");
|
||||
alwaysIncludedShaders.Shaders = new Shader[foundShaders.Count];
|
||||
for (int shaderIdx = 0; shaderIdx < foundShaders.Count; ++shaderIdx)
|
||||
alwaysIncludedShaders.Shaders[shaderIdx] = foundShaders[shaderIdx];
|
||||
#endif
|
||||
|
||||
SerializedProperty preloaded = graphicsManager.FindProperty("m_PreloadedShaders");
|
||||
preloaded.ClearArray();
|
||||
preloaded.arraySize = 0;
|
||||
|
||||
SerializedProperty spritesDefaultMaterial = graphicsManager.FindProperty("m_SpritesDefaultMaterial");
|
||||
spritesDefaultMaterial.objectReferenceValue = Shader.Find("Sprites/Default");
|
||||
|
||||
SerializedProperty renderPipeline = graphicsManager.FindProperty("m_CustomRenderPipeline");
|
||||
renderPipeline.objectReferenceValue = null;
|
||||
|
||||
SerializedProperty transparencySortMode = graphicsManager.FindProperty("m_TransparencySortMode");
|
||||
transparencySortMode.enumValueIndex = 0;
|
||||
|
||||
SerializedProperty transparencySortAxis = graphicsManager.FindProperty("m_TransparencySortAxis");
|
||||
transparencySortAxis.vector3Value = Vector3.forward;
|
||||
|
||||
SerializedProperty defaultRenderingPath = graphicsManager.FindProperty("m_DefaultRenderingPath");
|
||||
defaultRenderingPath.intValue = 1;
|
||||
|
||||
SerializedProperty defaultMobileRenderingPath = graphicsManager.FindProperty("m_DefaultMobileRenderingPath");
|
||||
defaultMobileRenderingPath.intValue = 1;
|
||||
|
||||
SerializedProperty tierSettings = graphicsManager.FindProperty("m_TierSettings");
|
||||
tierSettings.ClearArray();
|
||||
tierSettings.arraySize = 0;
|
||||
|
||||
#if ENV_SET_LIGHTMAP
|
||||
SerializedProperty lightmapStripping = graphicsManager.FindProperty("m_LightmapStripping");
|
||||
lightmapStripping.enumValueIndex = 1;
|
||||
|
||||
SerializedProperty instancingStripping = graphicsManager.FindProperty("m_InstancingStripping");
|
||||
instancingStripping.enumValueIndex = 2;
|
||||
|
||||
SerializedProperty lightmapKeepPlain = graphicsManager.FindProperty("m_LightmapKeepPlain");
|
||||
lightmapKeepPlain.boolValue = true;
|
||||
|
||||
SerializedProperty lightmapKeepDirCombined = graphicsManager.FindProperty("m_LightmapKeepDirCombined");
|
||||
lightmapKeepDirCombined.boolValue = true;
|
||||
|
||||
SerializedProperty lightmapKeepDynamicPlain = graphicsManager.FindProperty("m_LightmapKeepDynamicPlain");
|
||||
lightmapKeepDynamicPlain.boolValue = true;
|
||||
|
||||
SerializedProperty lightmapKeepDynamicDirCombined = graphicsManager.FindProperty("m_LightmapKeepDynamicDirCombined");
|
||||
lightmapKeepDynamicDirCombined.boolValue = true;
|
||||
|
||||
SerializedProperty lightmapKeepShadowMask = graphicsManager.FindProperty("m_LightmapKeepShadowMask");
|
||||
lightmapKeepShadowMask.boolValue = true;
|
||||
|
||||
SerializedProperty lightmapKeepSubtractive = graphicsManager.FindProperty("m_LightmapKeepSubtractive");
|
||||
lightmapKeepSubtractive.boolValue = true;
|
||||
#endif
|
||||
|
||||
SerializedProperty albedoSwatchInfos = graphicsManager.FindProperty("m_AlbedoSwatchInfos");
|
||||
albedoSwatchInfos.ClearArray();
|
||||
albedoSwatchInfos.arraySize = 0;
|
||||
|
||||
SerializedProperty lightsUseLinearIntensity = graphicsManager.FindProperty("m_LightsUseLinearIntensity");
|
||||
lightsUseLinearIntensity.boolValue = true;
|
||||
|
||||
SerializedProperty lightsUseColorTemperature = graphicsManager.FindProperty("m_LightsUseColorTemperature");
|
||||
lightsUseColorTemperature.boolValue = true;
|
||||
|
||||
graphicsManager.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
public static FogSettings GetFogSettings()
|
||||
{
|
||||
VRC.Core.Logger.Log("Force-enabling Fog", VRC.Core.DebugLevel.All);
|
||||
|
||||
const string graphicsSettingsAssetPath = "ProjectSettings/GraphicsSettings.asset";
|
||||
SerializedObject graphicsManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath(graphicsSettingsAssetPath)[0]);
|
||||
|
||||
|
||||
SerializedProperty fogStrippingSerializedProperty = graphicsManager.FindProperty("m_FogStripping");
|
||||
FogSettings.FogStrippingMode fogStripping = (FogSettings.FogStrippingMode)fogStrippingSerializedProperty.enumValueIndex;
|
||||
|
||||
SerializedProperty fogKeepLinearSerializedProperty = graphicsManager.FindProperty("m_FogKeepLinear");
|
||||
bool keepLinear = fogKeepLinearSerializedProperty.boolValue;
|
||||
|
||||
SerializedProperty fogKeepExpSerializedProperty = graphicsManager.FindProperty("m_FogKeepExp");
|
||||
bool keepExp = fogKeepExpSerializedProperty.boolValue;
|
||||
|
||||
SerializedProperty fogKeepExp2SerializedProperty = graphicsManager.FindProperty("m_FogKeepExp2");
|
||||
bool keepExp2 = fogKeepExp2SerializedProperty.boolValue;
|
||||
|
||||
FogSettings fogSettings = new FogSettings(fogStripping, keepLinear, keepExp, keepExp2);
|
||||
return fogSettings;
|
||||
}
|
||||
|
||||
public static void SetFogSettings(FogSettings fogSettings)
|
||||
{
|
||||
VRC.Core.Logger.Log("Force-enabling Fog", VRC.Core.DebugLevel.All);
|
||||
|
||||
const string graphicsSettingsAssetPath = "ProjectSettings/GraphicsSettings.asset";
|
||||
SerializedObject graphicsManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath(graphicsSettingsAssetPath)[0]);
|
||||
|
||||
SerializedProperty fogStripping = graphicsManager.FindProperty("m_FogStripping");
|
||||
fogStripping.enumValueIndex = (int)fogSettings.fogStrippingMode;
|
||||
|
||||
SerializedProperty fogKeepLinear = graphicsManager.FindProperty("m_FogKeepLinear");
|
||||
fogKeepLinear.boolValue = fogSettings.keepLinear;
|
||||
|
||||
SerializedProperty fogKeepExp = graphicsManager.FindProperty("m_FogKeepExp");
|
||||
fogKeepExp.boolValue = fogSettings.keepExp;
|
||||
|
||||
SerializedProperty fogKeepExp2 = graphicsManager.FindProperty("m_FogKeepExp2");
|
||||
fogKeepExp2.boolValue = fogSettings.keepExp2;
|
||||
|
||||
graphicsManager.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
static void SetAudioSettings()
|
||||
{
|
||||
var config = AudioSettings.GetConfiguration();
|
||||
config.dspBufferSize = 0; // use default
|
||||
config.speakerMode = AudioSpeakerMode.Stereo; // use default
|
||||
config.sampleRate = 48000; // forcing 48k seems to avoid sample rate conversion problems
|
||||
if (EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.Android)
|
||||
{
|
||||
config.numRealVoices = 24;
|
||||
config.numVirtualVoices = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
config.numRealVoices = 32;
|
||||
config.numVirtualVoices = 64;
|
||||
}
|
||||
AudioSettings.Reset(config);
|
||||
}
|
||||
|
||||
static void SetPlayerSettings()
|
||||
{
|
||||
// asset bundles MUST be built with settings that are compatible with VRC client
|
||||
#if VRC_OVERRIDE_COLORSPACE_GAMMA
|
||||
PlayerSettings.colorSpace = ColorSpace.Gamma;
|
||||
#else
|
||||
PlayerSettings.colorSpace = ColorSpace.Linear;
|
||||
#endif
|
||||
|
||||
#if !VRC_CLIENT // In client rely on platform-switcher
|
||||
PlayerSettings.SetVirtualRealitySupported(EditorUserBuildSettings.selectedBuildTargetGroup, true);
|
||||
#endif
|
||||
|
||||
PlayerSettings.graphicsJobs = false; // else we get occasional crashing
|
||||
|
||||
PlayerSettings.gpuSkinning = true;
|
||||
|
||||
PlayerSettings.stereoRenderingPath = StereoRenderingPath.SinglePass;
|
||||
|
||||
#if UNITY_2018_4_OR_NEWER
|
||||
PlayerSettings.scriptingRuntimeVersion = ScriptingRuntimeVersion.Latest;
|
||||
#endif
|
||||
|
||||
#if VRC_VR_OCULUS_QUEST
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
#elif VRC_VR_FOCUS
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7;
|
||||
#endif
|
||||
|
||||
#if UNITY_ANDROID
|
||||
if(PlayerSettings.Android.targetArchitectures.HasFlag(AndroidArchitecture.ARM64))
|
||||
{
|
||||
// Since we need different IL2CPP args we can't build ARM64 with other Architectures.
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
PlayerSettings.SetAdditionalIl2CppArgs("");
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerSettings.SetAdditionalIl2CppArgs("--linker-flags=\"-long-plt\"");
|
||||
}
|
||||
#else
|
||||
PlayerSettings.SetAdditionalIl2CppArgs("");
|
||||
#endif
|
||||
|
||||
SetActiveSDKDefines();
|
||||
|
||||
EnableBatching(true);
|
||||
}
|
||||
|
||||
public static void SetActiveSDKDefines()
|
||||
{
|
||||
bool definesChanged = false;
|
||||
BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
List<string> defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList();
|
||||
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
if (assemblies.Any(assembly => assembly.GetType("VRC.Udon.UdonBehaviour") != null))
|
||||
{
|
||||
if (!defines.Contains("UDON", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
defines.Add("UDON");
|
||||
definesChanged = true;
|
||||
}
|
||||
}
|
||||
else if (defines.Contains("UDON"))
|
||||
defines.Remove("UDON");
|
||||
|
||||
if (VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK2))
|
||||
{
|
||||
if (!defines.Contains("VRC_SDK_VRCSDK2", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
defines.Add("VRC_SDK_VRCSDK2");
|
||||
definesChanged = true;
|
||||
}
|
||||
}
|
||||
else if (defines.Contains("VRC_SDK_VRCSDK2"))
|
||||
defines.Remove("VRC_SDK_VRCSDK2");
|
||||
|
||||
if (VRCSdk3Analysis.IsSdkDllActive(VRCSdk3Analysis.SdkVersion.VRCSDK3))
|
||||
{
|
||||
if (!defines.Contains("VRC_SDK_VRCSDK3", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
defines.Add("VRC_SDK_VRCSDK3");
|
||||
definesChanged = true;
|
||||
}
|
||||
}
|
||||
else if (defines.Contains("VRC_SDK_VRCSDK3"))
|
||||
defines.Remove("VRC_SDK_VRCSDK3");
|
||||
|
||||
if (definesChanged)
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", defines.ToArray()));
|
||||
}
|
||||
|
||||
static void SetBuildTarget()
|
||||
{
|
||||
#if !VRC_CLIENT
|
||||
VRC.Core.Logger.Log("Setting build target", VRC.Core.DebugLevel.All);
|
||||
|
||||
BuildTarget target = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
|
||||
|
||||
if (!allowedBuildtargets.Contains(target))
|
||||
{
|
||||
Debug.LogError("Target not supported, switching to one that is.");
|
||||
target = allowedBuildtargets[0];
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
EditorUserBuildSettings.SwitchActiveBuildTarget(target);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void LoadEditorResources()
|
||||
{
|
||||
AvatarPerformanceStats.Initialize();
|
||||
}
|
||||
|
||||
public struct FogSettings
|
||||
{
|
||||
public enum FogStrippingMode
|
||||
{
|
||||
Automatic,
|
||||
Custom
|
||||
}
|
||||
|
||||
public readonly FogStrippingMode fogStrippingMode;
|
||||
public readonly bool keepLinear;
|
||||
public readonly bool keepExp;
|
||||
public readonly bool keepExp2;
|
||||
|
||||
public FogSettings(FogStrippingMode fogStrippingMode)
|
||||
{
|
||||
this.fogStrippingMode = fogStrippingMode;
|
||||
keepLinear = true;
|
||||
keepExp = true;
|
||||
keepExp2 = true;
|
||||
}
|
||||
|
||||
public FogSettings(FogStrippingMode fogStrippingMode, bool keepLinear, bool keepExp, bool keepExp2)
|
||||
{
|
||||
this.fogStrippingMode = fogStrippingMode;
|
||||
this.keepLinear = keepLinear;
|
||||
this.keepExp = keepExp;
|
||||
this.keepExp2 = keepExp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10d9f721d76e07a47bc9e5f61e2fae72
|
||||
timeCreated: 1455115256
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public static class HDRColorFixerUtility
|
||||
{
|
||||
[MenuItem("VRChat SDK/Utilities/Convert HDR Material Colors/To Linear", false, 995)]
|
||||
private static void ConvertToLinear()
|
||||
{
|
||||
if (!TryConvert())
|
||||
EditorUtility.DisplayDialog("Error", "Please select one or more HDR materials to convert.", "OK");
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Utilities/Convert HDR Material Colors/To Gamma", false, 996)]
|
||||
private static void ConvertToGamma()
|
||||
{
|
||||
if (!TryConvert(false))
|
||||
EditorUtility.DisplayDialog("Error", "Please select one or more HDR materials to convert.", "OK");
|
||||
}
|
||||
|
||||
static bool TryConvert(bool toLinear = true)
|
||||
{
|
||||
Object[] selection = Selection.objects;
|
||||
if (selection == null)
|
||||
return false;
|
||||
|
||||
int matCount = 0;
|
||||
int colorCount = 0;
|
||||
foreach (Material mat in selection)
|
||||
{
|
||||
matCount++;
|
||||
MaterialProperty[] props = MaterialEditor.GetMaterialProperties(new Material[] { mat });
|
||||
if ((props == null) || (props.Length == 0))
|
||||
return false;
|
||||
|
||||
foreach (MaterialProperty m in props)
|
||||
{
|
||||
if (m.flags == MaterialProperty.PropFlags.HDR)
|
||||
{
|
||||
//Color prev = m.colorValue;
|
||||
m.colorValue = (toLinear ? m.colorValue.linear : m.colorValue.gamma);
|
||||
colorCount++;
|
||||
//Debug.Log("prev: " + prev + ", current: " + m.colorValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (colorCount == 0)
|
||||
EditorUtility.DisplayDialog("Result", "Found no HDR Color properties in the selected material" + (matCount > 1 ? "s." : "."), "OK");
|
||||
else
|
||||
EditorUtility.DisplayDialog("Result", "Converted " + colorCount + " HDR Color propert"+ (colorCount > 1 ? "ies" : "y") + " in "+matCount+" material"+(matCount > 1 ? "s":"") + " to " + (toLinear ? "Linear" : "Gamma") + " color space.", "OK");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Utilities/Convert HDR Material Colors/To Linear", true, 995)]
|
||||
[MenuItem("VRChat SDK/Utilities/Convert HDR Material Colors/To Gamma", true, 996)]
|
||||
private static bool CheckSelection()
|
||||
{
|
||||
if (Selection.objects.Length == 0)
|
||||
return false;
|
||||
bool allMaterials = true;
|
||||
foreach (Object obj in Selection.objects)
|
||||
{
|
||||
if (obj.GetType() != typeof(Material))
|
||||
{
|
||||
allMaterials = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allMaterials;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3399613f583f3e46b2df27ae87dd5d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57304ced9b2de5f48a30b7b662d18c19
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
public class VRCSdk3Analysis
|
||||
{
|
||||
static Assembly GetAssemblyByName(string name)
|
||||
{
|
||||
return AppDomain.CurrentDomain.GetAssemblies().
|
||||
SingleOrDefault(assembly => assembly.GetName().Name == name);
|
||||
}
|
||||
|
||||
static List<Component> GetSceneComponentsFromAssembly( Assembly assembly )
|
||||
{
|
||||
if (assembly == null)
|
||||
return new List<Component>();
|
||||
|
||||
Type[] types = assembly.GetTypes();
|
||||
|
||||
List<Component> present = new List<Component>();
|
||||
foreach (var type in types )
|
||||
{
|
||||
if (!type.IsSubclassOf(typeof(MonoBehaviour)))
|
||||
continue;
|
||||
|
||||
var monos = VRC.Tools.FindSceneObjectsOfTypeAll(type);
|
||||
present.AddRange(monos);
|
||||
}
|
||||
return present;
|
||||
}
|
||||
|
||||
public enum SdkVersion
|
||||
{
|
||||
VRCSDK2,
|
||||
VRCSDK3
|
||||
};
|
||||
|
||||
public static List<Component> GetSDKInScene(SdkVersion version)
|
||||
{
|
||||
var assembly = GetAssemblyByName( version.ToString() );
|
||||
return GetSceneComponentsFromAssembly(assembly);
|
||||
}
|
||||
|
||||
public static bool IsSdkDllActive(SdkVersion version)
|
||||
{
|
||||
string assembly = version.ToString();
|
||||
PluginImporter importer = AssetImporter.GetAtPath("Assets/VRCSDK/Plugins/" + assembly + ".dll") as PluginImporter;
|
||||
if (importer == false)
|
||||
{
|
||||
//Handle Avatar Dll Split
|
||||
importer = AssetImporter.GetAtPath("Assets/VRCSDK/Plugins/" + assembly + "A.dll") as PluginImporter;
|
||||
if (importer == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return importer.GetCompatibleWithAnyPlatform();
|
||||
}
|
||||
|
||||
//public static void SetSdkVersionActive(SdkVersion version)
|
||||
//{
|
||||
// AssetDatabase.StartAssetEditing();
|
||||
|
||||
// PluginImporter importer = AssetImporter.GetAtPath("Assets/VRCSDK/Plugins/" + version + ".dll") as PluginImporter;
|
||||
// if (importer == null)
|
||||
// return;
|
||||
|
||||
// SetSDKDefine(version);
|
||||
|
||||
// var other = SdkVersion.VRCSDK2;
|
||||
// if (version == SdkVersion.VRCSDK2)
|
||||
// other = SdkVersion.VRCSDK3;
|
||||
|
||||
// SetSDKAssembly(other, false);
|
||||
// SetSDKAssembly(version, true);
|
||||
|
||||
// AssetDatabase.StopAssetEditing();
|
||||
//}
|
||||
|
||||
//static void SetSDKAssembly( SdkVersion version, bool active )
|
||||
//{
|
||||
// string assembly = version.ToString();
|
||||
// PluginImporter importer = AssetImporter.GetAtPath("Assets/VRCSDK/Plugins/" + assembly + ".dll") as PluginImporter;
|
||||
// if (importer)
|
||||
// {
|
||||
// importer.SetCompatibleWithAnyPlatform(active);
|
||||
// importer.SetCompatibleWithEditor(active);
|
||||
// importer.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, active);
|
||||
// importer.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, active);
|
||||
// importer.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, active);
|
||||
// importer.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, active);
|
||||
// importer.SetCompatibleWithPlatform(BuildTarget.Android, active);
|
||||
// importer.SaveAndReimport();
|
||||
// }
|
||||
//}
|
||||
|
||||
//static void SetSDKDefine( SdkVersion version )
|
||||
//{
|
||||
// string defineString = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone);
|
||||
// var defs = defineString.Split(';');
|
||||
// string finalDefs = null;
|
||||
// foreach( var s in defs )
|
||||
// {
|
||||
// if (s != "VRC_SDK_VRCSDK2" && s != "VRC_SDK_VRCSDK3")
|
||||
// {
|
||||
// if (finalDefs == null)
|
||||
// finalDefs = s;
|
||||
// else
|
||||
// finalDefs += ";" + s;
|
||||
// }
|
||||
// }
|
||||
// if (version == SdkVersion.VRCSDK2)
|
||||
// finalDefs += ";VRC_SDK_VRCSDK2";
|
||||
// else if (version == SdkVersion.VRCSDK3)
|
||||
// finalDefs += ";VRC_SDK_VRCSDK3";
|
||||
// PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, finalDefs);
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93710d221addc0243ba90dd20369844b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
public class SDKUpdater : MonoBehaviour
|
||||
{
|
||||
static string GetCurrentVersion()
|
||||
{
|
||||
string currentVersion = "";
|
||||
string versionTextPath = Application.dataPath + "/VRCSDK/version.txt";
|
||||
if(System.IO.File.Exists(versionTextPath))
|
||||
{
|
||||
string[] versionFileLines = System.IO.File.ReadAllLines(versionTextPath);
|
||||
if(versionFileLines.Length > 0)
|
||||
currentVersion = versionFileLines[0];
|
||||
}
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
[MenuItem("VRChat SDK/Utilities/Check For Updates")]
|
||||
static void CheckForUpdatesWithProgressBar()
|
||||
{
|
||||
CheckForUpdates(false);
|
||||
}
|
||||
|
||||
public static void CheckForUpdates(bool isSilent = true)
|
||||
{
|
||||
Debug.Log("Checking for VRChat SDK updates...");
|
||||
if(!isSilent)
|
||||
EditorUtility.DisplayProgressBar("SDK Updater", "Checking for updates...", 1f);
|
||||
|
||||
VRC.Core.ConfigManager.RemoteConfig.Init(delegate() {
|
||||
string currentSdkVersion = GetCurrentVersion();
|
||||
string sdkVersion = VRC.Core.ConfigManager.RemoteConfig.GetString("devSdkVersion");
|
||||
string sdkUrl = VRC.Core.ConfigManager.RemoteConfig.GetString("devSdkUrl");
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
if(sdkVersion == currentSdkVersion)
|
||||
{
|
||||
ShowDownloadUpdatePopup(false, currentSdkVersion, sdkUrl, isSilent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowDownloadUpdatePopup(true, sdkVersion, sdkUrl, isSilent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void ShowDownloadUpdatePopup(bool updateAvailable, string latestVersion, string sdkUrl, bool isSilent)
|
||||
{
|
||||
if(!updateAvailable)
|
||||
{
|
||||
if(!isSilent)
|
||||
EditorUtility.DisplayDialog("VRChat SDK Updater", "SDK is up to date (version " + latestVersion + ")", "Okay");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(EditorUtility.DisplayDialog("VRChat SDK Updater", "An update is available (version " + latestVersion + ")", "Download", "Cancel"))
|
||||
{
|
||||
DownloadUpdate(sdkUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DownloadUpdate(string sdkUrl)
|
||||
{
|
||||
Application.OpenURL(sdkUrl);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b8bb626428d0f341b9ed6a68cb5c9cc
|
||||
timeCreated: 1473273663
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,383 @@
|
||||
// Original ShaderKeywordsUtility by ScruffyRules#0879
|
||||
// Thank you to Xiexe and all that tested!
|
||||
// Licensed under the MIT License (see https://vrchat.com/legal/attribution)
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class ShaderKeywordsUtility : EditorWindow
|
||||
{
|
||||
private static Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, Dictionary<Material, bool>> avatars = new Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, Dictionary<Material, bool>>();
|
||||
private Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, bool> avatarsOpened = new Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, bool>();
|
||||
private Vector2 scrollPos;
|
||||
private static GUIStyle titleGuiStyle;
|
||||
public static HashSet<string> keywordBlacklist = new HashSet<string>(new string[]
|
||||
{
|
||||
// Unity Keywords, these don't matter at all. (They should be loaded)
|
||||
// All Keywords that are in Standard Unity Shaders
|
||||
"_ALPHABLEND_ON",
|
||||
"_ALPHAMODULATE_ON",
|
||||
"_ALPHAPREMULTIPLY_ON",
|
||||
"_ALPHATEST_ON",
|
||||
"_COLORADDSUBDIFF_ON",
|
||||
"_COLORCOLOR_ON",
|
||||
"_COLOROVERLAY_ON",
|
||||
"_DETAIL_MULX2",
|
||||
"_EMISSION",
|
||||
"_FADING_ON",
|
||||
"_GLOSSYREFLECTIONS_OFF",
|
||||
"_GLOSSYREFLECTIONS_OFF",
|
||||
"_MAPPING_6_FRAMES_LAYOUT",
|
||||
"_METALLICGLOSSMAP",
|
||||
"_NORMALMAP",
|
||||
"_PARALLAXMAP",
|
||||
"_REQUIRE_UV2",
|
||||
"_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A",
|
||||
"_SPECGLOSSMAP",
|
||||
"_SPECULARHIGHLIGHTS_OFF",
|
||||
"_SPECULARHIGHLIGHTS_OFF",
|
||||
"_SUNDISK_HIGH_QUALITY",
|
||||
"_SUNDISK_NONE",
|
||||
"_SUNDISK_SIMPLE",
|
||||
"_TERRAIN_NORMAL_MAP",
|
||||
"BILLBOARD_FACE_CAMERA_POS",
|
||||
"EFFECT_BUMP",
|
||||
"EFFECT_HUE_VARIATION",
|
||||
"ETC1_EXTERNAL_ALPHA",
|
||||
"GEOM_TYPE_BRANCH",
|
||||
"GEOM_TYPE_BRANCH_DETAIL",
|
||||
"GEOM_TYPE_FROND",
|
||||
"GEOM_TYPE_LEAF",
|
||||
"GEOM_TYPE_MESH",
|
||||
"LOD_FADE_CROSSFADE",
|
||||
"PIXELSNAP_ON",
|
||||
"SOFTPARTICLES_ON",
|
||||
"STEREO_INSTANCING_ON",
|
||||
"STEREO_MULTIVIEW_ON",
|
||||
"UNITY_HDR_ON",
|
||||
"UNITY_SINGLE_PASS_STEREO",
|
||||
"UNITY_UI_ALPHACLIP",
|
||||
"UNITY_UI_CLIP_RECT",
|
||||
// Post Processing Stack V1 and V2
|
||||
// This is mostly just safe keeping somewhere
|
||||
"FOG_OFF",
|
||||
"FOG_LINEAR",
|
||||
"FOG_EXP",
|
||||
"FOG_EXP2",
|
||||
"ANTI_FLICKER",
|
||||
"UNITY_COLORSPACE_GAMMA",
|
||||
"SOURCE_GBUFFER",
|
||||
"AUTO_KEY_VALUE",
|
||||
"GRAIN",
|
||||
"DITHERING",
|
||||
"TONEMAPPING_NEUTRAL",
|
||||
"TONEMAPPING_FILMIC",
|
||||
"CHROMATIC_ABERRATION",
|
||||
"DEPTH_OF_FIELD",
|
||||
"DEPTH_OF_FIELD_COC_VIEW",
|
||||
"BLOOM",
|
||||
"BLOOM_LENS_DIRT",
|
||||
"COLOR_GRADING",
|
||||
"COLOR_GRADING_LOG_VIEW",
|
||||
"USER_LUT",
|
||||
"VIGNETTE_CLASSIC",
|
||||
"VIGNETTE_MASKED",
|
||||
"FXAA",
|
||||
"FXAA_LOW",
|
||||
"FXAA_KEEP_ALPHA",
|
||||
"STEREO_INSTANCING_ENABLED",
|
||||
"STEREO_DOUBLEWIDE_TARGET",
|
||||
"TONEMAPPING_ACES",
|
||||
"TONEMAPPING_CUSTOM",
|
||||
"APPLY_FORWARD_FOG",
|
||||
"DISTORT",
|
||||
"CHROMATIC_ABERRATION_LOW",
|
||||
"BLOOM_LOW",
|
||||
"VIGNETTE",
|
||||
"FINALPASS",
|
||||
"COLOR_GRADING_HDR_3D",
|
||||
"COLOR_GRADING_HDR",
|
||||
"AUTO_EXPOSURE"
|
||||
});
|
||||
|
||||
const string keywordDescription = "Unity has a global limit of 256 keywords. A lot (~60) are used internally by Unity.\n\nAny new keyword you encounter goes onto a global list, and will stay until you restart the client.\n\nKeywords are used to create compile time branches and remove code, to optimize a shader, however, because of the 256 keyword limit, using them in VRChat can cause other shaders which use keywords to break, as once you hit the limit, any new keyword will get ignored.\n\nIt's best in the confines of VRChat to stay away from using custom keywords if possible, as not to cause issues with (your) shaders breaking.\n\nFor the full list of internal keywords, see 'ShaderKeywordsUtility.cs'";
|
||||
|
||||
private static bool avatarsDirty = true;
|
||||
private int loadedScenes = 0;
|
||||
|
||||
[MenuItem("VRChat SDK/Utilities/Avatar Shader Keywords Utility", false, 990)]
|
||||
static void Init()
|
||||
{
|
||||
ShaderKeywordsUtility window = EditorWindow.GetWindow<ShaderKeywordsUtility>();
|
||||
window.titleContent = new GUIContent("Shader Keywords Utility");
|
||||
window.minSize = new Vector2(325, 410);
|
||||
window.Show();
|
||||
|
||||
titleGuiStyle = new GUIStyle
|
||||
{
|
||||
fontSize = 15,
|
||||
fontStyle = FontStyle.BoldAndItalic,
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
wordWrap = true
|
||||
};
|
||||
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
titleGuiStyle.normal.textColor = Color.white;
|
||||
else
|
||||
titleGuiStyle.normal.textColor = Color.black;
|
||||
}
|
||||
|
||||
public static List<VRC.SDKBase.VRC_AvatarDescriptor> getADescs()
|
||||
{
|
||||
List<GameObject> GOs = new List<GameObject>();
|
||||
for (int i = 0; i < UnityEditor.SceneManagement.EditorSceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = UnityEditor.SceneManagement.EditorSceneManager.GetSceneAt(i);
|
||||
if (scene.isLoaded)
|
||||
{
|
||||
GameObject[] GOs2 = scene.GetRootGameObjects();
|
||||
foreach (GameObject go in GOs2)
|
||||
{
|
||||
GOs.Add(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<VRC.SDKBase.VRC_AvatarDescriptor> descriptors = new List<VRC.SDKBase.VRC_AvatarDescriptor>();
|
||||
foreach (GameObject go in GOs)
|
||||
{
|
||||
var vrcdescs = go.GetComponentsInChildren<VRC.SDKBase.VRC_AvatarDescriptor>(true);
|
||||
foreach (VRC.SDKBase.VRC_AvatarDescriptor vrcdesc in vrcdescs)
|
||||
{
|
||||
descriptors.Add(vrcdesc);
|
||||
}
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
public static bool DetectCustomShaderKeywords(VRC.SDKBase.VRC_AvatarDescriptor ad)
|
||||
{
|
||||
foreach (Renderer renderer in ad.transform.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
foreach (Material mat in renderer.sharedMaterials)
|
||||
{
|
||||
if (mat != null)
|
||||
{
|
||||
foreach (string keyword in mat.shaderKeywords)
|
||||
{
|
||||
if (!keywordBlacklist.Contains(keyword))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("Shader Keywords Utility", titleGuiStyle);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(15);
|
||||
|
||||
bool showHelp = EditorPrefs.GetBool("VRCSDK_ShowShaderKeywordsHelp", true);
|
||||
if (showHelp)
|
||||
{
|
||||
GUILayout.Label(keywordDescription, EditorStyles.helpBox, GUILayout.ExpandWidth(true));
|
||||
GUILayout.Space(15);
|
||||
}
|
||||
|
||||
int _loadedScenes = 0;
|
||||
for (int i = 0; i < UnityEditor.SceneManagement.EditorSceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = UnityEditor.SceneManagement.EditorSceneManager.GetSceneAt(i);
|
||||
if (scene.isLoaded)
|
||||
_loadedScenes += 1;
|
||||
}
|
||||
if (_loadedScenes != loadedScenes)
|
||||
{
|
||||
// Debug.Log("Loaded Scenes changed");
|
||||
loadedScenes = _loadedScenes;
|
||||
avatarsDirty = true;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Refresh Avatars", GUILayout.ExpandWidth(false)))
|
||||
avatarsDirty = true;
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button((showHelp ? "Hide" : "Show") + " Info about Keywords"))
|
||||
{
|
||||
showHelp = !showHelp;
|
||||
EditorPrefs.SetBool("VRCSDK_ShowShaderKeywordsHelp", showHelp);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(5);
|
||||
|
||||
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, false);
|
||||
ListAvatars();
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
}
|
||||
|
||||
void ListAvatars()
|
||||
{
|
||||
|
||||
if (avatarsDirty)
|
||||
CacheAvatars();
|
||||
|
||||
Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, Dictionary<Material, bool>> avatarsE = new Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, Dictionary<Material, bool>>(avatars);
|
||||
foreach (VRC.SDKBase.VRC_AvatarDescriptor vrcAD in avatarsE.Keys)
|
||||
{
|
||||
List<string> keywords = new List<string>();
|
||||
foreach (Material mat in avatars[vrcAD].Keys)
|
||||
{
|
||||
foreach (string keyword in mat.shaderKeywords)
|
||||
{
|
||||
if (!keywords.Contains(keyword) && !keywordBlacklist.Contains(keyword))
|
||||
keywords.Add(keyword);
|
||||
}
|
||||
}
|
||||
if (keywords.Count == 0)
|
||||
{
|
||||
avatars.Remove(vrcAD);
|
||||
avatarsOpened.Remove(vrcAD);
|
||||
continue;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
bool avatarOpened = avatarsOpened[vrcAD];
|
||||
avatarOpened = EditorGUILayout.ToggleLeft("", avatarOpened, GUILayout.MaxWidth(15f));
|
||||
avatarsOpened[vrcAD] = avatarOpened;
|
||||
EditorGUILayout.ObjectField(vrcAD, typeof(VRC.SDKBase.VRC_AvatarDescriptor), true);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (avatarOpened)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(23.0879f);
|
||||
GUILayout.Label("Total Custom Keywords on Avatar: " + keywords.Count);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
Dictionary<Material, bool> materials = new Dictionary<Material, bool>(avatars[vrcAD]);
|
||||
foreach (KeyValuePair<Material, bool> matKeyVal in materials)
|
||||
{
|
||||
Material material = matKeyVal.Key;
|
||||
bool materialOpened = matKeyVal.Value;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(23.0879f);
|
||||
materialOpened = EditorGUILayout.ToggleLeft("", materialOpened, GUILayout.MaxWidth(15f));
|
||||
avatars[vrcAD][material] = materialOpened;
|
||||
EditorGUILayout.ObjectField(material, typeof(Material), false);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (materialOpened)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(23.0879f * 2f);
|
||||
if (GUILayout.Button("Delete ALL Keywords on this Material"))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete All Keywords on this Material", "Are you sure you want to delete all Shader Keywords on this material?\nSome shaders might use these!", "Yes", "No"))
|
||||
{
|
||||
foreach (string keyword in material.shaderKeywords)
|
||||
{
|
||||
if (!keywordBlacklist.Contains(keyword))
|
||||
material.DisableKeyword(keyword);
|
||||
}
|
||||
avatars[vrcAD].Remove(material);
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(23.0879f * 2f);
|
||||
GUILayout.Label("Keywords", EditorStyles.boldLabel);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
int keywordsCount = 0;
|
||||
foreach (string keyword in material.shaderKeywords)
|
||||
{
|
||||
if (!keywordBlacklist.Contains(keyword))
|
||||
{
|
||||
keywordsCount++;
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(23.0879f * 2f);
|
||||
GUILayout.Label(keyword);
|
||||
if (GUILayout.Button("Delete", GUILayout.ExpandWidth(false)))
|
||||
material.DisableKeyword(keyword);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
if (keywordsCount == 0)
|
||||
avatars[vrcAD].Remove(material);
|
||||
}
|
||||
}
|
||||
GUILayout.Space(2f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CacheAvatars()
|
||||
{
|
||||
|
||||
//Debug.Log("Caching avatars");
|
||||
avatars = new Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, Dictionary<Material, bool>>();
|
||||
|
||||
List<VRC.SDKBase.VRC_AvatarDescriptor> avatarDescriptors = getADescs();
|
||||
|
||||
foreach (VRC.SDKBase.VRC_AvatarDescriptor aD in avatarDescriptors)
|
||||
{
|
||||
if (!avatars.ContainsKey(aD))
|
||||
avatars.Add(aD, new Dictionary<Material, bool>());
|
||||
|
||||
if (!avatarsOpened.ContainsKey(aD))
|
||||
avatarsOpened.Add(aD, false);
|
||||
|
||||
foreach (Renderer renderer in aD.transform.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
foreach (Material mat in renderer.sharedMaterials)
|
||||
{
|
||||
if (mat != null)
|
||||
{
|
||||
if (!avatars[aD].ContainsKey(mat))
|
||||
{
|
||||
foreach (string keyword in mat.shaderKeywords)
|
||||
{
|
||||
if (!keywordBlacklist.Contains(keyword))
|
||||
{
|
||||
avatars[aD].Add(mat, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (avatars[aD].Count == 0)
|
||||
{
|
||||
avatars.Remove(aD);
|
||||
avatarsOpened.Remove(aD);
|
||||
}
|
||||
}
|
||||
// prevent leaking
|
||||
Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, bool> avatarsOpenedE = new Dictionary<VRC.SDKBase.VRC_AvatarDescriptor, bool>();
|
||||
foreach (VRC.SDKBase.VRC_AvatarDescriptor aO in avatarsOpenedE.Keys)
|
||||
{
|
||||
if (!avatarDescriptors.Contains(aO))
|
||||
avatarsOpened.Remove(aO);
|
||||
}
|
||||
avatarsDirty = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
Loaded 100 of 3297 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user