├── src ├── .gitignore ├── AssemblyInfo.cs ├── Gesture │ ├── IGesture.cs │ ├── ITouchProvider.cs │ └── CircleGesture.cs ├── GUI │ ├── GUIIToolbarWidget.cs │ ├── GUIIView.cs │ ├── GUIHelper.cs │ ├── GUIIcons.cs │ ├── GUIStyles.cs │ ├── GUITable.cs │ ├── GUIScrollView.cs │ └── GUIListView.cs ├── Util │ ├── L.cs │ ├── StringCache.cs │ ├── Toggle.cs │ └── Mouse.cs ├── Core │ ├── IBehaviourListener.cs │ ├── Config.cs │ ├── Settings.cs │ └── Installer.cs ├── Extension │ ├── Log │ │ ├── Log │ │ │ ├── ILogProvider.cs │ │ │ ├── LogSample.cs │ │ │ ├── LogWatch.cs │ │ │ ├── LogStash.cs │ │ │ ├── Log.cs │ │ │ ├── AbstractLog.cs │ │ │ ├── LogBroker.cs │ │ │ ├── LogMask.cs │ │ │ └── LogOrganizer.cs │ │ └── View │ │ │ ├── LogView.Stack.cs │ │ │ ├── LogView.Toolbar.cs │ │ │ ├── LogView.Keyboard.cs │ │ │ ├── LogView.cs │ │ │ ├── LogView.Styles.cs │ │ │ ├── LogView.Table.cs │ │ │ └── LogVIew.Icons.cs │ ├── FPS │ │ ├── FPSCounter.cs │ │ └── FPSToolbarWidget.cs │ ├── SystemInfo │ │ ├── SystemInfoView.cs │ │ ├── SystemInfoView.Icons.cs │ │ ├── SystemInfoView.Styles.cs │ │ ├── SystemInfoView.PageSelect.cs │ │ ├── SystemInfoView.Row.cs │ │ └── SystemInfoView.Pages.cs │ └── Scene │ │ ├── SceneView.cs │ │ └── SceneView.Icons.cs └── GUIDrawer │ ├── GUIDrawer.Keyboard.cs │ ├── GUIDrawer.Styles.cs │ ├── GUIDrawer.Toolbar.cs │ └── GUIDrawer.cs ├── example ├── Assets │ ├── UnitySettings │ ├── SampleListView.cs.meta │ ├── Main.unity.meta │ ├── Main.cs.meta │ ├── SampleListView.cs │ ├── UnitySettings.meta │ ├── Main.cs │ └── Main.unity ├── ProjectSettings │ ├── ProjectVersion.txt │ ├── ClusterInputManager.asset │ ├── NetworkManager.asset │ ├── EditorBuildSettings.asset │ ├── TimeManager.asset │ ├── AudioManager.asset │ ├── EditorSettings.asset │ ├── TagManager.asset │ ├── DynamicsManager.asset │ ├── UnityConnectSettings.asset │ ├── NavMeshAreas.asset │ ├── Physics2DSettings.asset │ ├── GraphicsSettings.asset │ ├── QualitySettings.asset │ ├── InputManager.asset │ └── ProjectSettings.asset ├── UnityPackageManager │ └── manifest.json └── .gitignore ├── tools └── icons │ ├── resize.sh │ ├── compress.sh │ ├── process.sh │ └── file_to_bytes.py ├── .gitignore ├── bin ├── UnitySettings.dll └── UnitySettings.dll.mdb ├── libs └── UnityEngine.dll ├── .vscode ├── tasks.json └── settings.json ├── Makefile ├── test ├── MainTest.cs ├── Lens.cs ├── ITest.cs ├── Assert.cs ├── Util │ └── StringCache.cs ├── L.cs ├── Extension │ └── Log │ │ ├── LogMask.cs │ │ └── LogStash.cs └── Gesture │ └── CircleGesture.cs ├── README.md ├── UnitySettings-Test.csproj └── UnitySettings.csproj /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.meta 2 | 3 | -------------------------------------------------------------------------------- /example/Assets/UnitySettings: -------------------------------------------------------------------------------- 1 | ../../src/ -------------------------------------------------------------------------------- /tools/icons/resize.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | sips -Z 64 $1 3 | -------------------------------------------------------------------------------- /tools/icons/compress.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | pngquant -v -f -nofs 4 $1 3 | -------------------------------------------------------------------------------- /example/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.3.0f3 2 | -------------------------------------------------------------------------------- /example/UnityPackageManager/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | Library 3 | Temp 4 | *.sln 5 | *.csproj 6 | *.apk 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | 3 | bin/* 4 | !bin/UnitySettings.dll 5 | !bin/UnitySettings.dll.mdb 6 | -------------------------------------------------------------------------------- /bin/UnitySettings.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devsisters/UnitySettings/HEAD/bin/UnitySettings.dll -------------------------------------------------------------------------------- /libs/UnityEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devsisters/UnitySettings/HEAD/libs/UnityEngine.dll -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "make", 3 | "isShellCommand": true, 4 | "args": ["build"] 5 | } -------------------------------------------------------------------------------- /bin/UnitySettings.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devsisters/UnitySettings/HEAD/bin/UnitySettings.dll.mdb -------------------------------------------------------------------------------- /src/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("UnitySettings-Test")] -------------------------------------------------------------------------------- /example/Assets/SampleListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ea94a115559c42619542fbe623437c25 3 | timeCreated: 1515388160 -------------------------------------------------------------------------------- /src/Gesture/IGesture.cs: -------------------------------------------------------------------------------- 1 | namespace Settings 2 | { 3 | internal interface IGesture 4 | { 5 | void SampleOrCancel(); 6 | bool CheckAndClear(); 7 | } 8 | } -------------------------------------------------------------------------------- /tools/icons/process.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | FILE=$1 3 | FILE_WITH_OUT_EXT=${FILE%%.*} 4 | ./resize.sh $FILE 5 | ./compress.sh $FILE 6 | ./file_to_bytes.py $FILE_WITH_OUT_EXT-or8.png 7 | -------------------------------------------------------------------------------- /example/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /src/GUI/GUIIToolbarWidget.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | public abstract class IToolbarWidget 6 | { 7 | public abstract void OnGUI(Rect area); 8 | } 9 | } -------------------------------------------------------------------------------- /example/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /example/Assets/Main.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc95ef1ca954f4e4eb01ae58efa977c8 3 | timeCreated: 1489822717 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "bin": true, 4 | "obj": true, 5 | "lib": true, 6 | "example": true, 7 | ".gitignore": true, 8 | "**/*.meta": true 9 | } 10 | } -------------------------------------------------------------------------------- /src/Util/L.cs: -------------------------------------------------------------------------------- 1 | namespace Settings 2 | { 3 | internal static class L 4 | { 5 | public static void SomethingWentWrong() 6 | { 7 | UnityEngine.Debug.LogError("SomethingWentWrong"); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /example/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Main.unity 10 | -------------------------------------------------------------------------------- /src/Core/IBehaviourListener.cs: -------------------------------------------------------------------------------- 1 | namespace Settings 2 | { 3 | public class IBehaviourListener 4 | { 5 | public virtual void OnEnable() { } 6 | public virtual void OnDisable() { } 7 | public virtual void Update(bool isShowingGUI) { } 8 | } 9 | } -------------------------------------------------------------------------------- /example/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /example/Assets/Main.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 373fabcdef2e242a2ab9a221c14e17b9 3 | timeCreated: 1489822719 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | msbuild UnitySettings.csproj /verbosity:minimal /p:Configuration=Release 3 | 4 | unit: 5 | msbuild UnitySettings-Test.csproj /verbosity:minimal 6 | mono --debug bin/test/UnitySettings-Test.exe 7 | 8 | copy_unity_dll: 9 | cp /Applications/Unity/Unity.app/Contents/Managed/UnityEngine.dll libs/UnityEngine.dll 10 | 11 | all: build unit 12 | -------------------------------------------------------------------------------- /tools/icons/file_to_bytes.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python3 2 | import sys 3 | 4 | if __name__ == '__main__': 5 | filename = sys.argv[1] 6 | text = '' 7 | i = 0 8 | with open(filename, 'rb') as f: 9 | for b in f.read(): 10 | text += str(b) + ',' 11 | i += 1 12 | if i % 16 == 0: text += '\n' 13 | print(text) 14 | -------------------------------------------------------------------------------- /test/MainTest.cs: -------------------------------------------------------------------------------- 1 | namespace Test 2 | { 3 | public static class MainTest 4 | { 5 | public static void Main(string[] args) 6 | { 7 | new Util.CircleGesture().Test(); 8 | new Util.StringCache().Test(); 9 | new Extension.Log.MaskTest().Test(); 10 | new Extension.Log.StashTest().Test(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_DisableAudio: 0 16 | m_VirtualizeEffects: 1 17 | -------------------------------------------------------------------------------- /test/Lens.cs: -------------------------------------------------------------------------------- 1 | namespace Test 2 | { 3 | public class Lens 4 | { 5 | public delegate Value FromCallback(Obj obj); 6 | public delegate Obj ToCallback(Value value, Obj obj); 7 | 8 | public Lens(FromCallback from, ToCallback to) 9 | { 10 | From = from; 11 | To = to; 12 | } 13 | 14 | public readonly FromCallback From; 15 | public readonly ToCallback To; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/ITest.cs: -------------------------------------------------------------------------------- 1 | namespace Test 2 | { 3 | public abstract class ITest 4 | { 5 | private readonly string _name; 6 | 7 | public ITest(string name) 8 | { 9 | _name = name; 10 | } 11 | 12 | public void Test() 13 | { 14 | L.I("[" + _name + "] starts..."); 15 | TestImpl(); 16 | L.I("[" + _name + "] done"); 17 | } 18 | 19 | protected abstract void TestImpl(); 20 | } 21 | } -------------------------------------------------------------------------------- /example/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_DefaultBehaviorMode: 1 10 | m_SpritePackerMode: 2 11 | m_SpritePackerPaddingPower: 1 12 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 13 | m_ProjectGenerationRootNamespace: 14 | m_UserGeneratedProjectSuffix: 15 | -------------------------------------------------------------------------------- /src/GUI/GUIIView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | public abstract class IView 6 | { 7 | public readonly string Title; 8 | public readonly GUIContent ToolbarIcon; 9 | 10 | public IView(string title, GUIContent toolbarIcon) 11 | { 12 | Title = title; 13 | ToolbarIcon = toolbarIcon; 14 | } 15 | 16 | public virtual void Update() { } 17 | public abstract void OnGUI(Rect area); 18 | } 19 | } -------------------------------------------------------------------------------- /example/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /example/Assets/SampleListView.cs: -------------------------------------------------------------------------------- 1 | using Settings.GUI; 2 | using UnityEngine; 3 | 4 | public class SampleListView : ListView 5 | { 6 | class ListViewDelegate : IListViewDelegate 7 | { 8 | public int Count => 11; 9 | 10 | public ListViewItem GetItem(int index) 11 | { 12 | var shouldHighlight = (index - 1) % 5 == 0; 13 | return new ListViewItem("List View Item: " + index, shouldHighlight); 14 | } 15 | 16 | public void OnSelect(int index) 17 | { 18 | Debug.Log("OnSelect: " + index); 19 | } 20 | } 21 | 22 | public SampleListView() 23 | : base("Sample List View", GUIContent.none, 80, new ListViewDelegate()) 24 | { 25 | } 26 | } -------------------------------------------------------------------------------- /src/Extension/Log/Log/ILogProvider.cs: -------------------------------------------------------------------------------- 1 | using LogCallback = UnityEngine.Application.LogCallback; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | public interface IProvider 6 | { 7 | void RegisterThreaded(LogCallback listener); 8 | void UnregisterThreaded(LogCallback listener); 9 | } 10 | 11 | internal class Provider : IProvider 12 | { 13 | public void RegisterThreaded(LogCallback listener) 14 | { 15 | UnityEngine.Application.logMessageReceivedThreaded += listener; 16 | } 17 | 18 | public void UnregisterThreaded(LogCallback listener) 19 | { 20 | UnityEngine.Application.logMessageReceivedThreaded -= listener; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/Assets/UnitySettings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2817ef822702747799231976e5809123 3 | timeCreated: 1489822705 4 | licenseType: Pro 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | isPreloaded: 0 11 | isOverridable: 0 12 | platformData: 13 | - first: 14 | Any: 15 | second: 16 | enabled: 1 17 | settings: {} 18 | - first: 19 | Editor: Editor 20 | second: 21 | enabled: 0 22 | settings: 23 | DefaultValueInitialized: true 24 | - first: 25 | Windows Store Apps: WindowsStoreApps 26 | second: 27 | enabled: 0 28 | settings: 29 | CPU: AnyCPU 30 | userData: 31 | assetBundleName: 32 | assetBundleVariant: 33 | -------------------------------------------------------------------------------- /example/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_EnablePCM: 1 18 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 19 | -------------------------------------------------------------------------------- /example/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | CrashReportingSettings: 11 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 12 | m_Enabled: 0 13 | m_CaptureEditorExceptions: 1 14 | UnityPurchasingSettings: 15 | m_Enabled: 0 16 | m_TestMode: 0 17 | UnityAnalyticsSettings: 18 | m_Enabled: 0 19 | m_InitializeOnStartup: 1 20 | m_TestMode: 0 21 | m_TestEventUrl: 22 | m_TestConfigUrl: 23 | UnityAdsSettings: 24 | m_Enabled: 0 25 | m_InitializeOnStartup: 1 26 | m_TestMode: 0 27 | m_EnabledPlatforms: 4294967295 28 | m_IosGameId: 29 | m_AndroidGameId: 30 | -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogSample.cs: -------------------------------------------------------------------------------- 1 | namespace Settings.Extension.Log 2 | { 3 | internal struct Sample 4 | { 5 | public readonly float Time; 6 | public readonly string Scene; 7 | public string TimeToDisplay { get { return Time.ToString("0.000"); } } 8 | 9 | public Sample(float time, string scene) 10 | { 11 | Time = time; 12 | Scene = scene; 13 | } 14 | } 15 | 16 | internal interface ISampler 17 | { 18 | Sample Sample(); 19 | } 20 | 21 | internal class Sampler : ISampler 22 | { 23 | public Sample Sample() 24 | { 25 | var time = UnityEngine.Time.realtimeSinceStartup; 26 | var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; 27 | return new Sample(time, scene); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/GUIDrawer/GUIDrawer.Keyboard.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using K = UnityEngine.KeyCode; 3 | 4 | namespace Settings.GUI 5 | { 6 | internal partial class Drawer 7 | { 8 | private static readonly KeyCode[] _alphaNumKeys = new[] { 9 | K.Alpha1, K.Alpha2, K.Alpha3, 10 | K.Alpha4, K.Alpha5, K.Alpha6, 11 | K.Alpha7, K.Alpha8, K.Alpha9, 12 | K.Alpha0, 13 | }; 14 | 15 | private static int GetAlphaNumKeyDown() 16 | { 17 | for (var i = 0; i != _alphaNumKeys.Length; ++i) 18 | if (Input.GetKeyDown(_alphaNumKeys[i])) 19 | return i; 20 | return -1; 21 | } 22 | 23 | private void UpdateKeyboard() 24 | { 25 | var i = GetAlphaNumKeyDown(); 26 | if (i == -1 || i >= _views.Count) return; 27 | _curView = _views[i]; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Core/Config.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Settings 5 | { 6 | public class Config 7 | { 8 | private const string _prefKey = "UnitySettings_Config"; 9 | 10 | private struct ViewConfig 11 | { 12 | public string View; 13 | public string Data; 14 | } 15 | 16 | public string StartView; 17 | private List _viewConfigs = new List(); 18 | 19 | public static Config LoadFromPrefs() 20 | { 21 | var json = PlayerPrefs.GetString(_prefKey); 22 | if (string.IsNullOrEmpty(json)) return new Config(); 23 | return JsonUtility.FromJson(json); 24 | } 25 | 26 | public void SaveToPrefs() 27 | { 28 | var json = JsonUtility.ToJson(this); 29 | PlayerPrefs.SetString(_prefKey, json); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/Assets/Main.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class Main : MonoBehaviour 4 | { 5 | void Start() 6 | { 7 | Settings.Installer.Install(); 8 | Settings.Installer.Instance.AddView(new SampleListView()); 9 | } 10 | 11 | void OnEnable() 12 | { 13 | StartCoroutine(CoroutineLog()); 14 | } 15 | 16 | void LogSame() 17 | { 18 | for (var i = 0; i != 40; ++i) 19 | Debug.Log("some message some message some message"); 20 | } 21 | 22 | void Log() 23 | { 24 | for (var i = 0; i != 40; ++i) 25 | Debug.Log(i + "some message some message some message"); 26 | } 27 | 28 | private System.Collections.IEnumerator CoroutineLog() 29 | { 30 | while (true) 31 | { 32 | yield return new WaitForSeconds(1); 33 | Debug.Log(Time.realtimeSinceStartup.ToString("0.000") + " coroutine log"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Util/StringCache.cs: -------------------------------------------------------------------------------- 1 | using Cache = System.Collections.Generic.Dictionary; 2 | 3 | namespace Settings.Util 4 | { 5 | internal class StringCache 6 | { 7 | private readonly Cache _cache = new Cache(128); 8 | 9 | public string Cache(string queryStr) 10 | { 11 | if (queryStr == null) 12 | { 13 | L.SomethingWentWrong(); 14 | return string.Empty; 15 | } 16 | 17 | if (queryStr.Length == 0) 18 | return string.Empty; 19 | 20 | var hash = queryStr.GetHashCode(); 21 | string cachedStr; 22 | if (_cache.TryGetValue(hash, out cachedStr)) 23 | return cachedStr; 24 | 25 | _cache.Add(hash, queryStr); 26 | return queryStr; 27 | } 28 | 29 | public void Clear() 30 | { 31 | _cache.Clear(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Util/Toggle.cs: -------------------------------------------------------------------------------- 1 | namespace Settings 2 | { 3 | internal struct Toggle 4 | { 5 | private bool _isOn; 6 | 7 | public bool On() 8 | { 9 | if (_isOn) return false; 10 | _isOn = true; 11 | return true; 12 | } 13 | 14 | public bool OnWithCheck() 15 | { 16 | var ret = On(); 17 | if (!ret) L.SomethingWentWrong(); 18 | return ret; 19 | } 20 | 21 | public bool Off() 22 | { 23 | if (!_isOn) return false; 24 | _isOn = false; 25 | return true; 26 | } 27 | 28 | public bool OffWithCheck() 29 | { 30 | var ret = Off(); 31 | if (!ret) L.SomethingWentWrong(); 32 | return ret; 33 | } 34 | 35 | public static implicit operator bool(Toggle thiz) 36 | { 37 | return thiz._isOn; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogWatch.cs: -------------------------------------------------------------------------------- 1 | namespace Settings.Extension.Log 2 | { 3 | internal class Watch : IBehaviourListener 4 | { 5 | public readonly Stash Stash; 6 | 7 | private readonly IProvider _provider; 8 | private readonly Broker _broker; 9 | 10 | public Watch(IProvider provider, ISampler sampler) 11 | { 12 | _provider = provider; 13 | Stash = new Stash(); 14 | _broker = new Broker(sampler); 15 | } 16 | 17 | public override void OnEnable() 18 | { 19 | _broker.Connect(_provider); 20 | } 21 | 22 | public override void OnDisable() 23 | { 24 | _broker.Disconnect(); 25 | } 26 | 27 | public override void Update(bool isShowingGUI) 28 | { 29 | _broker.Transfer(Stash); 30 | } 31 | 32 | private void Clear() 33 | { 34 | Stash.Clear(); 35 | _broker.Clear(); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/Extension/FPS/FPSCounter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Settings.Extension.FPS 6 | { 7 | internal class Counter : IBehaviourListener 8 | { 9 | private const float _interval = 1f; 10 | 11 | public int FPS { get; private set; } 12 | private int _lastFrameCount = 0; 13 | private float _nextTimeToSample = 0; 14 | 15 | public override void OnEnable() 16 | { 17 | FPS = Application.targetFrameRate; 18 | _lastFrameCount = Time.frameCount; 19 | _nextTimeToSample = Time.realtimeSinceStartup + _interval; 20 | } 21 | 22 | public override void Update(bool isShowingGUI) 23 | { 24 | if (Time.realtimeSinceStartup > _nextTimeToSample) 25 | { 26 | FPS = Time.frameCount - _lastFrameCount; 27 | _lastFrameCount = Time.frameCount; 28 | _nextTimeToSample += _interval; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Settings.Extension.SystemInfo 5 | { 6 | public partial class View : GUI.IView 7 | { 8 | private readonly GUI.ScrollView _scroll; 9 | private string _curPage; 10 | private readonly Dictionary> _pages; 11 | 12 | public View() 13 | : base("SystemInfo", Icons.Icon) 14 | { 15 | _scroll = new GUI.ScrollView(Vector2.zero, true, true); 16 | _pages = new Dictionary>(8); 17 | AddAllPages(); 18 | } 19 | 20 | public override void Update() 21 | { 22 | _scroll.Update(); 23 | UpdateKeyboardPages(); 24 | } 25 | 26 | public override void OnGUI(Rect area) 27 | { 28 | UnityEngine.GUI.Box(area, "", GUI.Styles.BG); 29 | _scroll.BeginLayout(area); 30 | OnGUIPageSelect(); 31 | OnGUICurPage(); 32 | _scroll.EndLayout(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /test/Assert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Test 4 | { 5 | internal static class Assert 6 | { 7 | public static void Equals(T value1, T value2) 8 | where T : IComparable 9 | { 10 | if (value1.CompareTo(value2) != 0) 11 | L.E(value1 + " is not same to " + value2); 12 | } 13 | 14 | public static void RefEquals(Object value1, Object value2) 15 | { 16 | if (!Object.ReferenceEquals(value1, value2)) 17 | L.E(value1 + " is not same to " + value2); 18 | } 19 | 20 | public static void RefNotEquals(Object value1, Object value2) 21 | { 22 | if (Object.ReferenceEquals(value1, value2)) 23 | L.E(value1 + " is same to " + value2); 24 | } 25 | 26 | public static void True(bool value) 27 | { 28 | if (!value) L.E(value + " is not true"); 29 | } 30 | 31 | public static void False(bool value) 32 | { 33 | if (value) L.E(value + " is not false"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/GUI/GUIHelper.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | public static class Helper 6 | { 7 | public static Color32 UintToColor(uint color) 8 | { 9 | var c = new Color32(); 10 | c.r = (byte)((color >> 24) & 0xFF); 11 | c.g = (byte)((color >> 16) & 0xFF); 12 | c.b = (byte)((color >> 8) & 0xFF); 13 | c.a = (byte)((color) & 0xFF); 14 | return c; 15 | } 16 | 17 | public static Texture2D Solid(Color color) 18 | { 19 | var tex = new Texture2D(1, 1); 20 | tex.SetPixel(0, 0, color); tex.Apply(); 21 | return tex; 22 | } 23 | 24 | public static Texture2D Solid(uint color) 25 | { 26 | return Solid(UintToColor(color)); 27 | } 28 | 29 | public static Texture2D ToTex(this byte[] thiz) 30 | { 31 | var ret = new Texture2D(2, 2); 32 | if (!ret.LoadImage(thiz, true)) 33 | L.SomethingWentWrong(); 34 | return ret; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/GUI/GUIIcons.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | public static class Icons 6 | { 7 | public static readonly GUIContent Close; 8 | 9 | private static GUIContent I(byte[] texData) { return new GUIContent(texData.ToTex()); } 10 | 11 | static Icons() 12 | { 13 | Close = I(new byte[] { 14 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 15 | 0,0,0,64,0,0,0,64,2,3,0,0,0,215,7,153, 16 | 77,0,0,0,12,80,76,84,69,0,0,0,22,0,0,202, 17 | 2,2,246,209,209,82,55,179,42,0,0,0,2,116,82,78, 18 | 83,5,194,126,142,154,225,0,0,0,109,73,68,65,84,120, 19 | 1,197,211,1,7,192,32,20,4,224,65,176,95,23,12,250, 20 | 127,193,193,254,95,240,214,65,66,238,88,99,135,241,62,166, 21 | 122,245,142,111,146,174,145,188,134,130,145,186,132,132,41,249, 22 | 29,148,25,234,175,112,7,139,104,10,26,63,18,2,8,5, 23 | 44,136,2,122,213,77,1,8,80,192,127,218,22,248,85,252, 24 | 78,253,105,125,199,124,215,253,205,237,191,143,115,134,188,130, 25 | 100,193,79,148,159,202,253,60,163,210,252,198,191,111,36,178, 26 | 0,0,0,0,73,69,78,68,174,66,96,130, }); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Gesture/ITouchProvider.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings 4 | { 5 | internal interface ITouchProvider 6 | { 7 | bool GetDown(out Vector2 result); 8 | } 9 | 10 | internal class TouchProvider : ITouchProvider 11 | { 12 | public bool GetDown(out Vector2 result) 13 | { 14 | result = Vector2.zero; 15 | if (Input.touchSupported) 16 | { 17 | if (Input.touches.Length != 1) return false; 18 | var touch = Input.touches[0]; 19 | var touchPhasee = touch.phase; 20 | if (touchPhasee == TouchPhase.Ended 21 | || touchPhasee == TouchPhase.Canceled) 22 | return false; 23 | result = touch.position; 24 | return true; 25 | } 26 | else 27 | { 28 | if (Input.GetMouseButtonUp(0)) return false; 29 | if (!Input.GetMouseButton(0)) return false; 30 | result = Input.mousePosition; 31 | return true; 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/GUIDrawer/GUIDrawer.Styles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | internal partial class Drawer 6 | { 7 | private class Styles 8 | { 9 | public static readonly GUIStyle ToolbarBG; 10 | public static readonly GUIStyle ToolbarButton; 11 | public static readonly GUIStyle ToolbarButtonOn; 12 | 13 | static Styles() 14 | { 15 | ToolbarBG = new GUIStyle(); 16 | ToolbarBG.normal.background = Helper.Solid(0x039be5f0); 17 | ToolbarButton = new GUIStyle(); 18 | ToolbarButton.margin = new RectOffset(2, 2, 2, 2); 19 | ToolbarButton.alignment = TextAnchor.MiddleCenter; 20 | ToolbarButton.normal.background = Helper.Solid(0x0288d1f0); 21 | ToolbarButton.hover.background = Helper.Solid(0xfdd83580); 22 | ToolbarButtonOn = new GUIStyle(ToolbarButton); 23 | ToolbarButtonOn.normal.background = Helper.Solid(0x0277bdf0); 24 | ToolbarButtonOn.hover.background = Helper.Solid(0xfbc02d80); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Extension/Scene/SceneView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Settings.GUI; 4 | using UnityEngine; 5 | using UnityEngine.SceneManagement; 6 | 7 | namespace Settings.Extension.Scene 8 | { 9 | internal partial class View : GUI.ListView 10 | { 11 | private class ListViewDelegate : GUI.IListViewDelegate 12 | { 13 | public int Count => SceneManager.sceneCountInBuildSettings; 14 | 15 | public ListViewItem GetItem(int index) 16 | { 17 | var scene = SceneManager.GetSceneByBuildIndex(index); 18 | var isCurrentScene = scene == SceneManager.GetActiveScene(); 19 | var path = SceneUtility.GetScenePathByBuildIndex(index); 20 | var name = System.IO.Path.GetFileNameWithoutExtension(path); 21 | return new ListViewItem(name, isCurrentScene); 22 | } 23 | 24 | public void OnSelect(int index) 25 | => SceneManager.LoadScene(index); 26 | } 27 | 28 | public View() 29 | : base("Scene", Icons.Icon, 80, new ListViewDelegate()) 30 | { 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /example/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | -------------------------------------------------------------------------------- /test/Util/StringCache.cs: -------------------------------------------------------------------------------- 1 | namespace Test.Util 2 | { 3 | public class StringCache : ITest 4 | { 5 | public StringCache() 6 | : base("StringCache") 7 | { } 8 | 9 | protected override void TestImpl() 10 | { 11 | var target = new Settings.Util.StringCache(); 12 | var orgStr = "some string"; 13 | var tmpStr1 = "some "; 14 | var tmpStr2 = "string"; 15 | var otherStr = tmpStr1 + tmpStr2; 16 | 17 | { 18 | Assert.Equals(orgStr, otherStr); 19 | Assert.RefNotEquals(orgStr, otherStr); 20 | } 21 | 22 | { 23 | var cacheStr = target.Cache(orgStr); 24 | Assert.RefEquals(orgStr, cacheStr); 25 | } 26 | 27 | { 28 | var cacheStr = target.Cache(otherStr); 29 | Assert.RefEquals(orgStr, cacheStr); 30 | } 31 | 32 | { 33 | var oldCache = target.Cache(orgStr); 34 | Assert.RefEquals(orgStr, oldCache); 35 | target.Clear(); 36 | var newCache = target.Cache(otherStr); 37 | Assert.Equals(oldCache, newCache); 38 | Assert.RefEquals(newCache, otherStr); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Extension/FPS/FPSToolbarWidget.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Extension.FPS 4 | { 5 | internal class ToolbarWidget : GUI.IToolbarWidget 6 | { 7 | private readonly Counter _counter; 8 | 9 | public ToolbarWidget(Counter counter) 10 | { 11 | _counter = counter; 12 | } 13 | 14 | private static int GetTargetFrameRate() 15 | { 16 | var target = Application.targetFrameRate; 17 | if (target != -1) return target; 18 | if (Application.isMobilePlatform) return 30; 19 | else if (Application.isEditor) return 60; 20 | else return 60; 21 | } 22 | 23 | private static Color ColorForFPS(int fps) 24 | { 25 | var target = GetTargetFrameRate(); 26 | if (fps < target / 2) return Color.red; 27 | else if (fps < ((target * 5) / 6f)) return Color.yellow; 28 | else return Color.green; 29 | } 30 | 31 | public override void OnGUI(Rect area) 32 | { 33 | var fps = _counter.FPS; 34 | var style = new GUIStyle(); 35 | style.alignment = TextAnchor.MiddleCenter; 36 | style.fontSize = (int)area.height - 30; 37 | style.normal.textColor = ColorForFPS(fps); 38 | UnityEngine.GUI.Label(area, fps.ToString(), style); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.Icons.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Settings.GUI; 3 | 4 | namespace Settings.Extension.SystemInfo 5 | { 6 | public partial class View 7 | { 8 | public static class Icons 9 | { 10 | public static readonly GUIContent Icon; 11 | 12 | private static GUIContent I(byte[] texData) { return new GUIContent(texData.ToTex()); } 13 | 14 | static Icons() 15 | { 16 | Icon = I(new byte[] { 17 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 18 | 0,0,0,64,0,0,0,52,2,3,0,0,0,71,180,214, 19 | 154,0,0,0,12,80,76,84,69,0,0,1,0,0,0,0, 20 | 1,18,4,21,164,252,92,195,53,0,0,0,3,116,82,78, 21 | 83,15,115,223,227,84,102,147,0,0,0,149,73,68,65,84, 22 | 120,1,173,200,129,102,69,65,16,131,225,64,96,159,110,32, 23 | 48,79,119,96,33,208,247,59,112,186,163,85,197,236,94,220, 24 | 251,131,228,195,39,163,124,0,41,109,111,65,114,245,245,56, 25 | 212,67,254,220,231,241,76,245,80,167,114,48,117,132,123,2, 26 | 169,51,8,242,17,130,210,104,96,252,193,133,129,247,129,204, 27 | 87,144,110,128,255,65,217,129,127,193,11,192,45,120,85,48, 28 | 26,192,130,219,246,116,108,161,242,4,5,198,14,166,32,44, 29 | 217,64,186,14,3,96,42,59,128,192,16,174,90,138,22,38, 30 | 68,176,160,234,33,2,137,3,212,86,156,0,86,6,118,240, 31 | 13,21,102,54,16,34,102,129,165,0,0,0,0,73,69,78, 32 | 68,174,66,96,130, }); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogStash.cs: -------------------------------------------------------------------------------- 1 | using Logs = System.Collections.Generic.List; 2 | using ReadOnlyLogs = System.Collections.ObjectModel.ReadOnlyCollection; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal class Stash 7 | { 8 | private readonly Logs _logs; 9 | private readonly ReadOnlyLogs _logsReadOnly; 10 | private readonly Util.StringCache _strCache; 11 | 12 | public readonly Organizer Organizer; 13 | 14 | public Stash() 15 | { 16 | _logs = new Logs(256); 17 | _logsReadOnly = _logs.AsReadOnly(); 18 | _strCache = new Util.StringCache(); 19 | Organizer = new Organizer(this); 20 | } 21 | 22 | public void Clear() 23 | { 24 | _logs.Clear(); 25 | _strCache.Clear(); 26 | Organizer.Clear(); 27 | } 28 | 29 | public void Add(RawLog raw, Sample sample) 30 | { 31 | var msg = _strCache.Cache(raw.Message); 32 | var stacktrace = _strCache.Cache(raw.Stacktrace); 33 | var newLog = new Log(raw.Type, msg, stacktrace, sample); 34 | _logs.Add(newLog); 35 | Organizer.Internal_AddToCache(newLog); 36 | } 37 | 38 | public ReadOnlyLogs All() 39 | { 40 | return _logsReadOnly; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnitySettings 2 | Runtime debugging menu (like setting on Android) for Unity. 3 | 4 | ## About this plugin 5 | Every single Unity projects have *lots of* debugging purpose features. 6 | The sad thing is, these kind of codes are just for one time use, even if these are not just project-specific codes. 7 | So usally after use these codes, these are just discarded. 8 | For preventing invent-a-wheel again and again, we decided to collect all the general purpose debugging features into one single plugin. 9 | 10 | ## The Final Form of Plugin, We Hope 11 | * It will be similar to Android Settings menu. 12 | * You will use this plugin just by add a single DLL file. 13 | * You will open runtime-debugging menu by gesture, like draw circle. 14 | * You will simply add your own view by few API call. 15 | * Or you will plugin in your own code in github repository. 16 | 17 | ## Current Status 18 | * Device information 19 | * Build information 20 | * Log viewer 21 | * Scene changer 22 | 23 | ## What Features, For Example? 24 | We will ship plenty of general purpose runtime debugging features! 25 | * Extensible CLI parser/executer 26 | * LUA repl for UnityEngine.dll 27 | * Account information 28 | * Touch infomation, with visualization 29 | * Network monitering tool/simulator 30 | * Scene flow monitering tool 31 | * PlayerPrefs modifier/viewer 32 | * Sound controller 33 | 34 | ## Milestone 35 | * Before NDC: Preview alpha, Open this repository as public 36 | -------------------------------------------------------------------------------- /example/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_MinPenetrationForPenalty: 0.01 17 | m_BaumgarteScale: 0.2 18 | m_BaumgarteTimeOfImpactScale: 0.75 19 | m_TimeToSleep: 0.5 20 | m_LinearSleepTolerance: 0.01 21 | m_AngularSleepTolerance: 2 22 | m_QueriesHitTriggers: 1 23 | m_QueriesStartInColliders: 1 24 | m_ChangeStopsCallbacks: 0 25 | m_AlwaysShowColliders: 0 26 | m_ShowColliderSleep: 1 27 | m_ShowColliderContacts: 0 28 | m_ShowColliderAABB: 0 29 | m_ContactArrowScale: 0.2 30 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 31 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 32 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 33 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 34 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 35 | -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.Styles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Settings.GUI; 3 | 4 | namespace Settings.Extension.SystemInfo 5 | { 6 | public partial class View 7 | { 8 | private static class Styles 9 | { 10 | public static readonly GUIStyle PageBar; 11 | public static readonly GUIStyle PageFont = GUI.Styles.ButtonGray; 12 | public static readonly GUIStyle SelectedPageFont = GUI.Styles.ButtonGraySelected; 13 | public static readonly GUIStyle HeaderFont; 14 | public static readonly GUIStyle RowTitleFont; 15 | public static readonly GUIStyle RowFont; 16 | 17 | static Styles() 18 | { 19 | PageBar = new GUIStyle(); 20 | PageBar.normal.background = Helper.Solid(0xbdbdbdf0); 21 | 22 | HeaderFont = new GUIStyle(); 23 | HeaderFont.padding = new RectOffset(5, 5, 5, 5); 24 | HeaderFont.fontSize = 32; 25 | HeaderFont.fontStyle = FontStyle.BoldAndItalic; 26 | HeaderFont.normal.textColor = Color.black; 27 | 28 | RowFont = new GUIStyle(); 29 | RowFont.fontSize = 32; 30 | RowFont.padding = new RectOffset(5, 5, 5, 5); 31 | RowFont.normal.textColor = Color.black; 32 | 33 | RowTitleFont = new GUIStyle(RowFont); 34 | RowTitleFont.fontStyle = FontStyle.Bold; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Extension/Scene/SceneView.Icons.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Settings.GUI; 3 | 4 | namespace Settings.Extension.Scene 5 | { 6 | internal partial class View 7 | { 8 | private static class Icons 9 | { 10 | public static readonly GUIContent Icon; 11 | 12 | private static GUIContent I(byte[] texData) { return new GUIContent(texData.ToTex()); } 13 | 14 | static Icons() 15 | { 16 | Icon = I(new byte[] { 17 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 18 | 0,0,0,64,0,0,0,64,8,3,0,0,0,157,183,129, 19 | 236,0,0,0,12,80,76,84,69,0,0,0,255,255,255,46, 20 | 45,46,250,250,250,135,169,196,198,0,0,0,4,116,82,78, 21 | 83,0,2,253,250,76,109,54,6,0,0,0,215,73,68,65, 22 | 84,120,218,237,214,49,14,131,64,12,68,209,172,125,255,59, 23 | 39,221,47,70,214,200,131,18,161,8,119,20,255,137,13,203, 24 | 146,215,51,255,49,231,218,236,128,250,76,0,16,7,0,113, 25 | 6,16,51,2,248,58,7,42,7,232,117,50,160,3,160,168, 26 | 187,3,128,152,222,0,164,196,244,172,195,1,212,75,192,247, 27 | 6,144,94,129,54,128,237,185,5,128,77,239,129,114,64,43, 28 | 176,232,185,24,0,250,0,176,189,7,200,91,1,46,199,223, 29 | 160,166,81,160,5,240,61,51,108,164,90,0,231,43,64,95, 30 | 93,2,130,80,246,41,136,48,236,3,3,32,132,27,201,11, 31 | 30,64,48,128,46,1,33,58,15,188,224,1,21,210,35,13, 32 | 33,61,84,17,130,99,221,10,6,16,161,150,0,51,60,255, 33 | 95,126,222,245,21,15,128,252,47,14,99,122,15,116,231,0, 34 | 70,123,96,101,156,45,0,146,3,32,49,0,114,50,128,121, 35 | 128,59,2,111,125,28,21,227,56,21,91,243,0,0,0,0, 36 | 73,69,78,68,174,66,96,130, }); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /test/L.cs: -------------------------------------------------------------------------------- 1 | namespace Test 2 | { 3 | internal static class L 4 | { 5 | public enum Color 6 | { 7 | None, Reset, Red, 8 | } 9 | 10 | private static string AnsiForFg(Color c) 11 | { 12 | switch (c) 13 | { 14 | case Color.None: return ""; 15 | case Color.Reset: return "\x1b[0m"; 16 | case Color.Red: return "\x1b[31m"; 17 | default: return ""; 18 | } 19 | } 20 | 21 | private static void WriteToConsole(string message, bool newLine) 22 | { 23 | if (newLine) System.Console.WriteLine(message); 24 | else System.Console.Write(message); 25 | } 26 | 27 | public static void Print(string message, bool newLine = true, Color fgColor = Color.None) 28 | { 29 | WriteToConsole(AnsiForFg(fgColor), false); 30 | WriteToConsole(message, newLine); 31 | WriteToConsole(AnsiForFg(Color.Reset), false); 32 | } 33 | 34 | private static void PrintWithTag(string tag, string message, Color fgColor = Color.None) 35 | { 36 | Print(tag + ") " + message, fgColor: fgColor); 37 | } 38 | 39 | public static void I(string message) 40 | { 41 | PrintWithTag("I", message); 42 | } 43 | 44 | public static void E(string message) 45 | { 46 | PrintWithTag("E", message, fgColor: Color.Red); 47 | var stacktrace = new System.Diagnostics.StackTrace(1, true); 48 | Print(stacktrace.ToString()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/GUI/GUIStyles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | internal static class Styles 6 | { 7 | public static readonly GUIStyle BG; 8 | public static readonly GUIStyle ButtonGray; 9 | public static readonly GUIStyle ButtonLightGray; 10 | public static readonly GUIStyle ButtonGraySelected; 11 | 12 | static Styles() 13 | { 14 | BG = new GUIStyle(); 15 | BG.normal.background = Helper.Solid(0xffffffa0); 16 | 17 | ButtonGray = new GUIStyle(); 18 | ButtonGray.padding = new RectOffset(10, 10, 10, 10); 19 | ButtonGray.margin = new RectOffset(2, 2, 2, 2); 20 | ButtonGray.fontSize = 32; 21 | ButtonGray.normal.background = Helper.Solid(0x9e9e9ef0); 22 | ButtonGray.hover.background = Helper.Solid(0x696969f0); 23 | 24 | ButtonLightGray = new GUIStyle(); 25 | ButtonLightGray.padding = new RectOffset(10, 10, 10, 10); 26 | ButtonLightGray.margin = new RectOffset(2, 2, 2, 2); 27 | ButtonLightGray.fontSize = 32; 28 | ButtonLightGray.normal.background = Helper.Solid(0xa9a9a9f0); 29 | ButtonLightGray.hover.background = Helper.Solid(0x757575f0); 30 | 31 | ButtonGraySelected = new GUIStyle(ButtonGray); 32 | ButtonGraySelected.fontStyle = FontStyle.Bold; 33 | ButtonGraySelected.normal.background = Helper.Solid(0x616161f0); 34 | ButtonGraySelected.normal.textColor = Color.white; 35 | ButtonGraySelected.hover.background = Helper.Solid(0x424242f0); 36 | ButtonGraySelected.hover.textColor = Color.white; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/GUIDrawer/GUIDrawer.Toolbar.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | internal partial class Drawer 6 | { 7 | private static Rect _toolbarIconRect = new Rect(0, 0, _toolbarH, _toolbarH); 8 | 9 | private bool DrawToolbarToggle(GUIContent icon, bool value) 10 | { 11 | var style = value ? Styles.ToolbarButtonOn : Styles.ToolbarButton; 12 | var clicked = UnityEngine.GUI.Button(_toolbarIconRect, icon, style); 13 | if (clicked) value = !value; 14 | return value; 15 | } 16 | 17 | private void OnGUIToolbar(Rect area) 18 | { 19 | // draw views 20 | var viewArea = new Rect(area); viewArea.width -= _toolbarH; 21 | _toolbarIconRect = new Rect(0, 0, _toolbarH, _toolbarH); 22 | _toolbarTable.OnGUI(viewArea, _views.Count, OnGUIToolbarIcon); 23 | 24 | // draw close 25 | var closeRect = new Rect(area.xMax - _toolbarH, area.y, _toolbarH, area.height); 26 | if (UnityEngine.GUI.Button(closeRect, Icons.Close, Styles.ToolbarButton)) 27 | OnClose(); 28 | 29 | // draw widgets 30 | for (var i = _toolbarWidgets.Count - 1; i >= 0; --i) 31 | { 32 | var rect = closeRect; 33 | rect.x -= _toolbarH * (i + 1); 34 | _toolbarWidgets[i].OnGUI(rect); 35 | } 36 | } 37 | 38 | private void OnGUIToolbarIcon(int i) 39 | { 40 | var view = _views[i]; 41 | var icon = view.ToolbarIcon; 42 | if (DrawToolbarToggle(icon, view == _curView)) 43 | _curView = view; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Extension/Log/Log/Log.cs: -------------------------------------------------------------------------------- 1 | using LogType = UnityEngine.LogType; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | internal struct RawLog 6 | { 7 | public readonly LogType Type; 8 | public readonly string Message; 9 | public readonly string Stacktrace; 10 | private int _cachedHash; 11 | 12 | public RawLog(LogType type, string message, string stacktrace) 13 | { 14 | Type = type; 15 | Message = message; 16 | Stacktrace = stacktrace; 17 | _cachedHash = 0; 18 | } 19 | 20 | public override int GetHashCode() 21 | { 22 | if (_cachedHash != 0) 23 | return _cachedHash; 24 | 25 | unchecked 26 | { 27 | _cachedHash = (int)Type * 311 28 | + Message.GetHashCode() * 659 29 | + Stacktrace.GetHashCode() * 823; 30 | } 31 | 32 | return _cachedHash; 33 | } 34 | } 35 | 36 | internal struct Log 37 | { 38 | public readonly LogType Type; 39 | public readonly string Message; 40 | public readonly string Stacktrace; 41 | public readonly Sample Sample; 42 | 43 | public Log(LogType type, string message, string stacktrace, Sample sample) 44 | { 45 | Type = type; 46 | Message = message; 47 | Stacktrace = stacktrace; 48 | Sample = sample; 49 | } 50 | } 51 | 52 | internal struct LogAndCount 53 | { 54 | public readonly RawLog Log; 55 | public int Count { get; private set; } 56 | 57 | public LogAndCount(RawLog log) 58 | { 59 | Log = log; 60 | Count = 1; 61 | } 62 | 63 | public void Inc() { ++Count; } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /test/Extension/Log/LogMask.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Mask = Settings.Extension.Log.Mask; 3 | using Lens = Test.Lens; 4 | 5 | namespace Test.Extension.Log 6 | { 7 | public class MaskTest : ITest 8 | { 9 | public MaskTest() 10 | : base("LogMask") 11 | { } 12 | 13 | protected override void TestImpl() 14 | { 15 | var log = new Lens(t => t.Log, (v, t) => { t.Log = v; return t; }); 16 | var warning = new Lens(t => t.Warning, (v, t) => { t.Warning = v; return t; }); 17 | var error = new Lens(t => t.Error, (v, t) => { t.Error = v; return t; }); 18 | var assert = new Lens(t => t.Assert, (v, t) => { t.Assert = v; return t; }); 19 | var exception = new Lens(t => t.Exception, (v, t) => { t.Exception = v; return t; }); 20 | var all = new[] { log, warning, error, assert, exception }; 21 | 22 | var target = new Mask(); 23 | 24 | target.SetAllTrue(); 25 | Assert.True(all.All(l => l.From(target))); 26 | 27 | target.SetAllFalse(); 28 | Assert.False(all.Any(l => l.From(target))); 29 | 30 | all.ToList().ForEach(l => target = TestFlag(l, target)); 31 | Assert.True(all.All(l => l.From(target))); 32 | } 33 | 34 | private static Mask TestFlag(Lens flag, Mask target) 35 | { 36 | target = flag.To(false, target); 37 | Assert.False(flag.From(target)); 38 | target = flag.To(true, target); 39 | Assert.True(flag.From(target)); 40 | target = flag.To(false, target); 41 | Assert.False(flag.From(target)); 42 | target = flag.To(true, target); 43 | Assert.True(flag.From(target)); 44 | return target; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /UnitySettings-Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | 9 | {C0E5CC1F-AACD-4794-A66D-D63D3E0BA3B5} 10 | Settings.Test 11 | Exe 12 | Properties 13 | UnitySettings-Test 14 | v3.5 15 | 512 16 | Assets 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\test\ 23 | DEBUG 24 | prompt 25 | 4 26 | 27 | 28 | 29 | libs\UnityEngine.dll 30 | 31 | 32 | bin\UnitySettings.dll 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.PageSelect.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Settings.Extension.SystemInfo 5 | { 6 | public partial class View 7 | { 8 | private RowBuilder AddPage(string title) 9 | { 10 | var key = title; 11 | var rows = new List(32); 12 | if (_curPage == null) _curPage = key; 13 | _pages.Add(key, rows); 14 | return new RowBuilder(rows); 15 | } 16 | 17 | private void UpdateKeyboardPages() 18 | { 19 | var dir = 0; 20 | if (Input.GetKeyDown(KeyCode.LeftArrow)) dir = -1; 21 | if (Input.GetKeyDown(KeyCode.RightArrow)) dir = 1; 22 | if (dir == 0) return; 23 | var keys = new List(_pages.Keys); 24 | var curIndex = keys.FindIndex(x => x == _curPage); 25 | if (curIndex != -1) 26 | { 27 | curIndex = (curIndex + dir + keys.Count) % keys.Count; 28 | _curPage = keys[curIndex]; 29 | } 30 | } 31 | 32 | private void OnGUIPageSelect() 33 | { 34 | var height = GUILayout.Height(32); 35 | GUILayout.BeginHorizontal(Styles.PageBar, height); 36 | foreach (var kv in _pages) 37 | { 38 | var title = kv.Key; 39 | var isSelected = _curPage == title; 40 | var style = isSelected ? Styles.SelectedPageFont : Styles.PageFont; 41 | if (GUILayout.Button(title, style)) _curPage = title; 42 | } 43 | GUILayout.FlexibleSpace(); 44 | GUILayout.EndHorizontal(); 45 | } 46 | 47 | private void OnGUICurPage() 48 | { 49 | List page; 50 | if (_pages.TryGetValue(_curPage, out page)) 51 | page.ForEach(OnGUIRow); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/GUIDrawer/GUIDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using Views = System.Collections.Generic.List; 4 | 5 | namespace Settings.GUI 6 | { 7 | internal partial class Drawer 8 | { 9 | const int _toolbarH = 80; 10 | 11 | private readonly Views _views = new Views(8); 12 | private IView _curView; 13 | private readonly Table _toolbarTable; 14 | private readonly List _toolbarWidgets = new List(); 15 | 16 | public System.Action OnClose; 17 | 18 | public Drawer() 19 | { 20 | _toolbarTable = new GUI.Table( 21 | GUI.Table.Direction.Horizontal, 22 | _toolbarH, 0, 23 | Styles.ToolbarBG); 24 | } 25 | 26 | public void AddView(IView view) 27 | { 28 | _views.Add(view); 29 | if (_curView == null) 30 | _curView = view; 31 | } 32 | 33 | public void AddToolbarWidget(IToolbarWidget toolbarWidget) 34 | { 35 | _toolbarWidgets.Add(toolbarWidget); 36 | } 37 | 38 | public void Update() 39 | { 40 | UpdateKeyboard(); 41 | if (_curView != null) 42 | _curView.Update(); 43 | } 44 | 45 | public void OnGUI() 46 | { 47 | // layout 48 | var y = 0; 49 | var w = Screen.width; 50 | var h = Screen.height; 51 | 52 | var toolbarArea = new Rect(0, y, w, _toolbarH); 53 | y += _toolbarH; h -= _toolbarH; 54 | var viewArea = new Rect(0, y, w, h); 55 | 56 | // draw 57 | OnGUIToolbar(toolbarArea); 58 | if (_curView != null) 59 | _curView.OnGUI(viewArea); 60 | 61 | // touch block 62 | UnityEngine.GUI.Button(new Rect(0, 0, w, h), "", new GUIStyle()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Extension/Log/Log/AbstractLog.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using LogType = UnityEngine.LogType; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal struct AbstractLog 7 | { 8 | public LogType Type; 9 | public string Message; 10 | public string Stacktrace; 11 | public Sample? Sample; 12 | public int? Count; 13 | } 14 | 15 | internal class AbstractLogs 16 | { 17 | private readonly ReadOnlyCollection _logs; 18 | private readonly ReadOnlyCollection _collapsedLogs; 19 | 20 | public int Count 21 | { 22 | get 23 | { 24 | if (_logs != null) return _logs.Count; 25 | else return _collapsedLogs.Count; 26 | } 27 | } 28 | 29 | public AbstractLog this[int index] 30 | { 31 | get 32 | { 33 | if (_logs != null) 34 | { 35 | var log = _logs[index]; 36 | return new AbstractLog 37 | { 38 | Type = log.Type, 39 | Message = log.Message, 40 | Stacktrace = log.Stacktrace, 41 | Sample = log.Sample, 42 | }; 43 | } 44 | else 45 | { 46 | var clog = _collapsedLogs[index]; 47 | return new AbstractLog 48 | { 49 | Type = clog.Log.Type, 50 | Message = clog.Log.Message, 51 | Stacktrace = clog.Log.Stacktrace, 52 | Count = clog.Count, 53 | }; 54 | } 55 | } 56 | } 57 | 58 | public AbstractLogs(ReadOnlyCollection logs) { _logs = logs; } 59 | public AbstractLogs(ReadOnlyCollection logs) { _collapsedLogs = logs; } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /UnitySettings.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | 9 | {D2868622-A814-44FF-A5BE-1DA488EB660D} 10 | Library 11 | Properties 12 | UnitySettings 13 | v3.5 14 | 512 15 | Assets 16 | 17 | 18 | pdbonly 19 | true 20 | bin\ 21 | prompt 22 | 4 23 | 24 | 25 | 26 | libs\UnityEngine.dll 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogBroker.cs: -------------------------------------------------------------------------------- 1 | using Queue = System.Collections.Generic.List; 2 | using LogType = UnityEngine.LogType; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal class Broker 7 | { 8 | private bool _isConnected { get { return _provider != null; } } 9 | private IProvider _provider; 10 | private bool _isQueueEmpty = true; 11 | private readonly Queue _queue = new Queue(16); 12 | private readonly ISampler _sampler; 13 | 14 | public Broker(ISampler sampler) 15 | { 16 | _sampler = sampler; 17 | } 18 | 19 | public void Connect(IProvider provider) 20 | { 21 | if (_isConnected) 22 | { 23 | L.SomethingWentWrong(); 24 | return; 25 | } 26 | 27 | _provider = provider; 28 | _provider.RegisterThreaded(OnSubscribe); 29 | } 30 | 31 | public void Disconnect() 32 | { 33 | if (!_isConnected) 34 | { 35 | L.SomethingWentWrong(); 36 | return; 37 | } 38 | 39 | _provider.UnregisterThreaded(OnSubscribe); 40 | _provider = null; 41 | } 42 | 43 | private void OnSubscribe(string message, string stacktrace, LogType type) 44 | { 45 | var log = new RawLog(type, message, stacktrace); 46 | lock (_queue) 47 | { 48 | _isQueueEmpty = false; 49 | _queue.Add(log); 50 | } 51 | } 52 | 53 | public void Transfer(Stash stash) 54 | { 55 | if (_isQueueEmpty) return; 56 | var sample = _sampler.Sample(); 57 | lock (_queue) 58 | { 59 | foreach (var l in _queue) 60 | stash.Add(l, sample); 61 | _isQueueEmpty = true; 62 | _queue.Clear(); 63 | } 64 | } 65 | 66 | public void Clear() 67 | { 68 | lock (_queue) 69 | { 70 | _isQueueEmpty = true; 71 | _queue.Clear(); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.Stack.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | internal partial class View 6 | { 7 | private void DrawStackEmpty(Rect area) 8 | { 9 | UnityEngine.GUI.Box(area, "", Styles.StackBG); 10 | } 11 | 12 | private void DrawStack(Rect area, AbstractLog log) 13 | { 14 | DrawStackEmpty(area); 15 | 16 | // layout 17 | const int stackPadding = 12; 18 | const int stackSpace = 12; 19 | var x = area.x + stackPadding; var y = area.y; 20 | var w = area.width - 2 * stackPadding; var h = area.height; 21 | 22 | const int sampleH = 40; 23 | var stackH = h; 24 | var drawSample = log.Sample.HasValue; 25 | if (drawSample) stackH -= sampleH; 26 | 27 | // draw stack 28 | { 29 | if (_isSelectedLogDirty) 30 | _stackScroll.Scroll.Set(0, 0); 31 | _stackScroll.BeginLayout(new Rect(x, y, w, stackH)); 32 | GUILayout.Space(stackSpace); 33 | GUILayout.Label(log.Message, Styles.Font); 34 | GUILayout.Space(stackSpace); 35 | GUILayout.Label(log.Stacktrace, Styles.StackFont); 36 | GUILayout.Space(stackSpace); 37 | _stackScroll.EndLayout(); 38 | y += stackH; 39 | } 40 | 41 | // draw sample 42 | if (drawSample) 43 | { 44 | System.Action drawIconAndLabel = (icon, label) => 45 | { 46 | GUILayout.Box(icon, Styles.Icon, GUILayout.Width(_iconWidth), GUILayout.Height(sampleH)); 47 | GUILayout.Label(label, Styles.Font); 48 | GUILayout.Space(stackSpace); 49 | }; 50 | 51 | GUILayout.BeginArea(new Rect(x, y, w, sampleH)); 52 | GUILayout.BeginHorizontal(); 53 | var sample = log.Sample.Value; 54 | drawIconAndLabel(Icons.ShowTime, sample.TimeToDisplay); 55 | drawIconAndLabel(Icons.ShowScene, sample.Scene); 56 | GUILayout.FlexibleSpace(); 57 | GUILayout.EndHorizontal(); 58 | GUILayout.EndArea(); 59 | y += sampleH; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Gesture/CircleGesture.cs: -------------------------------------------------------------------------------- 1 | using Vector2 = UnityEngine.Vector2; 2 | 3 | namespace Settings 4 | { 5 | internal class CircleGesture : IGesture 6 | { 7 | private const int _minSqrDistToSample = 100; 8 | private const int _minTouchToCheck = 10; 9 | 10 | private readonly ITouchProvider _touchProvider; 11 | private readonly float _leastLength; 12 | 13 | public int TouchCount { get; private set; } 14 | private Vector2 _touchSum; 15 | private float _touchLength; 16 | 17 | private Vector2 _lastTouch; 18 | private Vector2 _lastDelta; 19 | 20 | public CircleGesture(ITouchProvider touchProvider, float leastLength) 21 | { 22 | _touchProvider = touchProvider; 23 | _leastLength = leastLength; 24 | } 25 | 26 | public void Clear() 27 | { 28 | TouchCount = 0; 29 | _touchSum = Vector2.zero; 30 | _touchLength = 0; 31 | } 32 | 33 | public void SampleOrCancel() 34 | { 35 | Vector2 touchPos; 36 | if (!_touchProvider.GetDown(out touchPos)) 37 | { 38 | Clear(); 39 | return; 40 | } 41 | 42 | if (TouchCount == 0) 43 | { 44 | ++TouchCount; 45 | _lastTouch = touchPos; 46 | return; 47 | } 48 | 49 | var delta = touchPos - _lastTouch; 50 | if (delta.sqrMagnitude < _minSqrDistToSample) 51 | return; 52 | 53 | if (TouchCount >= 2) 54 | { 55 | var dot = Vector2.Dot(delta, _lastDelta); 56 | if (dot < 0) 57 | { 58 | Clear(); 59 | return; 60 | } 61 | } 62 | 63 | ++TouchCount; 64 | _touchSum += delta; 65 | _touchLength += delta.magnitude; 66 | _lastTouch = touchPos; 67 | _lastDelta = delta; 68 | } 69 | 70 | public bool CheckAndClear() 71 | { 72 | if (TouchCount < _minTouchToCheck) 73 | return false; 74 | 75 | if (_touchLength > _leastLength && _touchSum.magnitude < _leastLength / 2) 76 | { 77 | Clear(); 78 | return true; 79 | } 80 | 81 | return false; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.Toolbar.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | internal partial class View 6 | { 7 | private static GUILayoutOption _toolbarTempWidth; 8 | private static GUILayoutOption _toolbarTempHeight; 9 | 10 | private bool DrawToolbarButton(GUIContent icon) 11 | { 12 | return GUILayout.Button(icon, Styles.ToolbarButton, _toolbarTempWidth, _toolbarTempHeight); 13 | } 14 | 15 | private bool DrawToolbarToggle(GUIContent icon, bool value) 16 | { 17 | var style = value ? Styles.ToolbarButtonOn : Styles.ToolbarButton; 18 | var clicked = GUILayout.Button(icon, style, _toolbarTempWidth, _toolbarTempHeight); 19 | if (clicked) value = !value; 20 | return value; 21 | } 22 | 23 | private void DrawToolbarToggle(GUIContent icon, ref bool value) 24 | { 25 | value = DrawToolbarToggle(icon, value); 26 | } 27 | 28 | private void OnGUIToolbar(Rect area) 29 | { 30 | const int padding = 2; 31 | _toolbarTempWidth = GUILayout.MinWidth(64); 32 | _toolbarTempHeight = GUILayout.Height(area.height - padding * 2); 33 | 34 | GUILayout.BeginArea(area, Styles.ToolbarBG); 35 | GUILayout.BeginHorizontal(); 36 | 37 | var c = _config; 38 | 39 | // draw actions 40 | if (DrawToolbarButton(Icons.Clear)) _isClickedClear.On(); 41 | DrawToolbarToggle(Icons.Collapse, ref c.Collapse); 42 | DrawToolbarToggle(Icons.KeepScrollToLast, ref c.KeepScrollToLast); 43 | 44 | // draw show sample 45 | if (!c.Collapse) 46 | { 47 | DrawToolbarToggle(Icons.ShowTime, ref c.ShowTime); 48 | DrawToolbarToggle(Icons.ShowScene, ref c.ShowScene); 49 | } 50 | 51 | GUILayout.FlexibleSpace(); 52 | 53 | // draw log mask 54 | c.Filter.Log = DrawToolbarToggle(Icons.Log, c.Filter.Log); 55 | c.Filter.Warning = DrawToolbarToggle(Icons.Warning, c.Filter.Warning); 56 | var showError = DrawToolbarToggle(Icons.Error, c.Filter.Error); 57 | c.Filter.Error = showError; 58 | c.Filter.Exception = showError; 59 | c.Filter.Assert = showError; 60 | 61 | GUILayout.EndHorizontal(); 62 | GUILayout.EndArea(); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /example/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 39 | m_PreloadedShaders: [] 40 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 41 | type: 0} 42 | m_TierSettings_Tier1: 43 | renderingPath: 1 44 | useCascadedShadowMaps: 0 45 | m_TierSettings_Tier2: 46 | renderingPath: 1 47 | useCascadedShadowMaps: 0 48 | m_TierSettings_Tier3: 49 | renderingPath: 1 50 | useCascadedShadowMaps: 0 51 | m_DefaultRenderingPath: 1 52 | m_DefaultMobileRenderingPath: 1 53 | m_TierSettings: [] 54 | m_LightmapStripping: 0 55 | m_FogStripping: 0 56 | m_LightmapKeepPlain: 1 57 | m_LightmapKeepDirCombined: 1 58 | m_LightmapKeepDirSeparate: 1 59 | m_LightmapKeepDynamicPlain: 1 60 | m_LightmapKeepDynamicDirCombined: 1 61 | m_LightmapKeepDynamicDirSeparate: 1 62 | m_FogKeepLinear: 1 63 | m_FogKeepExp: 1 64 | m_FogKeepExp2: 1 65 | -------------------------------------------------------------------------------- /src/Util/Mouse.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Util 4 | { 5 | internal static class Mouse 6 | { 7 | public static bool IsDown { get; private set; } 8 | 9 | private static bool _curPresent; 10 | private static Vector2 _curPos; 11 | private static bool _lastPresent; 12 | private static Vector2 _lastPos; 13 | 14 | public static void Refresh() 15 | { 16 | RefreshDown(); 17 | RefreshPos(); 18 | } 19 | 20 | private static void RefreshDown() 21 | { 22 | if (Input.touchSupported) 23 | { 24 | var touches = Input.touches; 25 | if (touches.Length != 1) 26 | { 27 | IsDown = false; 28 | return; 29 | } 30 | 31 | IsDown = touches[0].phase == TouchPhase.Began; 32 | } 33 | else 34 | { 35 | IsDown = Input.GetMouseButtonDown(0); 36 | } 37 | } 38 | 39 | private static void RefreshPos() 40 | { 41 | _lastPresent = _curPresent; 42 | _lastPos = _curPos; 43 | 44 | if (Input.touchSupported) 45 | { 46 | var touches = Input.touches; 47 | if (touches.Length == 1) 48 | { 49 | _curPresent = true; 50 | _curPos = touches[0].position; 51 | return; 52 | } 53 | } 54 | else 55 | { 56 | if (Input.GetMouseButton(0)) 57 | { 58 | _curPresent = true; 59 | _curPos = Input.mousePosition; 60 | return; 61 | } 62 | } 63 | 64 | _curPresent = false; 65 | _curPos = default(Vector2); 66 | } 67 | 68 | public static bool CurPos(out Vector2 result) 69 | { 70 | result = _curPos; 71 | return _curPresent; 72 | } 73 | 74 | public static bool Delta(out Vector2 result) 75 | { 76 | if (_curPresent && _lastPresent) 77 | { 78 | result = _curPos - _lastPos; 79 | return true; 80 | } 81 | else 82 | { 83 | result = Vector2.zero; 84 | return false; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.Row.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Settings.Extension.SystemInfo 6 | { 7 | public partial class View 8 | { 9 | private enum RowType 10 | { 11 | Header, Row, 12 | } 13 | 14 | private struct RowDef 15 | { 16 | public readonly RowType Type; 17 | public readonly string Col1; 18 | public readonly Func Col2; 19 | 20 | public RowDef(RowType type, string col1, string col2) 21 | { 22 | Type = type; 23 | Col1 = col1; 24 | Col2 = () => col2; 25 | } 26 | 27 | public RowDef(RowType type, string col1, Func col2) 28 | { 29 | Type = type; 30 | Col1 = col1; 31 | Col2 = col2; 32 | } 33 | } 34 | 35 | private struct RowBuilder 36 | { 37 | private readonly List _rows; 38 | public RowBuilder(List rows) { _rows = rows; } 39 | public void Header(string title) { _rows.Add(new RowDef(RowType.Header, title, default(string))); } 40 | public void Row(string title, object desc) { _rows.Add(new RowDef(RowType.Row, title, desc.ToString())); } 41 | public void Row(string title, Func desc) { _rows.Add(new RowDef(RowType.Row, title, () => desc().ToString())); } 42 | public void Row(string title, object desc, object descDetail) { _rows.Add(new RowDef(RowType.Row, title, DescAndDetail(desc, descDetail))); } 43 | public static string DescAndDetail(object desc, object descDetail) { return desc + " (" + descDetail + ")"; } 44 | } 45 | 46 | private static GUILayoutOption _minTitleWidth = GUILayout.MinWidth(240); 47 | 48 | private static void OnGUIRow(RowDef rowDef) 49 | { 50 | switch (rowDef.Type) 51 | { 52 | case RowType.Header: 53 | GUILayout.Label(rowDef.Col1, Styles.HeaderFont); 54 | break; 55 | case RowType.Row: 56 | GUILayout.BeginHorizontal(); 57 | GUILayout.Label(rowDef.Col1, Styles.RowTitleFont, _minTitleWidth); 58 | GUILayout.Label(rowDef.Col2(), Styles.RowFont); 59 | GUILayout.FlexibleSpace(); 60 | GUILayout.EndHorizontal(); 61 | break; 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /test/Extension/Log/LogStash.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using LogType = UnityEngine.LogType; 3 | using Stash = Settings.Extension.Log.Stash; 4 | using RawLog = Settings.Extension.Log.RawLog; 5 | using Sample = Settings.Extension.Log.Sample; 6 | using Mask = Settings.Extension.Log.Mask; 7 | 8 | namespace Test.Extension.Log 9 | { 10 | public class StashTest : ITest 11 | { 12 | public StashTest() 13 | : base("LogStash") 14 | { } 15 | 16 | protected override void TestImpl() 17 | { 18 | var message = "message"; 19 | var stacktrace = "stacktrace"; 20 | var time = 1234; 21 | var scene = "scene"; 22 | var sample = new Sample(time, scene); 23 | 24 | var target = new Stash(); 25 | var organizer = target.Organizer; 26 | 27 | var loop = 5; 28 | var logTypes = new[] { LogType.Log, LogType.Warning, LogType.Error, }; 29 | for (var i = 0; i != loop; ++i) 30 | { 31 | logTypes.ToList().ForEach(t => 32 | { 33 | var rawLog = new RawLog(t, message, stacktrace); 34 | target.Add(rawLog, sample); 35 | }); 36 | } 37 | 38 | var allCount = loop * logTypes.Length; 39 | Assert.Equals(target.All().Count, allCount); 40 | { 41 | var mask = new Mask(); 42 | mask.SetAllTrue(); 43 | var logs = organizer.Filter(mask); 44 | Assert.Equals(logs.Count, allCount); 45 | } 46 | 47 | { 48 | var mask = new Mask(); 49 | mask.SetAllFalse(); 50 | var logs = organizer.Filter(mask); 51 | Assert.Equals(logs.Count, 0); 52 | } 53 | 54 | { 55 | var mask = new Mask(); 56 | mask.Warning = true; 57 | mask.Assert = true; 58 | Assert.Equals(organizer.Filter(mask).Count, loop * 1); 59 | mask.Log = true; 60 | Assert.Equals(organizer.Filter(mask).Count, loop * 2); 61 | } 62 | 63 | { 64 | var mask = new Mask(); 65 | mask.Log = true; 66 | var logs = organizer.Filter(mask); 67 | Assert.Equals(logs.Count, loop); 68 | var firstLog = logs[0]; 69 | Assert.Equals(firstLog.Type, logTypes[0]); 70 | Assert.Equals(firstLog.Message, message); 71 | Assert.Equals(firstLog.Stacktrace, stacktrace); 72 | Assert.Equals(firstLog.Sample.Scene, scene); 73 | Assert.Equals(firstLog.Sample.Time, time); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /test/Gesture/CircleGesture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vector2 = UnityEngine.Vector2; 3 | 4 | namespace Test.Util 5 | { 6 | public class CircleGesture : ITest 7 | { 8 | public CircleGesture() 9 | : base("CircleGesture") 10 | { } 11 | 12 | public class TouchProvider : Settings.ITouchProvider 13 | { 14 | public Vector2 Next; 15 | 16 | public bool GetDown(out Vector2 result) 17 | { 18 | result = Next; 19 | return true; 20 | } 21 | } 22 | 23 | private static Vector2 V2(float x, float y) 24 | { 25 | return new Vector2(x, y); 26 | } 27 | 28 | protected override void TestImpl() 29 | { 30 | var touch = new TouchProvider(); 31 | var target = new Settings.CircleGesture(touch, 100); 32 | 33 | Action test_Sample = (x, y, cnt) => 34 | { 35 | touch.Next = V2(x, y); 36 | target.SampleOrCancel(); 37 | Assert.Equals(target.TouchCount, cnt); 38 | }; 39 | 40 | Action test_Check = shouldTrue => 41 | { 42 | var result = target.CheckAndClear(); 43 | Assert.Equals(result, shouldTrue); 44 | if (result) Assert.Equals(target.TouchCount, 0); 45 | }; 46 | 47 | test_Sample(0, 0, 1); 48 | test_Sample(0, 0, 1); 49 | test_Sample(0, 5, 1); 50 | test_Sample(0, 10, 2); 51 | test_Sample(0, -10, 0); 52 | 53 | test_Sample(0, 0, 1); 54 | test_Sample(0, 10, 2); 55 | test_Sample(10, 10, 3); 56 | test_Sample(20, 20, 4); 57 | test_Check(false); 58 | 59 | test_Sample(20, 20, 4); 60 | test_Sample(10, 20, 0); 61 | test_Check(false); 62 | 63 | var radius = 60; 64 | var slice = 20; 65 | var sliceRad = 2 * Math.PI / slice; 66 | for (var i = 0; i != slice; ++i) 67 | { 68 | var x = (float)(radius * Math.Sin(sliceRad * i)); 69 | var y = (float)(radius * Math.Cos(sliceRad * i)); 70 | test_Sample(x, y, i + 1); 71 | } 72 | test_Check(true); 73 | test_Check(false); 74 | 75 | var startIndex = 3; 76 | for (var i = startIndex; i != slice - 2; ++i) 77 | { 78 | var x = (float)(radius * Math.Sin(sliceRad * i)); 79 | var y = (float)(radius * Math.Cos(sliceRad * i)); 80 | test_Sample(x, y, i + 1 - startIndex); 81 | } 82 | test_Check(false); 83 | test_Check(false); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogMask.cs: -------------------------------------------------------------------------------- 1 | using LogType = UnityEngine.LogType; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | public struct Mask 6 | { 7 | private struct ByteMask 8 | { 9 | private byte _mask; 10 | public bool IsAll1 { get { return _mask == 0xff; } } 11 | public bool IsAll0 { get { return _mask == 0; } } 12 | 13 | public bool this[byte bit] 14 | { 15 | get { return (_mask & (1 << bit)) != 0; } 16 | set 17 | { 18 | if (value) _mask = (byte)(_mask | (1 << bit)); 19 | else _mask = (byte)(_mask & ~(1 << bit)); 20 | } 21 | } 22 | 23 | public byte Get() { return _mask; } 24 | public void All1() { _mask = 0xff; } 25 | public void All0() { _mask = 0; } 26 | } 27 | 28 | public static Mask AllTrue; 29 | 30 | static Mask() 31 | { 32 | AllTrue.SetAllTrue(); 33 | } 34 | 35 | private ByteMask _mask; 36 | 37 | public bool Log { get { return _mask[0]; } set { _mask[0] = value; } } 38 | public bool Warning { get { return _mask[1]; } set { _mask[1] = value; } } 39 | public bool Error { get { return _mask[2]; } set { _mask[2] = value; } } 40 | public bool Assert { get { return _mask[3]; } set { _mask[3] = value; } } 41 | public bool Exception { get { return _mask[4]; } set { _mask[4] = value; } } 42 | 43 | public bool IsAllTrue { get { return _mask.IsAll1; } } 44 | public bool IsAllFalse { get { return _mask.IsAll0; } } 45 | 46 | public bool Check(LogType type) 47 | { 48 | switch (type) 49 | { 50 | case LogType.Log: return Log; 51 | case LogType.Warning: return Warning; 52 | case LogType.Error: return Error; 53 | case LogType.Assert: return Assert; 54 | case LogType.Exception: return Exception; 55 | default: 56 | L.SomethingWentWrong(); 57 | return false; 58 | } 59 | } 60 | 61 | public void SetAllTrue() { _mask.All1(); } 62 | public void SetAllFalse() { _mask.All0(); } 63 | 64 | public override int GetHashCode() { return _mask.Get(); } 65 | 66 | public bool Equals(Mask other) 67 | { 68 | return _mask.Get() == other._mask.Get(); 69 | } 70 | 71 | public override bool Equals(object obj) 72 | { 73 | if (obj == null || !(obj is Mask)) return false; 74 | return Equals((Mask)obj); 75 | } 76 | 77 | public static bool operator ==(Mask a, Mask b) { return a.Equals(b); } 78 | public static bool operator !=(Mask a, Mask b) { return !(a == b); } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/GUI/GUITable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Settings.GUI 5 | { 6 | public class Table 7 | { 8 | public enum Direction { Horizontal, Vertical, } 9 | 10 | private readonly Direction _dir; 11 | private readonly ScrollView _scroll; 12 | private readonly float _rowSize; 13 | private readonly GUIStyle _bg; 14 | 15 | private bool _isHorizontal { get { return _dir == Direction.Horizontal; } } 16 | private bool _isVertical { get { return _dir == Direction.Vertical; } } 17 | private float _scrollAmount 18 | { 19 | get { return ScrollSide(_scroll.Scroll); } 20 | set 21 | { 22 | if (_isHorizontal) _scroll.ScrollX = value; 23 | else _scroll.ScrollY = value; 24 | } 25 | } 26 | 27 | public Table(Direction dir, float rowSize, float initScroll, GUIStyle bg) 28 | { 29 | _dir = dir; 30 | _rowSize = rowSize; 31 | _bg = bg; 32 | _scroll = new ScrollView(Align(0, initScroll), _isHorizontal, _isVertical); 33 | } 34 | 35 | private Vector2 Align(float fixedSide, float scrollSide) 36 | { 37 | if (_isHorizontal) return new Vector2(scrollSide, fixedSide); 38 | else return new Vector2(fixedSide, scrollSide); 39 | } 40 | 41 | private float FixedSide(Rect rect) 42 | { 43 | if (_isHorizontal) return rect.height; 44 | else return rect.width; 45 | } 46 | 47 | private float ScrollSide(Vector2 v) 48 | { 49 | if (_isHorizontal) return v.x; 50 | else return v.y; 51 | } 52 | 53 | private float ScrollSide(Rect rect) 54 | { 55 | if (_isHorizontal) return rect.width; 56 | else return rect.height; 57 | } 58 | 59 | public void Update() 60 | { 61 | _scroll.Update(); 62 | } 63 | 64 | public void OnGUI(Rect area, int count, Action drawer) 65 | { 66 | UnityEngine.GUI.Box(area, "", _bg); 67 | 68 | var fixedSide = FixedSide(area); 69 | var scrollSide = ScrollSide(area); 70 | 71 | var viewSize = Align(fixedSide, count * _rowSize); 72 | var viewRect = new Rect(0, 0, viewSize.x, viewSize.y); 73 | _scroll.Begin(area, viewRect); 74 | 75 | var startIdx = Mathf.Clamp((int)(_scrollAmount / _rowSize), 0, count); 76 | var visibleCount = (int)(scrollSide / _rowSize) + 2; 77 | var rowSize = Align(fixedSide, _rowSize); 78 | var drawedRows = 0; 79 | for (var i = startIdx; i < count && drawedRows < visibleCount; ++i, ++drawedRows) 80 | { 81 | var rowPos = Align(0, i * _rowSize); 82 | var rowArea = new Rect(rowPos.x, rowPos.y, rowSize.x, rowSize.y); 83 | GUILayout.BeginArea(rowArea); 84 | drawer(i); 85 | GUILayout.EndArea(); 86 | } 87 | 88 | _scroll.End(); 89 | } 90 | 91 | public void SetScrollToKeepIn(Rect area, int idx) 92 | { 93 | var scrollMax = idx * _rowSize; 94 | var scrollMin = scrollMax + _rowSize - ScrollSide(area); 95 | _scrollAmount = Mathf.Clamp(_scrollAmount, scrollMin, scrollMax); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/GUI/GUIScrollView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.GUI 4 | { 5 | public class ScrollView 6 | { 7 | private Vector2 _scroll; 8 | public Vector2 Scroll 9 | { 10 | get { return _scroll; } 11 | set { _scroll = value; } 12 | } 13 | 14 | public float ScrollX 15 | { 16 | get { return _scroll.x; } 17 | set { _scroll.x = value; } 18 | } 19 | 20 | public float ScrollY 21 | { 22 | get { return _scroll.y; } 23 | set { _scroll.y = value; } 24 | } 25 | 26 | private readonly bool _horizontal; 27 | private readonly bool _vertical; 28 | 29 | private Rect _lastArea; 30 | private bool _isTouchFocused; 31 | private int _lastTouchUpdateFrame; 32 | 33 | public ScrollView(Vector2 initScroll, bool horizontal, bool vertical) 34 | { 35 | _scroll = initScroll; 36 | _horizontal = horizontal; 37 | _vertical = vertical; 38 | } 39 | 40 | public void Update() 41 | { 42 | UpdateTouch(); 43 | } 44 | 45 | public void Begin(Rect area, Rect viewRect) 46 | { 47 | _lastArea = area; 48 | var afterScroll = UnityEngine.GUI.BeginScrollView( 49 | area, _scroll, viewRect); 50 | if (_horizontal) _scroll.x = afterScroll.x; 51 | if (_vertical) _scroll.y = afterScroll.y; 52 | _scroll.x = Mathf.Clamp(_scroll.x, 0, viewRect.width - area.width); 53 | _scroll.y = Mathf.Clamp(_scroll.y, 0, viewRect.height - area.height); 54 | } 55 | 56 | public void End() 57 | { 58 | UnityEngine.GUI.EndScrollView(); 59 | } 60 | 61 | public void BeginLayout(Rect area) 62 | { 63 | _lastArea = area; 64 | GUILayout.BeginArea(area); 65 | var afterScroll = GUILayout.BeginScrollView(_scroll); 66 | if (_horizontal) _scroll.x = afterScroll.x; 67 | if (_vertical) _scroll.y = afterScroll.y; 68 | } 69 | 70 | public void EndLayout() 71 | { 72 | GUILayout.EndScrollView(); 73 | GUILayout.EndArea(); 74 | } 75 | 76 | private void UpdateTouch() 77 | { 78 | // check touch discontinued 79 | if (_lastTouchUpdateFrame < Time.frameCount - 10 /* magic number */) 80 | _isTouchFocused = false; 81 | _lastTouchUpdateFrame = Time.frameCount; 82 | 83 | // check focus 84 | if (!_isTouchFocused && Util.Mouse.IsDown) 85 | { 86 | Vector2 curPos; 87 | if (!Util.Mouse.CurPos(out curPos)) return; 88 | curPos = new Vector2(curPos.x, Screen.height - curPos.y); 89 | if (!_lastArea.Contains(curPos)) return; 90 | _isTouchFocused = true; 91 | return; 92 | } 93 | 94 | if (!_isTouchFocused) 95 | return; 96 | 97 | // check delta 98 | Vector2 delta; 99 | if (!Util.Mouse.Delta(out delta)) 100 | _isTouchFocused = false; 101 | 102 | // update scroll 103 | if (_horizontal && delta.x != 0) 104 | _scroll.x -= delta.x; 105 | if (_vertical && delta.y != 0) 106 | _scroll.y += delta.y; 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Core/Settings.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using BehaviourListeners = System.Collections.Generic.List; 3 | using FPSCounter = Settings.Extension.FPS.Counter; 4 | 5 | namespace Settings 6 | { 7 | [AddComponentMenu("Settings/Settings.Settings")] 8 | public class Settings : MonoBehaviour 9 | { 10 | public bool EnableGesture; 11 | public KeyCode KeyboardShortcutForShow; 12 | 13 | private bool _isInited { get { return _guiDrawer != null; } } 14 | private GUI.Drawer _guiDrawer; 15 | private bool _isShowingGUI; 16 | public bool IsShowingGUI => _isShowingGUI; 17 | private IGesture _gesture; 18 | private readonly BehaviourListeners _behaviourListeners = new BehaviourListeners(8); 19 | 20 | private void Awake() 21 | { 22 | Init(); 23 | } 24 | 25 | private void Init() 26 | { 27 | if (_isInited) return; 28 | _guiDrawer = new GUI.Drawer(); 29 | _guiDrawer.OnClose += () => _isShowingGUI = false; 30 | var gestureLeastLength = (Screen.width + Screen.height) / 4; 31 | _gesture = new CircleGesture(new TouchProvider(), gestureLeastLength); 32 | } 33 | 34 | private void OnEnable() 35 | { 36 | Init(); 37 | foreach (var l in _behaviourListeners) 38 | l.OnEnable(); 39 | } 40 | 41 | private void OnDestroy() 42 | { 43 | foreach (var l in _behaviourListeners) 44 | l.OnDisable(); 45 | } 46 | 47 | private void Update() 48 | { 49 | Init(); 50 | 51 | UpdateKeyboard(); 52 | 53 | if (_isShowingGUI) 54 | { 55 | Util.Mouse.Refresh(); 56 | _guiDrawer.Update(); 57 | } 58 | 59 | foreach (var l in _behaviourListeners) 60 | l.Update(_isShowingGUI); 61 | 62 | DetectGesture(); 63 | } 64 | 65 | private void UpdateKeyboard() 66 | { 67 | if (Input.GetKeyDown(KeyCode.Escape)) 68 | _isShowingGUI = false; 69 | if (Input.GetKeyDown(KeyboardShortcutForShow)) 70 | _isShowingGUI = !_isShowingGUI; 71 | } 72 | 73 | private void DetectGesture() 74 | { 75 | if (!EnableGesture) return; 76 | if (_isShowingGUI) return; 77 | _gesture.SampleOrCancel(); 78 | if (_gesture.CheckAndClear()) 79 | _isShowingGUI = true; 80 | } 81 | 82 | private void OnGUI() 83 | { 84 | Init(); 85 | if (!_isShowingGUI) return; 86 | var orgDepth = UnityEngine.GUI.depth; 87 | UnityEngine.GUI.depth = -1000; 88 | _guiDrawer.OnGUI(); 89 | UnityEngine.GUI.depth = orgDepth; 90 | } 91 | 92 | public void AddBehaviourListener(IBehaviourListener behaviourListener) 93 | { 94 | Init(); 95 | _behaviourListeners.Add(behaviourListener); 96 | if (enabled) behaviourListener.OnEnable(); 97 | } 98 | 99 | public void AddView(GUI.IView view) 100 | { 101 | Init(); 102 | _guiDrawer.AddView(view); 103 | } 104 | 105 | public void AddToolbarWidget(GUI.IToolbarWidget toolbarWidget) 106 | { 107 | Init(); 108 | _guiDrawer.AddToolbarWidget(toolbarWidget); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.Keyboard.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using K = UnityEngine.KeyCode; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal partial class View 7 | { 8 | private float _upDownTimeLeft; 9 | private K _curUpDownKey; 10 | private readonly K[] _upDownKeys = new[] { 11 | K.UpArrow, K.DownArrow, 12 | K.PageUp, K.PageDown, 13 | K.Home, K.End, 14 | }; 15 | 16 | private static int UpDownAmountForKey(K key) 17 | { 18 | switch (key) 19 | { 20 | case K.UpArrow: return -1; 21 | case K.DownArrow: return 1; 22 | case K.PageUp: return -5; 23 | case K.PageDown: return 5; 24 | case K.Home: return -10000; 25 | case K.End: return 10000; 26 | default: return 0; 27 | } 28 | } 29 | 30 | private void UpDownSelectedLogWithCurKey(float cooltime) 31 | { 32 | _config.KeepScrollToLast = false; 33 | _keepInSelectedLog = true; 34 | _selectedLog += UpDownAmountForKey(_curUpDownKey); 35 | _upDownTimeLeft = cooltime; 36 | } 37 | 38 | private void CheckAndUpdateSelectedLog(K key) 39 | { 40 | const float coolTimeFirst = 0.3f; 41 | if (_curUpDownKey != key && (Input.GetKeyDown(key) || Input.GetKey(key))) 42 | { 43 | _curUpDownKey = key; 44 | UpDownSelectedLogWithCurKey(coolTimeFirst); 45 | } 46 | else if (_curUpDownKey == key && (Input.GetKeyUp(key) || !Input.GetKey(key))) 47 | { 48 | _curUpDownKey = K.None; 49 | _upDownTimeLeft = coolTimeFirst; 50 | } 51 | } 52 | 53 | private void UpdateKeyboardAction() 54 | { 55 | foreach (var key in _upDownKeys) 56 | CheckAndUpdateSelectedLog(key); 57 | } 58 | 59 | private void UpdateKeyboardStay() 60 | { 61 | if (_curUpDownKey == K.None) 62 | return; 63 | 64 | if (_upDownTimeLeft > 0) 65 | { 66 | _upDownTimeLeft -= Time.unscaledDeltaTime; 67 | return; 68 | } 69 | 70 | const float coolTimeFast = 0.02f; 71 | UpDownSelectedLogWithCurKey(coolTimeFast); 72 | } 73 | 74 | private void UpdateKeyboardShortcut() 75 | { 76 | if (Input.GetKeyDown(KeyCode.Space)) 77 | _config.Collapse = !_config.Collapse; 78 | if (Input.GetKeyDown(KeyCode.Comma)) 79 | _config.KeepScrollToLast = !_config.KeepScrollToLast; 80 | if (Input.GetKeyDown(KeyCode.C)) 81 | _isClickedClear.On(); 82 | if (Input.GetKeyDown(KeyCode.L)) 83 | _config.Filter.Log = !_config.Filter.Log; 84 | if (Input.GetKeyDown(KeyCode.W)) 85 | _config.Filter.Warning = !_config.Filter.Warning; 86 | if (Input.GetKeyDown(KeyCode.E)) 87 | { 88 | var flag = !_config.Filter.Error; 89 | _config.Filter.Error = flag; 90 | _config.Filter.Assert = flag; 91 | _config.Filter.Exception = flag; 92 | } 93 | } 94 | 95 | private void UpdateKeyboard() 96 | { 97 | UpdateKeyboardAction(); 98 | UpdateKeyboardStay(); 99 | UpdateKeyboardShortcut(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | internal partial class View : GUI.IView 6 | { 7 | private const int _iconWidth = 40; 8 | private const int _rowHeight = 80; 9 | private const int _toolbarHeight = 80; 10 | 11 | private readonly GUI.Table _table; 12 | private GUI.ScrollView _stackScroll; 13 | private readonly Organizer _organizer; 14 | 15 | private int _selectedLog = -1; 16 | private int _lastSelectedLog = -1; 17 | private bool _isSelectedLogDirty { get { return _selectedLog != _lastSelectedLog; } } 18 | private bool _keepInSelectedLog; 19 | 20 | private Toggle _isClickedClear; 21 | public System.Action OnClickClear; 22 | 23 | public class Config 24 | { 25 | public bool Collapse = false; 26 | public bool KeepScrollToLast = true; 27 | public bool ShowTime = false; 28 | public bool ShowScene = false; 29 | public Mask Filter = Mask.AllTrue; 30 | } 31 | 32 | private readonly Config _config; 33 | 34 | public View(Config config, Organizer organizer) 35 | : base("Log", Icons.Log) 36 | { 37 | _config = config; 38 | _table = new GUI.Table( 39 | GUI.Table.Direction.Vertical, 40 | _rowHeight, 0, 41 | GUI.Styles.BG); 42 | _stackScroll = new GUI.ScrollView(Vector2.zero, true, true); 43 | _organizer = organizer; 44 | } 45 | 46 | public override void Update() 47 | { 48 | UpdateKeyboard(); 49 | _table.Update(); 50 | _stackScroll.Update(); 51 | if (_isClickedClear.Off()) 52 | OnClickClear(); 53 | } 54 | 55 | private void ClampSelectedLog(int logCount) 56 | { 57 | if (logCount == 0) _selectedLog = -1; 58 | else _selectedLog = Mathf.Clamp(_selectedLog, 0, logCount - 1); 59 | } 60 | 61 | public override void OnGUI(Rect area) 62 | { 63 | // layout 64 | Rect toolbarArea, tableArea, stackArea; 65 | 66 | { 67 | var x = area.x; var y = area.y; 68 | var w = area.width; var h = area.height; 69 | var tableH = (h - _toolbarHeight) * 0.75f; 70 | var stackH = (h - _toolbarHeight) * 0.25f; 71 | toolbarArea = new Rect(x, y, w, _toolbarHeight); 72 | y += _toolbarHeight; 73 | tableArea = new Rect(x, y, w, tableH); 74 | y += tableH; 75 | stackArea = new Rect(x, y, w, stackH); 76 | y += stackH; 77 | } 78 | 79 | // filter 80 | AbstractLogs logs = null; 81 | if (_config.Collapse) 82 | { 83 | var rawLogs = _organizer.FilterCollapsed(_config.Filter); 84 | logs = new AbstractLogs(rawLogs); 85 | } 86 | else 87 | { 88 | var rawLogs = _organizer.Filter(_config.Filter); 89 | logs = new AbstractLogs(rawLogs); 90 | } 91 | 92 | // draw 93 | OnGUIToolbar(toolbarArea); 94 | ClampSelectedLog(logs.Count); 95 | OnGUITable(tableArea, logs); 96 | if (_selectedLog >= 0) DrawStack(stackArea, logs[_selectedLog]); 97 | else DrawStackEmpty(stackArea); 98 | _lastSelectedLog = _selectedLog; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.Styles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Helper = Settings.GUI.Helper; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal partial class View 7 | { 8 | private static class Styles 9 | { 10 | public static readonly GUIStyle Font; 11 | public static readonly GUIStyle Icon; 12 | 13 | public static readonly GUIStyle EvenLog; 14 | public static readonly GUIStyle OddLog; 15 | public static readonly GUIStyle SelectedLog; 16 | public static readonly GUIStyle SelectedLogFont; 17 | public static readonly GUIStyle CollapsedCountFont; 18 | 19 | public static readonly GUIStyle StackBG; 20 | public static readonly GUIStyle StackFont; 21 | 22 | public static readonly GUIStyle ToolbarBG; 23 | public static readonly GUIStyle ToolbarButton; 24 | public static readonly GUIStyle ToolbarButtonOn; 25 | 26 | private static GUIStyle MakeBaseLogStyle() 27 | { 28 | var ret = new GUIStyle(); 29 | ret.clipping = TextClipping.Clip; 30 | ret.alignment = TextAnchor.UpperLeft; 31 | ret.imagePosition = ImagePosition.ImageLeft; 32 | return ret; 33 | } 34 | 35 | static Styles() 36 | { 37 | const int fontSize = 32; 38 | 39 | Font = new GUIStyle(); 40 | Font.fontSize = fontSize; 41 | Font.alignment = TextAnchor.MiddleLeft; 42 | Font.clipping = TextClipping.Clip; 43 | Icon = new GUIStyle(); 44 | Icon.alignment = TextAnchor.MiddleCenter; 45 | 46 | EvenLog = MakeBaseLogStyle(); 47 | EvenLog.normal.background = Helper.Solid(0xeeeeeee0); 48 | OddLog = MakeBaseLogStyle(); 49 | OddLog.normal.background = Helper.Solid(0xe0e0e0e0); 50 | 51 | SelectedLog = MakeBaseLogStyle(); 52 | SelectedLog.normal.background = Helper.Solid(0x0d47a1e0); 53 | SelectedLogFont = new GUIStyle(); 54 | SelectedLogFont.fontSize = fontSize; 55 | SelectedLogFont.alignment = TextAnchor.MiddleLeft; 56 | SelectedLogFont.clipping = TextClipping.Clip; 57 | SelectedLogFont.normal.textColor = Color.white; 58 | 59 | CollapsedCountFont = new GUIStyle(); 60 | CollapsedCountFont.alignment = TextAnchor.MiddleCenter; 61 | CollapsedCountFont.fontSize = fontSize; 62 | CollapsedCountFont.normal.background = Helper.Solid(0x75757570); 63 | CollapsedCountFont.fixedWidth = fontSize * 2; 64 | 65 | StackBG = new GUIStyle(); 66 | StackBG.normal.background = Helper.Solid(0x9e9e9ef0); 67 | StackFont = new GUIStyle(); 68 | StackFont.fontSize = 28; 69 | StackFont.normal.textColor = Helper.UintToColor(0x424242ff); 70 | 71 | ToolbarBG = new GUIStyle(); 72 | ToolbarBG.normal.background = Helper.Solid(0xbdbdbdf0); 73 | ToolbarButton = new GUIStyle(); 74 | ToolbarButton.margin = new RectOffset(2, 2, 2, 2); 75 | ToolbarButton.alignment = TextAnchor.MiddleCenter; 76 | ToolbarButton.normal.background = Helper.Solid(0x9e9e9ef0); 77 | ToolbarButton.hover.background = Helper.Solid(0x757575f0); 78 | ToolbarButtonOn = new GUIStyle(ToolbarButton); 79 | ToolbarButtonOn.normal.background = Helper.Solid(0x616161f0); 80 | ToolbarButtonOn.hover.background = Helper.Solid(0x424242f0); 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogView.Table.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Settings.Extension.Log 4 | { 5 | internal partial class View 6 | { 7 | private static readonly GUIContent _tempContent = new GUIContent(); 8 | 9 | private static Rect OnGUILogRowRightToLeft(string text, GUIStyle fontStyle, ref float x) 10 | { 11 | _tempContent.text = text; 12 | var w = fontStyle.CalcSize(_tempContent).x; 13 | x -= w; 14 | var r = new Rect(x, 0, w, _rowHeight); 15 | UnityEngine.GUI.Label(r, _tempContent, fontStyle); 16 | return r; 17 | } 18 | 19 | private static Rect OnGUILogRowRightToLeft(GUIContent icon, GUIStyle iconStyle, ref float x) 20 | { 21 | x -= _iconWidth; 22 | var r = new Rect(x, 0, _iconWidth, _rowHeight); 23 | UnityEngine.GUI.Box(r, icon, iconStyle); 24 | return r; 25 | } 26 | 27 | private void OnGUILogRow(float width, AbstractLog log, int index, bool isSelected) 28 | { 29 | const int rightPadding = 10; 30 | 31 | GUIStyle backStyle = null; 32 | GUIStyle fontStyle = null; 33 | if (isSelected) 34 | { 35 | backStyle = Styles.SelectedLog; 36 | fontStyle = Styles.SelectedLogFont; 37 | } 38 | else 39 | { 40 | backStyle = (index % 2 == 0) ? Styles.EvenLog : Styles.OddLog; 41 | fontStyle = Styles.Font; 42 | } 43 | 44 | var rect = new Rect(0, 0, width, _rowHeight); 45 | if (UnityEngine.GUI.Button(rect, "", backStyle)) 46 | _selectedLog = index; 47 | 48 | var rightX = width - rightPadding; 49 | // draw sample datas 50 | if (log.Sample.HasValue) 51 | { 52 | System.Action drawIconAndLabel = (icon, text) => 53 | { 54 | OnGUILogRowRightToLeft(text, fontStyle, ref rightX); 55 | OnGUILogRowRightToLeft(icon, Styles.Icon, ref rightX); 56 | }; 57 | var sample = log.Sample.Value; 58 | if (_config.ShowScene) drawIconAndLabel(Icons.ShowScene, sample.Scene); 59 | if (_config.ShowTime) drawIconAndLabel(Icons.ShowTime, sample.TimeToDisplay); 60 | } 61 | 62 | // draw count 63 | if (log.Count.HasValue) 64 | { 65 | var count = log.Count.Value; 66 | if (count != 0) 67 | OnGUILogRowRightToLeft(count.ToString(), Styles.CollapsedCountFont, ref rightX); 68 | } 69 | 70 | // draw message 71 | { 72 | var msg = log.Message; 73 | msg = msg.Split('\n')[0]; 74 | if (msg.Length > 256 /* magic number */) 75 | msg = msg.Substring(0, 256); 76 | 77 | var icon = Icons.ForLogType(log.Type); 78 | var iconRect = new Rect(0, 0, _iconWidth, _rowHeight); 79 | UnityEngine.GUI.Box(iconRect, icon, Styles.Icon); 80 | var labelRect = new Rect(_iconWidth, 0, rightX - _iconWidth, _rowHeight); 81 | UnityEngine.GUI.Label(labelRect, msg, fontStyle); 82 | } 83 | } 84 | 85 | private void OnGUITable(Rect area, AbstractLogs logs) 86 | { 87 | if (_config.KeepScrollToLast) 88 | { 89 | _selectedLog = logs.Count - 1; 90 | _table.SetScrollToKeepIn(area, _selectedLog); 91 | } 92 | 93 | if (_keepInSelectedLog) 94 | { 95 | _table.SetScrollToKeepIn(area, _selectedLog); 96 | _keepInSelectedLog = false; 97 | } 98 | 99 | _table.OnGUI(area, logs.Count, 100 | i => OnGUILogRow(area.width, logs[i], i, i == _selectedLog)); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /src/GUI/GUIListView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Settings.GUI 6 | { 7 | public struct ListViewItem 8 | { 9 | public string Text; 10 | public bool ShouldHighlight; 11 | 12 | public ListViewItem(string text, bool shouldHighlight) 13 | { 14 | Text = text; 15 | ShouldHighlight = shouldHighlight; 16 | } 17 | } 18 | 19 | public interface IListViewDelegate 20 | { 21 | int Count { get; } 22 | ListViewItem GetItem(int index); 23 | void OnSelect(int index); 24 | } 25 | 26 | public class ListView : IView 27 | { 28 | private static class Styles 29 | { 30 | public static readonly GUIStyle ButtonEven; 31 | public static readonly GUIStyle ButtonOdd; 32 | public static readonly GUIStyle ButtonSelected; 33 | public static readonly GUIStyle ButtonFocusOverlay; 34 | 35 | static Styles() 36 | { 37 | ButtonEven = new GUIStyle(GUI.Styles.ButtonLightGray); 38 | ButtonEven.alignment = TextAnchor.MiddleCenter; 39 | ButtonOdd = new GUIStyle(GUI.Styles.ButtonGray); 40 | ButtonOdd.alignment = TextAnchor.MiddleCenter; 41 | ButtonSelected = new GUIStyle(GUI.Styles.ButtonGraySelected); 42 | ButtonSelected.alignment = TextAnchor.MiddleCenter; 43 | ButtonFocusOverlay = new GUIStyle(); 44 | ButtonFocusOverlay.normal.background = GUI.Helper.Solid(0xffff0060); 45 | } 46 | } 47 | 48 | private readonly int _cellHeight; 49 | private readonly IListViewDelegate _delegate; 50 | private int? _focus; 51 | 52 | public ListView(string title, GUIContent toolbarIcon, int cellHeight, IListViewDelegate dataProvider) 53 | : base(title, toolbarIcon) 54 | { 55 | _cellHeight = cellHeight; 56 | _delegate = dataProvider; 57 | } 58 | 59 | public override void Update() 60 | { 61 | UpdateFocus(); 62 | } 63 | 64 | private void UpdateFocus() 65 | { 66 | // up down focus 67 | if (Input.GetKeyDown(KeyCode.UpArrow)) 68 | { 69 | if (!_focus.HasValue) _focus = -1; 70 | else --_focus; 71 | } 72 | 73 | if (Input.GetKeyDown(KeyCode.DownArrow)) 74 | { 75 | if (!_focus.HasValue) _focus = 0; 76 | else ++_focus; 77 | } 78 | 79 | if (!_focus.HasValue) return; 80 | 81 | // cull focus 82 | var max = _delegate.Count; 83 | _focus = (_focus.Value + max) % max; 84 | 85 | // on hit space 86 | if (Input.GetKeyDown(KeyCode.Return)) 87 | { 88 | _delegate.OnSelect(_focus.Value); 89 | _focus = null; 90 | } 91 | } 92 | 93 | public override void OnGUI(Rect area) 94 | { 95 | GUILayout.BeginArea(area, GUI.Styles.BG); 96 | 97 | for (var i = 0; i != _delegate.Count; ++i) 98 | { 99 | var item = _delegate.GetItem(i); 100 | 101 | // select style 102 | var style = item.ShouldHighlight 103 | ? Styles.ButtonSelected 104 | : (i % 2 == 0 ? Styles.ButtonEven : Styles.ButtonOdd); 105 | 106 | // draw button 107 | var rect = new Rect(0, i * _cellHeight, area.width, _cellHeight); 108 | if (UnityEngine.GUI.Button(rect, item.Text, style)) 109 | _delegate.OnSelect(i); 110 | 111 | // draw overlay 112 | if (i == _focus) 113 | UnityEngine.GUI.Box(rect, "", Styles.ButtonFocusOverlay); 114 | } 115 | 116 | GUILayout.EndArea(); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/Extension/Log/Log/LogOrganizer.cs: -------------------------------------------------------------------------------- 1 | using Logs = System.Collections.Generic.List; 2 | using ReadOnlyLogs = System.Collections.ObjectModel.ReadOnlyCollection; 3 | using CollapsedIndex = System.Collections.Generic.Dictionary; 4 | using CollapsedLogs = System.Collections.Generic.List; 5 | using ReadOnlyCollapsedLogs = System.Collections.ObjectModel.ReadOnlyCollection; 6 | 7 | namespace Settings.Extension.Log 8 | { 9 | internal class Organizer 10 | { 11 | private readonly Stash _stash; 12 | private Mask _lastMask; 13 | private readonly Logs _lastLogs; 14 | private readonly ReadOnlyLogs _lastLogsReadOnly; 15 | private Mask _lastCollapsedMask; 16 | private readonly CollapsedIndex _lastCollapsedIndex; 17 | private readonly CollapsedLogs _lastCollapsedLogs; 18 | private readonly ReadOnlyCollapsedLogs _lastCollapsedLogsReadOnly; 19 | 20 | public Organizer(Stash stash) 21 | { 22 | const int reserve = 256; 23 | _stash = stash; 24 | _lastMask.SetAllTrue(); 25 | _lastLogs = new Logs(reserve); 26 | _lastLogsReadOnly = _lastLogs.AsReadOnly(); 27 | _lastCollapsedMask.SetAllTrue(); 28 | _lastCollapsedIndex = new CollapsedIndex(); 29 | _lastCollapsedLogs = new CollapsedLogs(reserve); 30 | _lastCollapsedLogsReadOnly = _lastCollapsedLogs.AsReadOnly(); 31 | } 32 | 33 | public void Internal_AddToCache(Log log) 34 | { 35 | if (!_lastMask.IsAllTrue && _lastMask.Check(log.Type)) 36 | _lastLogs.Add(log); 37 | AddToCache_Collapsed(log); 38 | } 39 | 40 | private void AddToCache_Collapsed(Log log) 41 | { 42 | if (!_lastCollapsedMask.Check(log.Type)) return; 43 | var rawLog = new RawLog(log.Type, log.Message, log.Stacktrace); 44 | var hash = rawLog.GetHashCode(); 45 | int index; 46 | if (_lastCollapsedIndex.TryGetValue(hash, out index)) 47 | { 48 | var logAndCount = _lastCollapsedLogs[index]; 49 | logAndCount.Inc(); 50 | _lastCollapsedLogs[index] = logAndCount; 51 | } 52 | else 53 | { 54 | _lastCollapsedIndex.Add(hash, _lastCollapsedLogs.Count); 55 | _lastCollapsedLogs.Add(new LogAndCount(rawLog)); 56 | } 57 | } 58 | 59 | public ReadOnlyLogs Filter(Mask mask) 60 | { 61 | if (mask.IsAllTrue) 62 | { 63 | _lastMask = mask; 64 | _lastLogs.Clear(); 65 | return _stash.All(); 66 | } 67 | 68 | if (_lastMask == mask) 69 | return _lastLogsReadOnly; 70 | 71 | _lastMask = mask; 72 | _lastLogs.Clear(); 73 | 74 | if (mask.IsAllFalse) 75 | return _lastLogsReadOnly; 76 | 77 | foreach (var log in _stash.All()) 78 | if (mask.Check(log.Type)) 79 | _lastLogs.Add(log); 80 | return _lastLogsReadOnly; 81 | } 82 | 83 | public ReadOnlyCollapsedLogs FilterCollapsed(Mask mask) 84 | { 85 | if (_lastCollapsedMask == mask) 86 | return _lastCollapsedLogsReadOnly; 87 | 88 | _lastCollapsedMask = mask; 89 | _lastCollapsedIndex.Clear(); 90 | _lastCollapsedLogs.Clear(); 91 | 92 | if (_lastCollapsedMask.IsAllFalse) 93 | return _lastCollapsedLogsReadOnly; 94 | 95 | foreach (var log in _stash.All()) 96 | AddToCache_Collapsed(log); 97 | return _lastCollapsedLogsReadOnly; 98 | } 99 | 100 | public void Clear() 101 | { 102 | _lastLogs.Clear(); 103 | _lastCollapsedIndex.Clear(); 104 | _lastCollapsedLogs.Clear(); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /src/Extension/SystemInfo/SystemInfoView.Pages.cs: -------------------------------------------------------------------------------- 1 | using S = UnityEngine.SystemInfo; 2 | using A = UnityEngine.Application; 3 | 4 | namespace Settings.Extension.SystemInfo 5 | { 6 | public partial class View 7 | { 8 | private void AddAllPages() 9 | { 10 | { 11 | var b = AddPage("Device"); 12 | b.Header(S.deviceUniqueIdentifier); 13 | b.Row("Model", S.deviceModel, S.deviceType); 14 | b.Row("Name", S.deviceName); 15 | b.Row("OS", S.operatingSystemFamily, S.operatingSystem); 16 | b.Row("Memory Size", S.systemMemorySize); 17 | b.Row("Processor Type", S.processorType); 18 | b.Row("Processor Count", S.processorCount); 19 | b.Row("Processor Hz", S.processorFrequency); 20 | } 21 | 22 | { 23 | var b = AddPage("Graphics"); 24 | b.Header(RowBuilder.DescAndDetail(S.graphicsDeviceName, S.graphicsDeviceID)); 25 | b.Row("Type", S.graphicsDeviceType); 26 | b.Row("Vendor", S.graphicsDeviceVendor, S.graphicsDeviceVendorID); 27 | b.Row("Version", S.graphicsDeviceVersion); 28 | b.Row("Support Multithread", S.graphicsMultiThreaded); 29 | b.Row("Memory Size", S.graphicsMemorySize); 30 | b.Row("Max Texture Size", S.maxTextureSize); 31 | b.Row("Shader Level", S.graphicsShaderLevel); 32 | b.Row("NPOT Support", S.npotSupport); 33 | } 34 | 35 | { 36 | var b = AddPage("Application"); 37 | b.Header(RowBuilder.DescAndDetail(A.productName, A.identifier)); 38 | b.Row("Ver", A.version + " / " + A.unityVersion); 39 | b.Row("Company Name", A.companyName); 40 | b.Row("Platform", A.platform); 41 | b.Row("System Lang", A.systemLanguage); 42 | 43 | b.Row("Data Path", A.dataPath); 44 | b.Row("Persistent Data Path", A.persistentDataPath); 45 | b.Row("Streaming Assets Path", A.streamingAssetsPath); 46 | b.Row("Temp Cache Path", A.temporaryCachePath); 47 | 48 | b.Row("Installer Name", A.installerName); 49 | b.Row("Install Mode", A.installMode); 50 | b.Row("Run In BG", A.runInBackground); 51 | b.Row("Sandbox Type", A.sandboxType); 52 | b.Row("BG Loading Priority", A.backgroundLoadingPriority); 53 | b.Row("Cloud Project Id", A.cloudProjectId); 54 | 55 | b.Row("Target Frame Rate", () => A.targetFrameRate); 56 | b.Row("Internet Reachability", () => A.internetReachability); 57 | b.Row("Genuine", () => A.genuine); 58 | b.Row("Genuine Check Available", () => A.genuineCheckAvailable); 59 | b.Row("Streamed Bytes", () => A.streamedBytes); 60 | } 61 | 62 | { 63 | var b = AddPage("G/Supported"); 64 | b.Row("Render Target", S.supportedRenderTargetCount); 65 | b.Row("Copy Texture", S.copyTextureSupport); 66 | b.Row("Shadow", S.supportsShadows); 67 | b.Row("Raw Shadow Depth Sampling", S.supportsRawShadowDepthSampling); 68 | b.Row("Compute Shader", S.supportsComputeShaders); 69 | b.Row("2D Array Tex", S.supports2DArrayTextures); 70 | b.Row("3D Tex", S.supports3DTextures); 71 | b.Row("Sparse Tex", S.supportsSparseTextures); 72 | b.Row("Image Effects", S.supportsImageEffects); 73 | b.Row("Motion Vectors", S.supportsMotionVectors); 74 | b.Row("Cubemap Array Tex", S.supportsCubemapArrayTextures); 75 | b.Row("Render To Cubemap", S.supportsRenderToCubemap); 76 | b.Row("Reversed Z Buffer", S.usesReversedZBuffer); 77 | } 78 | 79 | // skip 80 | // web player 81 | // b.Row("", A.srcValue); 82 | // b.Row("", A.absoluteURL); 83 | // b.Row("", A.isWebPlayer); 84 | // etc 85 | // b.Row("", A.isMobilePlatform); 86 | // b.Row("", A.isConsolePlatform); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Core/Installer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Object = UnityEngine.Object; 4 | using FPS = Settings.Extension.FPS; 5 | using SystemInfo = Settings.Extension.SystemInfo; 6 | using Log = Settings.Extension.Log; 7 | using Scene = Settings.Extension.Scene; 8 | 9 | namespace Settings 10 | { 11 | [AddComponentMenu("Settings/Settings.Installer")] 12 | public class Installer : MonoBehaviour 13 | { 14 | [NonSerialized] 15 | private bool _isInited = false; 16 | public bool EnableGestureForPlayer = true; 17 | public bool EnableGestureForEditor = false; 18 | public KeyCode KeyboardShortcutForShow = KeyCode.BackQuote; 19 | 20 | private static Settings _instance; 21 | public static Settings Instance 22 | { 23 | get 24 | { 25 | Install(); 26 | return _instance; 27 | } 28 | } 29 | 30 | private static bool InstantiateSettings() 31 | { 32 | if (_instance != null) 33 | return false; 34 | 35 | _instance = Object.FindObjectOfType(); 36 | var shouldInstantiate = _instance == null; 37 | if (shouldInstantiate) 38 | { 39 | var singleton = new GameObject("Settings (Singleton)"); 40 | _instance = singleton.AddComponent(); 41 | DontDestroyOnLoad(singleton); 42 | } 43 | 44 | // for readability 45 | var isInstantiated = shouldInstantiate; 46 | return isInstantiated; 47 | } 48 | 49 | public static void Install() 50 | { 51 | if (!Application.isPlaying) return; 52 | if (!InstantiateSettings()) return; 53 | var installer = Object.FindObjectOfType(); 54 | if (installer == null) new GameObject().AddComponent(); 55 | } 56 | 57 | private void Init() 58 | { 59 | if (_isInited) return; 60 | _isInited = true; 61 | 62 | var isInstantiated = InstantiateSettings(); 63 | 64 | // if there's another Installer already, just destroy. 65 | if (transform.parent != _instance.transform 66 | && _instance.transform.childCount > 0) 67 | { 68 | Destroy(gameObject); 69 | return; 70 | } 71 | 72 | gameObject.name = "Installer (For Recompile)"; 73 | 74 | // change parent to Settings. 75 | if (transform.parent != _instance.transform) 76 | transform.SetParent(_instance.transform, false); 77 | 78 | // initialize settings 79 | if (isInstantiated) 80 | { 81 | _instance.EnableGesture = Application.isEditor 82 | ? EnableGestureForEditor : EnableGestureForPlayer; 83 | _instance.KeyboardShortcutForShow = KeyboardShortcutForShow; 84 | } 85 | 86 | InjectDependency(_instance); 87 | } 88 | 89 | private void Awake() 90 | { 91 | Init(); 92 | } 93 | 94 | private void OnEnable() 95 | { 96 | Init(); 97 | } 98 | 99 | private static void InjectDependency(Settings settings) 100 | { 101 | // inject FPS 102 | { 103 | var fpsCounter = new FPS.Counter(); 104 | settings.AddBehaviourListener(fpsCounter); 105 | settings.AddToolbarWidget(new FPS.ToolbarWidget(fpsCounter)); 106 | } 107 | 108 | // inject SystemInfo 109 | { 110 | settings.AddView(new SystemInfo.View()); 111 | } 112 | 113 | // inject Log 114 | { 115 | var provider = new Log.Provider(); 116 | var sampler = new Log.Sampler(); 117 | var watch = new Log.Watch(provider, sampler); 118 | settings.AddBehaviourListener(watch); 119 | 120 | var viewConfig = new Log.View.Config(); // TODO 121 | var stash = watch.Stash; 122 | var organizer = stash.Organizer; 123 | var view = new Log.View(viewConfig, organizer); 124 | view.OnClickClear += () => stash.Clear(); 125 | settings.AddView(view); 126 | } 127 | 128 | // inject Scene 129 | { 130 | settings.AddView(new Scene.View()); 131 | } 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /example/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | blendWeights: 1 21 | textureQuality: 1 22 | anisotropicTextures: 0 23 | antiAliasing: 0 24 | softParticles: 0 25 | softVegetation: 0 26 | realtimeReflectionProbes: 0 27 | billboardsFaceCameraPosition: 0 28 | vSyncCount: 0 29 | lodBias: 0.3 30 | maximumLODLevel: 0 31 | particleRaycastBudget: 4 32 | asyncUploadTimeSlice: 2 33 | asyncUploadBufferSize: 4 34 | excludedTargetPlatforms: [] 35 | - serializedVersion: 2 36 | name: Fast 37 | pixelLightCount: 0 38 | shadows: 0 39 | shadowResolution: 0 40 | shadowProjection: 1 41 | shadowCascades: 1 42 | shadowDistance: 20 43 | shadowNearPlaneOffset: 3 44 | shadowCascade2Split: 0.33333334 45 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 46 | blendWeights: 2 47 | textureQuality: 0 48 | anisotropicTextures: 0 49 | antiAliasing: 0 50 | softParticles: 0 51 | softVegetation: 0 52 | realtimeReflectionProbes: 0 53 | billboardsFaceCameraPosition: 0 54 | vSyncCount: 0 55 | lodBias: 0.4 56 | maximumLODLevel: 0 57 | particleRaycastBudget: 16 58 | asyncUploadTimeSlice: 2 59 | asyncUploadBufferSize: 4 60 | excludedTargetPlatforms: [] 61 | - serializedVersion: 2 62 | name: Simple 63 | pixelLightCount: 1 64 | shadows: 1 65 | shadowResolution: 0 66 | shadowProjection: 1 67 | shadowCascades: 1 68 | shadowDistance: 20 69 | shadowNearPlaneOffset: 3 70 | shadowCascade2Split: 0.33333334 71 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 72 | blendWeights: 2 73 | textureQuality: 0 74 | anisotropicTextures: 1 75 | antiAliasing: 0 76 | softParticles: 0 77 | softVegetation: 0 78 | realtimeReflectionProbes: 0 79 | billboardsFaceCameraPosition: 0 80 | vSyncCount: 1 81 | lodBias: 0.7 82 | maximumLODLevel: 0 83 | particleRaycastBudget: 64 84 | asyncUploadTimeSlice: 2 85 | asyncUploadBufferSize: 4 86 | excludedTargetPlatforms: [] 87 | - serializedVersion: 2 88 | name: Good 89 | pixelLightCount: 2 90 | shadows: 2 91 | shadowResolution: 1 92 | shadowProjection: 1 93 | shadowCascades: 2 94 | shadowDistance: 40 95 | shadowNearPlaneOffset: 3 96 | shadowCascade2Split: 0.33333334 97 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 98 | blendWeights: 2 99 | textureQuality: 0 100 | anisotropicTextures: 1 101 | antiAliasing: 0 102 | softParticles: 0 103 | softVegetation: 1 104 | realtimeReflectionProbes: 1 105 | billboardsFaceCameraPosition: 1 106 | vSyncCount: 1 107 | lodBias: 1 108 | maximumLODLevel: 0 109 | particleRaycastBudget: 256 110 | asyncUploadTimeSlice: 2 111 | asyncUploadBufferSize: 4 112 | excludedTargetPlatforms: [] 113 | - serializedVersion: 2 114 | name: Beautiful 115 | pixelLightCount: 3 116 | shadows: 2 117 | shadowResolution: 2 118 | shadowProjection: 1 119 | shadowCascades: 2 120 | shadowDistance: 70 121 | shadowNearPlaneOffset: 3 122 | shadowCascade2Split: 0.33333334 123 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 124 | blendWeights: 4 125 | textureQuality: 0 126 | anisotropicTextures: 2 127 | antiAliasing: 2 128 | softParticles: 1 129 | softVegetation: 1 130 | realtimeReflectionProbes: 1 131 | billboardsFaceCameraPosition: 1 132 | vSyncCount: 1 133 | lodBias: 1.5 134 | maximumLODLevel: 0 135 | particleRaycastBudget: 1024 136 | asyncUploadTimeSlice: 2 137 | asyncUploadBufferSize: 4 138 | excludedTargetPlatforms: [] 139 | - serializedVersion: 2 140 | name: Fantastic 141 | pixelLightCount: 4 142 | shadows: 2 143 | shadowResolution: 2 144 | shadowProjection: 1 145 | shadowCascades: 4 146 | shadowDistance: 150 147 | shadowNearPlaneOffset: 3 148 | shadowCascade2Split: 0.33333334 149 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 150 | blendWeights: 4 151 | textureQuality: 0 152 | anisotropicTextures: 2 153 | antiAliasing: 2 154 | softParticles: 1 155 | softVegetation: 1 156 | realtimeReflectionProbes: 1 157 | billboardsFaceCameraPosition: 1 158 | vSyncCount: 1 159 | lodBias: 2 160 | maximumLODLevel: 0 161 | particleRaycastBudget: 4096 162 | asyncUploadTimeSlice: 2 163 | asyncUploadBufferSize: 4 164 | excludedTargetPlatforms: [] 165 | m_PerPlatformDefaultQuality: 166 | Android: 2 167 | Nintendo 3DS: 5 168 | PS4: 5 169 | PSM: 5 170 | PSP2: 2 171 | Samsung TV: 2 172 | Standalone: 5 173 | Tizen: 2 174 | Web: 5 175 | WebGL: 3 176 | WiiU: 5 177 | Windows Store Apps: 5 178 | XboxOne: 5 179 | iPhone: 2 180 | tvOS: 5 181 | -------------------------------------------------------------------------------- /example/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /example/Assets/Main.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 1 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 1 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 0 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 0 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &647584698 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 5 122 | m_Component: 123 | - component: {fileID: 647584699} 124 | - component: {fileID: 647584700} 125 | m_Layer: 0 126 | m_Name: Main 127 | m_TagString: Untagged 128 | m_Icon: {fileID: 0} 129 | m_NavMeshLayer: 0 130 | m_StaticEditorFlags: 0 131 | m_IsActive: 1 132 | --- !u!4 &647584699 133 | Transform: 134 | m_ObjectHideFlags: 0 135 | m_PrefabParentObject: {fileID: 0} 136 | m_PrefabInternal: {fileID: 0} 137 | m_GameObject: {fileID: 647584698} 138 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 139 | m_LocalPosition: {x: 0, y: 0, z: 0} 140 | m_LocalScale: {x: 1, y: 1, z: 1} 141 | m_Children: [] 142 | m_Father: {fileID: 0} 143 | m_RootOrder: 1 144 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 145 | --- !u!114 &647584700 146 | MonoBehaviour: 147 | m_ObjectHideFlags: 0 148 | m_PrefabParentObject: {fileID: 0} 149 | m_PrefabInternal: {fileID: 0} 150 | m_GameObject: {fileID: 647584698} 151 | m_Enabled: 1 152 | m_EditorHideFlags: 0 153 | m_Script: {fileID: 11500000, guid: 373fabcdef2e242a2ab9a221c14e17b9, type: 3} 154 | m_Name: 155 | m_EditorClassIdentifier: 156 | --- !u!1 &824145628 157 | GameObject: 158 | m_ObjectHideFlags: 0 159 | m_PrefabParentObject: {fileID: 0} 160 | m_PrefabInternal: {fileID: 0} 161 | serializedVersion: 5 162 | m_Component: 163 | - component: {fileID: 824145633} 164 | - component: {fileID: 824145632} 165 | - component: {fileID: 824145631} 166 | - component: {fileID: 824145630} 167 | - component: {fileID: 824145629} 168 | m_Layer: 0 169 | m_Name: Main Camera 170 | m_TagString: MainCamera 171 | m_Icon: {fileID: 0} 172 | m_NavMeshLayer: 0 173 | m_StaticEditorFlags: 0 174 | m_IsActive: 1 175 | --- !u!81 &824145629 176 | AudioListener: 177 | m_ObjectHideFlags: 0 178 | m_PrefabParentObject: {fileID: 0} 179 | m_PrefabInternal: {fileID: 0} 180 | m_GameObject: {fileID: 824145628} 181 | m_Enabled: 1 182 | --- !u!124 &824145630 183 | Behaviour: 184 | m_ObjectHideFlags: 0 185 | m_PrefabParentObject: {fileID: 0} 186 | m_PrefabInternal: {fileID: 0} 187 | m_GameObject: {fileID: 824145628} 188 | m_Enabled: 1 189 | --- !u!92 &824145631 190 | Behaviour: 191 | m_ObjectHideFlags: 0 192 | m_PrefabParentObject: {fileID: 0} 193 | m_PrefabInternal: {fileID: 0} 194 | m_GameObject: {fileID: 824145628} 195 | m_Enabled: 1 196 | --- !u!20 &824145632 197 | Camera: 198 | m_ObjectHideFlags: 0 199 | m_PrefabParentObject: {fileID: 0} 200 | m_PrefabInternal: {fileID: 0} 201 | m_GameObject: {fileID: 824145628} 202 | m_Enabled: 1 203 | serializedVersion: 2 204 | m_ClearFlags: 2 205 | m_BackGroundColor: {r: 0.6544118, g: 1, b: 0.7282961, a: 0} 206 | m_NormalizedViewPortRect: 207 | serializedVersion: 2 208 | x: 0 209 | y: 0 210 | width: 1 211 | height: 1 212 | near clip plane: 0.3 213 | far clip plane: 1000 214 | field of view: 60 215 | orthographic: 1 216 | orthographic size: 5 217 | m_Depth: -1 218 | m_CullingMask: 219 | serializedVersion: 2 220 | m_Bits: 4294967295 221 | m_RenderingPath: -1 222 | m_TargetTexture: {fileID: 0} 223 | m_TargetDisplay: 0 224 | m_TargetEye: 3 225 | m_HDR: 0 226 | m_AllowMSAA: 1 227 | m_AllowDynamicResolution: 0 228 | m_ForceIntoRT: 0 229 | m_OcclusionCulling: 1 230 | m_StereoConvergence: 10 231 | m_StereoSeparation: 0.022 232 | --- !u!4 &824145633 233 | Transform: 234 | m_ObjectHideFlags: 0 235 | m_PrefabParentObject: {fileID: 0} 236 | m_PrefabInternal: {fileID: 0} 237 | m_GameObject: {fileID: 824145628} 238 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 239 | m_LocalPosition: {x: 0, y: 0, z: -10} 240 | m_LocalScale: {x: 1, y: 1, z: 1} 241 | m_Children: [] 242 | m_Father: {fileID: 0} 243 | m_RootOrder: 0 244 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 245 | --- !u!1 &914233707 246 | GameObject: 247 | m_ObjectHideFlags: 0 248 | m_PrefabParentObject: {fileID: 0} 249 | m_PrefabInternal: {fileID: 0} 250 | serializedVersion: 5 251 | m_Component: 252 | - component: {fileID: 914233709} 253 | - component: {fileID: 914233708} 254 | m_Layer: 0 255 | m_Name: Line 256 | m_TagString: Untagged 257 | m_Icon: {fileID: 0} 258 | m_NavMeshLayer: 0 259 | m_StaticEditorFlags: 0 260 | m_IsActive: 1 261 | --- !u!212 &914233708 262 | SpriteRenderer: 263 | m_ObjectHideFlags: 0 264 | m_PrefabParentObject: {fileID: 0} 265 | m_PrefabInternal: {fileID: 0} 266 | m_GameObject: {fileID: 914233707} 267 | m_Enabled: 1 268 | m_CastShadows: 0 269 | m_ReceiveShadows: 0 270 | m_DynamicOccludee: 1 271 | m_MotionVectors: 1 272 | m_LightProbeUsage: 0 273 | m_ReflectionProbeUsage: 0 274 | m_Materials: 275 | - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} 276 | m_StaticBatchInfo: 277 | firstSubMesh: 0 278 | subMeshCount: 0 279 | m_StaticBatchRoot: {fileID: 0} 280 | m_ProbeAnchor: {fileID: 0} 281 | m_LightProbeVolumeOverride: {fileID: 0} 282 | m_ScaleInLightmap: 1 283 | m_PreserveUVs: 0 284 | m_IgnoreNormalsForChartDetection: 0 285 | m_ImportantGI: 0 286 | m_StitchLightmapSeams: 0 287 | m_SelectedEditorRenderState: 0 288 | m_MinimumChartSize: 4 289 | m_AutoUVMaxDistance: 0.5 290 | m_AutoUVMaxAngle: 89 291 | m_LightmapParameters: {fileID: 0} 292 | m_SortingLayerID: 0 293 | m_SortingLayer: 0 294 | m_SortingOrder: 0 295 | m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} 296 | m_Color: {r: 1, g: 0.7352941, b: 0.7352941, a: 1} 297 | m_FlipX: 0 298 | m_FlipY: 0 299 | m_DrawMode: 0 300 | m_Size: {x: 1, y: 1} 301 | m_AdaptiveModeThreshold: 0.5 302 | m_SpriteTileMode: 0 303 | m_WasSpriteAssigned: 1 304 | m_MaskInteraction: 0 305 | --- !u!4 &914233709 306 | Transform: 307 | m_ObjectHideFlags: 0 308 | m_PrefabParentObject: {fileID: 0} 309 | m_PrefabInternal: {fileID: 0} 310 | m_GameObject: {fileID: 914233707} 311 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 312 | m_LocalPosition: {x: 0, y: 0, z: 0} 313 | m_LocalScale: {x: 10, y: 100, z: 1} 314 | m_Children: [] 315 | m_Father: {fileID: 0} 316 | m_RootOrder: 3 317 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 318 | --- !u!1 &1001084876 319 | GameObject: 320 | m_ObjectHideFlags: 0 321 | m_PrefabParentObject: {fileID: 0} 322 | m_PrefabInternal: {fileID: 0} 323 | serializedVersion: 5 324 | m_Component: 325 | - component: {fileID: 1001084877} 326 | - component: {fileID: 1001084878} 327 | m_Layer: 0 328 | m_Name: Installer 329 | m_TagString: Untagged 330 | m_Icon: {fileID: 0} 331 | m_NavMeshLayer: 0 332 | m_StaticEditorFlags: 0 333 | m_IsActive: 1 334 | --- !u!4 &1001084877 335 | Transform: 336 | m_ObjectHideFlags: 0 337 | m_PrefabParentObject: {fileID: 0} 338 | m_PrefabInternal: {fileID: 0} 339 | m_GameObject: {fileID: 1001084876} 340 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 341 | m_LocalPosition: {x: 0, y: 0, z: 0} 342 | m_LocalScale: {x: 1, y: 1, z: 1} 343 | m_Children: [] 344 | m_Father: {fileID: 0} 345 | m_RootOrder: 2 346 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 347 | --- !u!114 &1001084878 348 | MonoBehaviour: 349 | m_ObjectHideFlags: 0 350 | m_PrefabParentObject: {fileID: 0} 351 | m_PrefabInternal: {fileID: 0} 352 | m_GameObject: {fileID: 1001084876} 353 | m_Enabled: 1 354 | m_EditorHideFlags: 0 355 | m_Script: {fileID: 11500000, guid: ce72f249e872f46afb475dba410eaf19, type: 3} 356 | m_Name: 357 | m_EditorClassIdentifier: 358 | EnableGesture: 1 359 | KeyboardShortcutForShow: 96 360 | -------------------------------------------------------------------------------- /src/Extension/Log/View/LogVIew.Icons.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Settings.GUI; 3 | 4 | namespace Settings.Extension.Log 5 | { 6 | internal partial class View 7 | { 8 | private static class Icons 9 | { 10 | public static readonly GUIContent Clear; 11 | public static readonly GUIContent Collapse; 12 | public static readonly GUIContent KeepScrollToLast; 13 | public static readonly GUIContent ShowTime; 14 | public static readonly GUIContent ShowScene; 15 | public static readonly GUIContent Log; 16 | public static readonly GUIContent Warning; 17 | public static readonly GUIContent Error; 18 | 19 | private static GUIContent I(byte[] texData) { return new GUIContent(texData.ToTex()); } 20 | 21 | static Icons() 22 | { 23 | Clear = I(new byte[] { 24 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 25 | 0,0,0,64,0,0,0,64,8,3,0,0,0,157,183,129, 26 | 236,0,0,0,12,80,76,84,69,0,0,0,183,108,34,229, 27 | 190,109,183,123,8,228,185,212,131,0,0,0,4,116,82,78, 28 | 83,0,246,252,95,65,7,139,44,0,0,1,88,73,68,65, 29 | 84,120,218,237,151,237,174,194,48,12,67,231,250,253,223,249, 30 | 38,106,134,53,170,210,52,213,21,127,56,18,251,130,227,185, 31 | 211,6,229,218,4,205,0,192,171,6,241,117,223,112,191,200, 32 | 119,125,146,71,62,128,67,191,225,168,63,154,3,163,100,19, 33 | 160,233,94,2,220,215,141,134,94,97,63,128,221,111,119,2, 34 | 192,253,211,135,218,33,11,167,15,250,14,88,56,253,3,110, 35 | 249,109,132,53,95,176,230,11,214,124,193,67,31,53,95,48, 36 | 231,79,19,192,140,31,84,71,0,81,26,129,92,95,246,12, 37 | 196,130,224,214,13,140,17,102,252,120,120,199,140,150,44,16, 38 | 157,69,246,81,148,255,234,32,122,64,214,31,19,96,164,11, 39 | 200,113,41,208,8,214,254,72,63,202,98,128,0,75,190,72, 40 | 20,80,223,74,0,142,2,116,15,213,47,65,247,235,1,42, 41 | 80,28,194,163,64,225,219,132,243,0,220,47,166,27,40,71, 42 | 1,6,150,13,36,14,1,88,94,199,15,1,169,4,102,2, 43 | 124,69,99,213,0,10,208,74,7,129,73,5,9,10,208,62, 44 | 240,218,227,108,12,243,128,204,44,135,0,38,1,74,224,37, 45 | 125,64,19,178,88,43,73,51,173,196,227,72,182,88,135,136, 46 | 187,254,114,154,199,46,198,188,158,124,84,241,125,103,125,47, 47 | 49,254,217,80,149,224,53,92,36,23,29,226,199,195,53,168, 48 | 146,123,201,73,42,227,68,112,45,54,226,8,178,9,8,17, 49 | 119,98,120,244,183,50,48,68,243,222,183,120,109,160,143,211, 50 | 182,126,252,43,127,19,109,11,32,90,180,56,240,0,0,0, 51 | 0,73,69,78,68,174,66,96,130, }); 52 | 53 | Collapse = I(new byte[] { 54 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 55 | 0,0,0,64,0,0,0,64,8,6,0,0,0,170,105,113, 56 | 222,0,0,1,41,73,68,65,84,120,1,237,155,129,134,131, 57 | 65,12,132,251,186,121,190,121,191,117,135,248,225,252,87,205, 58 | 68,117,244,251,8,160,77,102,42,75,119,147,7,192,45,213, 59 | 145,174,65,19,29,250,141,211,161,96,241,103,162,163,197,255, 60 | 137,202,21,127,133,6,226,227,76,168,39,26,244,252,131,190, 61 | 9,50,218,199,249,46,57,26,206,11,161,23,138,176,24,228, 62 | 29,215,127,22,76,208,114,219,212,93,222,253,218,59,217,32, 63 | 202,56,60,141,195,204,168,185,217,52,65,195,118,113,122,90, 64 | 142,248,117,19,222,105,128,17,229,39,206,53,160,252,228,190, 65 | 1,113,53,36,27,96,228,223,55,33,49,247,69,5,27,176, 66 | 70,5,26,80,24,176,132,130,91,64,190,248,252,67,80,150, 67 | 248,116,3,58,100,244,124,190,1,29,133,1,195,27,85,189, 68 | 59,241,226,15,161,142,122,44,81,131,8,200,9,0,0,0, 69 | 0,0,0,252,27,228,62,128,27,33,12,224,86,152,119,1, 70 | 94,134,46,120,27,196,128,216,22,240,77,96,66,68,27,69, 71 | 4,206,8,49,37,86,209,115,130,70,29,76,138,102,207,10, 72 | 251,38,124,245,180,248,196,209,79,217,23,208,134,9,250,162, 73 | 141,145,227,28,126,250,148,157,33,67,67,177,53,198,222,224, 74 | 255,40,88,252,157,14,237,239,221,178,3,157,207,15,147,169, 75 | 144,103,161,55,38,80,0,0,0,0,73,69,78,68,174,66, 76 | 96,130, }); 77 | 78 | KeepScrollToLast = I(new byte[] { 79 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 80 | 0,0,0,64,0,0,0,64,2,3,0,0,0,215,7,153, 81 | 77,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97, 82 | 5,0,0,0,1,115,82,71,66,0,174,206,28,233,0,0, 83 | 0,12,80,76,84,69,0,0,0,0,0,0,0,0,0,0, 84 | 0,0,53,233,55,150,0,0,0,4,116,82,78,83,250,4, 85 | 67,176,77,116,151,207,0,0,0,190,73,68,65,84,56,203, 86 | 237,211,177,13,194,48,16,5,208,47,83,165,176,88,129,198, 87 | 35,208,51,2,13,88,66,46,188,65,60,2,35,208,100,8, 88 | 152,194,203,48,6,18,231,220,119,148,184,65,74,1,13,87, 89 | 157,158,206,95,246,73,198,169,41,124,21,206,207,6,66,215, 90 | 192,209,54,16,255,240,107,232,7,194,139,112,112,10,126,67, 91 | 184,118,10,1,21,140,66,170,19,9,195,8,217,16,2,92, 92 | 1,143,142,80,58,129,226,188,135,204,10,148,147,4,105,5, 93 | 198,8,5,25,142,86,35,20,164,143,86,35,248,150,108,162, 94 | 213,8,66,194,205,106,4,33,96,183,213,8,130,135,148,155, 95 | 239,35,11,12,115,72,128,89,108,44,128,17,21,124,141,152, 96 | 118,154,25,49,65,50,159,126,131,223,87,8,88,148,89,3, 97 | 151,199,162,238,43,62,242,27,205,141,50,53,143,180,207,13, 98 | 0,0,0,0,73,69,78,68,174,66,96,130,}); 99 | 100 | ShowTime = I(new byte[] { 101 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 102 | 0,0,0,39,0,0,0,64,8,3,0,0,0,174,140,158, 103 | 229,0,0,0,12,80,76,84,69,0,0,0,31,25,14,171, 104 | 150,107,0,0,0,180,225,168,244,0,0,0,4,116,82,78, 105 | 83,0,165,249,1,222,89,147,115,0,0,0,201,73,68,65, 106 | 84,120,218,237,213,65,10,195,48,12,5,81,143,116,255,59, 107 | 183,5,17,89,253,182,234,64,151,153,93,194,195,94,72,36, 108 | 227,105,157,159,117,211,209,84,156,25,246,142,82,188,73,135, 109 | 237,43,142,67,119,21,87,207,206,103,151,86,170,110,87,113, 110 | 126,236,232,217,125,215,176,112,13,164,117,202,210,249,247,120, 111 | 131,137,211,25,7,19,135,56,87,23,80,153,58,103,150,116, 112 | 123,15,194,196,133,76,38,78,33,7,142,56,78,157,30,232, 113 | 103,142,255,58,135,223,14,112,129,234,192,141,208,197,9,251, 114 | 56,133,67,247,210,136,7,117,201,194,9,28,194,194,5,84, 115 | 7,215,56,18,170,131,121,249,123,39,107,10,233,146,89,169, 116 | 194,81,24,69,178,114,216,34,253,190,216,58,196,237,42,14, 117 | 182,76,28,171,206,239,21,199,153,219,5,183,255,131,61,244, 118 | 116,109,143,235,122,1,69,230,21,226,8,201,75,24,0,0, 119 | 0,0,73,69,78,68,174,66,96,130, }); 120 | 121 | ShowTime = I(new byte[] { 122 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 123 | 0,0,0,39,0,0,0,64,8,3,0,0,0,174,140,158, 124 | 229,0,0,0,12,80,76,84,69,0,0,0,31,25,14,171, 125 | 150,107,0,0,0,180,225,168,244,0,0,0,4,116,82,78, 126 | 83,0,165,249,1,222,89,147,115,0,0,0,201,73,68,65, 127 | 84,120,218,237,213,65,10,195,48,12,5,81,143,116,255,59, 128 | 183,5,17,89,253,182,234,64,151,153,93,194,195,94,72,36, 129 | 227,105,157,159,117,211,209,84,156,25,246,142,82,188,73,135, 130 | 237,43,142,67,119,21,87,207,206,103,151,86,170,110,87,113, 131 | 126,236,232,217,125,215,176,112,13,164,117,202,210,249,247,120, 132 | 131,137,211,25,7,19,135,56,87,23,80,153,58,103,150,116, 133 | 123,15,194,196,133,76,38,78,33,7,142,56,78,157,30,232, 134 | 103,142,255,58,135,223,14,112,129,234,192,141,208,197,9,251, 135 | 56,133,67,247,210,136,7,117,201,194,9,28,194,194,5,84, 136 | 7,215,56,18,170,131,121,249,123,39,107,10,233,146,89,169, 137 | 194,81,24,69,178,114,216,34,253,190,216,58,196,237,42,14, 138 | 182,76,28,171,206,239,21,199,153,219,5,183,255,131,61,244, 139 | 116,109,143,235,122,1,69,230,21,226,8,201,75,24,0,0, 140 | 0,0,73,69,78,68,174,66,96,130, }); 141 | 142 | ShowScene = I(new byte[] { 143 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 144 | 0,0,0,64,0,0,0,64,8,3,0,0,0,157,183,129, 145 | 236,0,0,0,12,80,76,84,69,0,0,0,255,255,255,46, 146 | 45,46,250,250,250,135,169,196,198,0,0,0,4,116,82,78, 147 | 83,0,2,253,250,76,109,54,6,0,0,0,215,73,68,65, 148 | 84,120,218,237,214,49,14,131,64,12,68,209,172,125,255,59, 149 | 39,221,47,70,214,200,131,18,161,8,119,20,255,137,13,203, 150 | 146,215,51,255,49,231,218,236,128,250,76,0,16,7,0,113, 151 | 6,16,51,2,248,58,7,42,7,232,117,50,160,3,160,168, 152 | 187,3,128,152,222,0,164,196,244,172,195,1,212,75,192,247, 153 | 6,144,94,129,54,128,237,185,5,128,77,239,129,114,64,43, 154 | 176,232,185,24,0,250,0,176,189,7,200,91,1,46,199,223, 155 | 160,166,81,160,5,240,61,51,108,164,90,0,231,43,64,95, 156 | 93,2,130,80,246,41,136,48,236,3,3,32,132,27,201,11, 157 | 30,64,48,128,46,1,33,58,15,188,224,1,21,210,35,13, 158 | 33,61,84,17,130,99,221,10,6,16,161,150,0,51,60,255, 159 | 95,126,222,245,21,15,128,252,47,14,99,122,15,116,231,0, 160 | 70,123,96,101,156,45,0,146,3,32,49,0,114,50,128,121, 161 | 128,59,2,111,125,28,21,227,56,21,91,243,0,0,0,0, 162 | 73,69,78,68,174,66,96,130, }); 163 | 164 | Log = I(new byte[] { 165 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 166 | 0,0,0,64,0,0,0,64,8,3,0,0,0,157,183,129, 167 | 236,0,0,0,12,80,76,84,69,173,173,173,191,191,191,247, 168 | 247,247,102,102,102,201,215,52,108,0,0,0,3,116,82,78, 169 | 83,6,186,254,186,212,33,69,0,0,0,220,73,68,65,84, 170 | 120,218,237,214,65,14,131,48,16,67,81,190,185,255,157,43, 171 | 85,173,188,32,196,195,100,209,170,197,75,36,191,68,128,38, 172 | 217,238,124,111,0,36,7,160,89,55,209,44,95,222,7,104, 173 | 146,4,224,122,139,0,229,192,165,58,67,130,50,0,227,167, 174 | 213,250,254,204,132,200,0,101,64,131,236,175,232,152,3,64, 175 | 0,146,32,93,6,88,4,196,240,5,230,175,224,64,17,160, 176 | 0,72,19,1,69,64,139,0,61,64,5,64,83,64,239,126, 177 | 0,116,3,127,1,108,93,128,2,64,6,44,228,228,121,176, 178 | 14,228,131,37,143,180,252,14,12,56,132,153,24,167,50,156, 179 | 0,48,6,56,0,156,1,212,142,54,224,108,7,16,214,183, 180 | 80,253,19,93,15,66,6,178,160,92,207,66,253,170,7,160, 181 | 213,107,30,196,213,219,134,219,89,0,145,46,37,217,48,229, 182 | 13,180,136,8,100,200,64,155,48,208,137,129,5,1,3,93, 183 | 227,115,128,137,237,55,243,0,128,139,17,99,93,98,191,161, 184 | 0,0,0,0,73,69,78,68,174,66,96,130, }); 185 | 186 | Warning = I(new byte[] { 187 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 188 | 0,0,0,64,0,0,0,64,2,3,0,0,0,215,7,153, 189 | 77,0,0,0,12,80,76,84,69,0,0,0,1,1,0,35, 190 | 33,6,242,213,42,39,126,82,137,0,0,0,3,116,82,78, 191 | 83,3,152,248,242,206,0,187,0,0,1,17,73,68,65,84, 192 | 120,94,141,208,177,145,131,48,20,132,97,57,128,224,74,160, 193 | 26,74,32,56,7,86,9,84,67,9,4,38,240,18,168,4, 194 | 245,67,66,174,224,246,24,107,7,235,137,224,238,69,204,55, 195 | 48,255,44,238,223,215,12,53,124,87,224,81,193,88,195,154, 196 | 6,3,183,144,38,3,109,72,179,129,175,240,243,52,208,69, 197 | 46,182,74,190,12,128,220,250,10,76,183,9,7,76,53,204, 198 | 166,74,154,110,119,0,23,91,37,81,110,37,119,3,224,134, 199 | 178,123,91,9,3,109,32,16,213,85,21,8,233,89,110,5, 200 | 212,85,149,64,44,246,130,4,72,88,136,250,1,154,6,104, 201 | 239,7,162,246,106,235,134,98,111,167,79,206,174,103,126,227, 202 | 236,142,130,179,11,1,83,175,173,36,211,27,6,109,61,223, 203 | 152,207,42,147,64,91,5,234,122,86,128,15,224,2,125,158, 204 | 166,83,215,192,148,171,58,117,187,12,59,169,31,224,169,10, 205 | 181,119,36,53,78,93,61,33,190,189,63,182,10,130,186,109, 206 | 16,168,171,42,55,80,93,31,115,37,127,201,69,85,50,80, 207 | 0,154,195,21,86,11,219,245,141,17,230,94,206,91,88,92, 208 | 243,184,23,247,24,92,115,55,55,184,63,239,23,4,183,220, 209 | 203,15,239,123,5,0,0,0,0,73,69,78,68,174,66,96, 210 | 130, }); 211 | 212 | Error = I(new byte[] { 213 | 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82, 214 | 0,0,0,64,0,0,0,64,2,3,0,0,0,215,7,153, 215 | 77,0,0,0,12,80,76,84,69,65,20,20,216,68,68,202, 216 | 23,23,248,218,218,21,114,9,223,0,0,0,3,116,82,78, 217 | 83,21,245,254,211,85,111,166,0,0,1,20,73,68,65,84, 218 | 120,1,157,146,1,102,196,64,20,134,39,232,1,138,66,79, 219 | 179,71,40,76,150,7,91,200,144,0,80,0,189,66,96,177, 220 | 3,10,243,120,57,82,47,82,10,233,251,155,190,153,120,91, 221 | 172,253,4,241,249,255,127,6,19,238,229,41,130,67,48,186, 222 | 229,151,23,47,230,42,158,55,81,188,16,215,192,136,19,115, 223 | 107,216,136,19,226,26,24,113,98,182,134,81,188,16,215,192, 224 | 136,19,179,53,140,226,5,70,182,191,227,27,45,160,138,211, 225 | 186,137,131,109,190,175,159,155,176,196,234,196,127,137,239,219, 226 | 55,228,42,113,17,225,93,162,19,206,25,9,106,9,78,105, 227 | 218,9,145,156,71,187,186,32,145,120,100,136,182,49,182,4, 228 | 107,130,179,142,76,42,56,233,150,138,194,131,16,157,214,41, 229 | 107,242,2,145,207,169,135,16,22,198,70,137,20,11,157,163, 230 | 212,68,236,227,160,130,146,109,68,101,57,126,17,40,38,112, 231 | 10,24,176,1,65,42,236,105,14,94,60,236,5,133,63,209, 232 | 227,107,2,148,8,62,130,18,1,45,78,128,173,81,59,94, 233 | 88,3,92,9,215,216,117,122,39,172,209,58,175,78,88,163, 234 | 118,200,139,57,84,108,211,69,66,163,123,4,225,54,126,0, 235 | 73,15,115,11,158,123,107,90,0,0,0,0,73,69,78,68, 236 | 174,66,96,130, }); 237 | } 238 | 239 | public static GUIContent ForLogType(LogType logType) 240 | { 241 | switch (logType) 242 | { 243 | case LogType.Log: return Icons.Log; 244 | case LogType.Warning: return Icons.Warning; 245 | default: return Icons.Error; 246 | } 247 | } 248 | } 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /example/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 14 7 | productGUID: aade1629939f54e7ea0d261ed2f36ab2 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | defaultScreenOrientation: 4 11 | targetDevice: 2 12 | useOnDemandResources: 0 13 | accelerometerFrequency: 60 14 | companyName: DefaultCompany 15 | productName: UnitySettings-Example 16 | defaultCursor: {fileID: 0} 17 | cursorHotspot: {x: 0, y: 0} 18 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 19 | m_ShowUnitySplashScreen: 0 20 | m_ShowUnitySplashLogo: 1 21 | m_SplashScreenOverlayOpacity: 1 22 | m_SplashScreenAnimation: 1 23 | m_SplashScreenLogoStyle: 1 24 | m_SplashScreenDrawMode: 0 25 | m_SplashScreenBackgroundAnimationZoom: 1 26 | m_SplashScreenLogoAnimationZoom: 1 27 | m_SplashScreenBackgroundLandscapeAspect: 1 28 | m_SplashScreenBackgroundPortraitAspect: 1 29 | m_SplashScreenBackgroundLandscapeUvs: 30 | serializedVersion: 2 31 | x: 0 32 | y: 0 33 | width: 1 34 | height: 1 35 | m_SplashScreenBackgroundPortraitUvs: 36 | serializedVersion: 2 37 | x: 0 38 | y: 0 39 | width: 1 40 | height: 1 41 | m_SplashScreenLogos: [] 42 | m_VirtualRealitySplashScreen: {fileID: 0} 43 | m_HolographicTrackingLossScreen: {fileID: 0} 44 | defaultScreenWidth: 1024 45 | defaultScreenHeight: 768 46 | defaultScreenWidthWeb: 960 47 | defaultScreenHeightWeb: 600 48 | m_StereoRenderingPath: 0 49 | m_ActiveColorSpace: 0 50 | m_MTRendering: 1 51 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 52 | iosShowActivityIndicatorOnLoading: -1 53 | androidShowActivityIndicatorOnLoading: -1 54 | tizenShowActivityIndicatorOnLoading: -1 55 | iosAppInBackgroundBehavior: 0 56 | displayResolutionDialog: 1 57 | iosAllowHTTPDownload: 1 58 | allowedAutorotateToPortrait: 1 59 | allowedAutorotateToPortraitUpsideDown: 1 60 | allowedAutorotateToLandscapeRight: 1 61 | allowedAutorotateToLandscapeLeft: 1 62 | useOSAutorotation: 1 63 | use32BitDisplayBuffer: 1 64 | preserveFramebufferAlpha: 0 65 | disableDepthAndStencilBuffers: 0 66 | androidBlitType: 0 67 | defaultIsFullScreen: 1 68 | defaultIsNativeResolution: 1 69 | macRetinaSupport: 1 70 | runInBackground: 0 71 | captureSingleScreen: 0 72 | muteOtherAudioSources: 0 73 | Prepare IOS For Recording: 0 74 | Force IOS Speakers When Recording: 0 75 | deferSystemGesturesMode: 0 76 | hideHomeButton: 0 77 | submitAnalytics: 1 78 | usePlayerLog: 1 79 | bakeCollisionMeshes: 0 80 | forceSingleInstance: 0 81 | resizableWindow: 0 82 | useMacAppStoreValidation: 0 83 | macAppStoreCategory: public.app-category.games 84 | gpuSkinning: 0 85 | graphicsJobs: 0 86 | xboxPIXTextureCapture: 0 87 | xboxEnableAvatar: 0 88 | xboxEnableKinect: 0 89 | xboxEnableKinectAutoTracking: 0 90 | xboxEnableFitness: 0 91 | visibleInBackground: 0 92 | allowFullscreenSwitch: 1 93 | graphicsJobMode: 0 94 | macFullscreenMode: 2 95 | d3d11FullscreenMode: 1 96 | xboxSpeechDB: 0 97 | xboxEnableHeadOrientation: 0 98 | xboxEnableGuest: 0 99 | xboxEnablePIXSampling: 0 100 | metalFramebufferOnly: 0 101 | n3dsDisableStereoscopicView: 0 102 | n3dsEnableSharedListOpt: 1 103 | n3dsEnableVSync: 0 104 | xboxOneResolution: 0 105 | xboxOneSResolution: 0 106 | xboxOneXResolution: 3 107 | xboxOneMonoLoggingLevel: 0 108 | xboxOneLoggingLevel: 1 109 | xboxOneDisableEsram: 0 110 | xboxOnePresentImmediateThreshold: 0 111 | videoMemoryForVertexBuffers: 0 112 | psp2PowerMode: 0 113 | psp2AcquireBGM: 1 114 | wiiUTVResolution: 0 115 | wiiUGamePadMSAA: 1 116 | wiiUSupportsNunchuk: 0 117 | wiiUSupportsClassicController: 0 118 | wiiUSupportsBalanceBoard: 0 119 | wiiUSupportsMotionPlus: 0 120 | wiiUSupportsProController: 0 121 | wiiUAllowScreenCapture: 1 122 | wiiUControllerCount: 0 123 | m_SupportedAspectRatios: 124 | 4:3: 1 125 | 5:4: 1 126 | 16:10: 1 127 | 16:9: 1 128 | Others: 1 129 | bundleVersion: 1.0 130 | preloadedAssets: [] 131 | metroInputSource: 0 132 | wsaTransparentSwapchain: 0 133 | m_HolographicPauseOnTrackingLoss: 1 134 | xboxOneDisableKinectGpuReservation: 0 135 | xboxOneEnable7thCore: 0 136 | vrSettings: 137 | cardboard: 138 | depthFormat: 0 139 | enableTransitionView: 0 140 | daydream: 141 | depthFormat: 0 142 | useSustainedPerformanceMode: 0 143 | enableVideoLayer: 0 144 | useProtectedVideoMemory: 0 145 | minimumSupportedHeadTracking: 0 146 | maximumSupportedHeadTracking: 1 147 | hololens: 148 | depthFormat: 1 149 | depthBufferSharingEnabled: 0 150 | oculus: 151 | sharedDepthBuffer: 0 152 | dashSupport: 0 153 | protectGraphicsMemory: 0 154 | useHDRDisplay: 0 155 | m_ColorGamuts: 00000000 156 | targetPixelDensity: 30 157 | resolutionScalingMode: 0 158 | androidSupportedAspectRatio: 1 159 | androidMaxAspectRatio: 2.1 160 | applicationIdentifier: 161 | Android: com.devsisters.UnitySettings 162 | Standalone: unity.DefaultCompany.UnitySettings-Example 163 | Tizen: com.devsisters.UnitySettings 164 | iOS: com.devsisters.UnitySettings 165 | tvOS: com.devsisters.UnitySettings 166 | buildNumber: 167 | iOS: 0 168 | AndroidBundleVersionCode: 1 169 | AndroidMinSdkVersion: 16 170 | AndroidTargetSdkVersion: 0 171 | AndroidPreferredInstallLocation: 1 172 | aotOptions: 173 | stripEngineCode: 1 174 | iPhoneStrippingLevel: 0 175 | iPhoneScriptCallOptimization: 0 176 | ForceInternetPermission: 0 177 | ForceSDCardPermission: 0 178 | CreateWallpaper: 0 179 | APKExpansionFiles: 0 180 | keepLoadedShadersAlive: 0 181 | StripUnusedMeshComponents: 0 182 | VertexChannelCompressionMask: 183 | serializedVersion: 2 184 | m_Bits: 238 185 | iPhoneSdkVersion: 988 186 | iOSTargetOSVersionString: 7.0 187 | tvOSSdkVersion: 0 188 | tvOSRequireExtendedGameController: 0 189 | tvOSTargetOSVersionString: 9.0 190 | uIPrerenderedIcon: 0 191 | uIRequiresPersistentWiFi: 0 192 | uIRequiresFullScreen: 1 193 | uIStatusBarHidden: 1 194 | uIExitOnSuspend: 0 195 | uIStatusBarStyle: 0 196 | iPhoneSplashScreen: {fileID: 0} 197 | iPhoneHighResSplashScreen: {fileID: 0} 198 | iPhoneTallHighResSplashScreen: {fileID: 0} 199 | iPhone47inSplashScreen: {fileID: 0} 200 | iPhone55inPortraitSplashScreen: {fileID: 0} 201 | iPhone55inLandscapeSplashScreen: {fileID: 0} 202 | iPhone58inPortraitSplashScreen: {fileID: 0} 203 | iPhone58inLandscapeSplashScreen: {fileID: 0} 204 | iPadPortraitSplashScreen: {fileID: 0} 205 | iPadHighResPortraitSplashScreen: {fileID: 0} 206 | iPadLandscapeSplashScreen: {fileID: 0} 207 | iPadHighResLandscapeSplashScreen: {fileID: 0} 208 | appleTVSplashScreen: {fileID: 0} 209 | appleTVSplashScreen2x: {fileID: 0} 210 | tvOSSmallIconLayers: [] 211 | tvOSSmallIconLayers2x: [] 212 | tvOSLargeIconLayers: [] 213 | tvOSLargeIconLayers2x: [] 214 | tvOSTopShelfImageLayers: [] 215 | tvOSTopShelfImageLayers2x: [] 216 | tvOSTopShelfImageWideLayers: [] 217 | tvOSTopShelfImageWideLayers2x: [] 218 | iOSLaunchScreenType: 0 219 | iOSLaunchScreenPortrait: {fileID: 0} 220 | iOSLaunchScreenLandscape: {fileID: 0} 221 | iOSLaunchScreenBackgroundColor: 222 | serializedVersion: 2 223 | rgba: 0 224 | iOSLaunchScreenFillPct: 100 225 | iOSLaunchScreenSize: 100 226 | iOSLaunchScreenCustomXibPath: 227 | iOSLaunchScreeniPadType: 0 228 | iOSLaunchScreeniPadImage: {fileID: 0} 229 | iOSLaunchScreeniPadBackgroundColor: 230 | serializedVersion: 2 231 | rgba: 0 232 | iOSLaunchScreeniPadFillPct: 100 233 | iOSLaunchScreeniPadSize: 100 234 | iOSLaunchScreeniPadCustomXibPath: 235 | iOSUseLaunchScreenStoryboard: 0 236 | iOSLaunchScreenCustomStoryboardPath: 237 | iOSDeviceRequirements: [] 238 | iOSURLSchemes: [] 239 | iOSBackgroundModes: 0 240 | iOSMetalForceHardShadows: 0 241 | metalEditorSupport: 0 242 | metalAPIValidation: 1 243 | iOSRenderExtraFrameOnPause: 1 244 | appleDeveloperTeamID: 245 | iOSManualSigningProvisioningProfileID: 246 | tvOSManualSigningProvisioningProfileID: 247 | appleEnableAutomaticSigning: 0 248 | clonedFromGUID: 00000000000000000000000000000000 249 | AndroidTargetDevice: 3 250 | AndroidSplashScreenScale: 0 251 | androidSplashScreen: {fileID: 0} 252 | AndroidKeystoreName: 253 | AndroidKeyaliasName: 254 | AndroidTVCompatibility: 1 255 | AndroidIsGame: 1 256 | AndroidEnableTango: 0 257 | androidEnableBanner: 1 258 | androidUseLowAccuracyLocation: 0 259 | m_AndroidBanners: 260 | - width: 320 261 | height: 180 262 | banner: {fileID: 0} 263 | androidGamepadSupportLevel: 0 264 | resolutionDialogBanner: {fileID: 0} 265 | m_BuildTargetIcons: [] 266 | m_BuildTargetBatching: [] 267 | m_BuildTargetGraphicsAPIs: [] 268 | m_BuildTargetVRSettings: [] 269 | m_BuildTargetEnableVuforiaSettings: [] 270 | openGLRequireES31: 0 271 | openGLRequireES31AEP: 0 272 | m_TemplateCustomTags: {} 273 | mobileMTRendering: 274 | iPhone: 1 275 | tvOS: 1 276 | m_BuildTargetGroupLightmapEncodingQuality: 277 | - m_BuildTarget: Standalone 278 | m_EncodingQuality: 1 279 | - m_BuildTarget: XboxOne 280 | m_EncodingQuality: 1 281 | - m_BuildTarget: PS4 282 | m_EncodingQuality: 1 283 | wiiUTitleID: 0005000011000000 284 | wiiUGroupID: 00010000 285 | wiiUCommonSaveSize: 4096 286 | wiiUAccountSaveSize: 2048 287 | wiiUOlvAccessKey: 0 288 | wiiUTinCode: 0 289 | wiiUJoinGameId: 0 290 | wiiUJoinGameModeMask: 0000000000000000 291 | wiiUCommonBossSize: 0 292 | wiiUAccountBossSize: 0 293 | wiiUAddOnUniqueIDs: [] 294 | wiiUMainThreadStackSize: 3072 295 | wiiULoaderThreadStackSize: 1024 296 | wiiUSystemHeapSize: 128 297 | wiiUTVStartupScreen: {fileID: 0} 298 | wiiUGamePadStartupScreen: {fileID: 0} 299 | wiiUDrcBufferDisabled: 0 300 | wiiUProfilerLibPath: 301 | playModeTestRunnerEnabled: 0 302 | actionOnDotNetUnhandledException: 1 303 | enableInternalProfiler: 0 304 | logObjCUncaughtExceptions: 1 305 | enableCrashReportAPI: 0 306 | cameraUsageDescription: 307 | locationUsageDescription: 308 | microphoneUsageDescription: 309 | switchNetLibKey: 310 | switchSocketMemoryPoolSize: 6144 311 | switchSocketAllocatorPoolSize: 128 312 | switchSocketConcurrencyLimit: 14 313 | switchScreenResolutionBehavior: 2 314 | switchUseCPUProfiler: 0 315 | switchApplicationID: 0x01004b9000490000 316 | switchNSODependencies: 317 | switchTitleNames_0: 318 | switchTitleNames_1: 319 | switchTitleNames_2: 320 | switchTitleNames_3: 321 | switchTitleNames_4: 322 | switchTitleNames_5: 323 | switchTitleNames_6: 324 | switchTitleNames_7: 325 | switchTitleNames_8: 326 | switchTitleNames_9: 327 | switchTitleNames_10: 328 | switchTitleNames_11: 329 | switchTitleNames_12: 330 | switchTitleNames_13: 331 | switchTitleNames_14: 332 | switchPublisherNames_0: 333 | switchPublisherNames_1: 334 | switchPublisherNames_2: 335 | switchPublisherNames_3: 336 | switchPublisherNames_4: 337 | switchPublisherNames_5: 338 | switchPublisherNames_6: 339 | switchPublisherNames_7: 340 | switchPublisherNames_8: 341 | switchPublisherNames_9: 342 | switchPublisherNames_10: 343 | switchPublisherNames_11: 344 | switchPublisherNames_12: 345 | switchPublisherNames_13: 346 | switchPublisherNames_14: 347 | switchIcons_0: {fileID: 0} 348 | switchIcons_1: {fileID: 0} 349 | switchIcons_2: {fileID: 0} 350 | switchIcons_3: {fileID: 0} 351 | switchIcons_4: {fileID: 0} 352 | switchIcons_5: {fileID: 0} 353 | switchIcons_6: {fileID: 0} 354 | switchIcons_7: {fileID: 0} 355 | switchIcons_8: {fileID: 0} 356 | switchIcons_9: {fileID: 0} 357 | switchIcons_10: {fileID: 0} 358 | switchIcons_11: {fileID: 0} 359 | switchIcons_12: {fileID: 0} 360 | switchIcons_13: {fileID: 0} 361 | switchIcons_14: {fileID: 0} 362 | switchSmallIcons_0: {fileID: 0} 363 | switchSmallIcons_1: {fileID: 0} 364 | switchSmallIcons_2: {fileID: 0} 365 | switchSmallIcons_3: {fileID: 0} 366 | switchSmallIcons_4: {fileID: 0} 367 | switchSmallIcons_5: {fileID: 0} 368 | switchSmallIcons_6: {fileID: 0} 369 | switchSmallIcons_7: {fileID: 0} 370 | switchSmallIcons_8: {fileID: 0} 371 | switchSmallIcons_9: {fileID: 0} 372 | switchSmallIcons_10: {fileID: 0} 373 | switchSmallIcons_11: {fileID: 0} 374 | switchSmallIcons_12: {fileID: 0} 375 | switchSmallIcons_13: {fileID: 0} 376 | switchSmallIcons_14: {fileID: 0} 377 | switchManualHTML: 378 | switchAccessibleURLs: 379 | switchLegalInformation: 380 | switchMainThreadStackSize: 1048576 381 | switchPresenceGroupId: 382 | switchLogoHandling: 0 383 | switchReleaseVersion: 0 384 | switchDisplayVersion: 1.0.0 385 | switchStartupUserAccount: 0 386 | switchTouchScreenUsage: 0 387 | switchSupportedLanguagesMask: 0 388 | switchLogoType: 0 389 | switchApplicationErrorCodeCategory: 390 | switchUserAccountSaveDataSize: 0 391 | switchUserAccountSaveDataJournalSize: 0 392 | switchApplicationAttribute: 0 393 | switchCardSpecSize: -1 394 | switchCardSpecClock: -1 395 | switchRatingsMask: 0 396 | switchRatingsInt_0: 0 397 | switchRatingsInt_1: 0 398 | switchRatingsInt_2: 0 399 | switchRatingsInt_3: 0 400 | switchRatingsInt_4: 0 401 | switchRatingsInt_5: 0 402 | switchRatingsInt_6: 0 403 | switchRatingsInt_7: 0 404 | switchRatingsInt_8: 0 405 | switchRatingsInt_9: 0 406 | switchRatingsInt_10: 0 407 | switchRatingsInt_11: 0 408 | switchLocalCommunicationIds_0: 409 | switchLocalCommunicationIds_1: 410 | switchLocalCommunicationIds_2: 411 | switchLocalCommunicationIds_3: 412 | switchLocalCommunicationIds_4: 413 | switchLocalCommunicationIds_5: 414 | switchLocalCommunicationIds_6: 415 | switchLocalCommunicationIds_7: 416 | switchParentalControl: 0 417 | switchAllowsScreenshot: 1 418 | switchAllowsVideoCapturing: 1 419 | switchAllowsRuntimeAddOnContentInstall: 0 420 | switchDataLossConfirmation: 0 421 | switchSupportedNpadStyles: 3 422 | switchSocketConfigEnabled: 0 423 | switchTcpInitialSendBufferSize: 32 424 | switchTcpInitialReceiveBufferSize: 64 425 | switchTcpAutoSendBufferSizeMax: 256 426 | switchTcpAutoReceiveBufferSizeMax: 256 427 | switchUdpSendBufferSize: 9 428 | switchUdpReceiveBufferSize: 42 429 | switchSocketBufferEfficiency: 4 430 | switchSocketInitializeEnabled: 1 431 | switchNetworkInterfaceManagerInitializeEnabled: 1 432 | switchPlayerConnectionEnabled: 1 433 | ps4NPAgeRating: 12 434 | ps4NPTitleSecret: 435 | ps4NPTrophyPackPath: 436 | ps4ParentalLevel: 1 437 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 438 | ps4Category: 0 439 | ps4MasterVersion: 01.00 440 | ps4AppVersion: 01.00 441 | ps4AppType: 0 442 | ps4ParamSfxPath: 443 | ps4VideoOutPixelFormat: 0 444 | ps4VideoOutInitialWidth: 1920 445 | ps4VideoOutBaseModeInitialWidth: 1920 446 | ps4VideoOutReprojectionRate: 120 447 | ps4PronunciationXMLPath: 448 | ps4PronunciationSIGPath: 449 | ps4BackgroundImagePath: 450 | ps4StartupImagePath: 451 | ps4StartupImagesFolder: 452 | ps4IconImagesFolder: 453 | ps4SaveDataImagePath: 454 | ps4SdkOverride: 455 | ps4BGMPath: 456 | ps4ShareFilePath: 457 | ps4ShareOverlayImagePath: 458 | ps4PrivacyGuardImagePath: 459 | ps4NPtitleDatPath: 460 | ps4RemotePlayKeyAssignment: -1 461 | ps4RemotePlayKeyMappingDir: 462 | ps4PlayTogetherPlayerCount: 0 463 | ps4EnterButtonAssignment: 1 464 | ps4ApplicationParam1: 0 465 | ps4ApplicationParam2: 0 466 | ps4ApplicationParam3: 0 467 | ps4ApplicationParam4: 0 468 | ps4DownloadDataSize: 0 469 | ps4GarlicHeapSize: 2048 470 | ps4ProGarlicHeapSize: 2560 471 | ps4Passcode: N2qmWqBlQ9wQj99nsQzldVI5ZuGXbEWR 472 | ps4pnSessions: 1 473 | ps4pnPresence: 1 474 | ps4pnFriends: 1 475 | ps4pnGameCustomData: 1 476 | playerPrefsSupport: 0 477 | restrictedAudioUsageRights: 0 478 | ps4UseResolutionFallback: 0 479 | ps4ReprojectionSupport: 0 480 | ps4UseAudio3dBackend: 0 481 | ps4SocialScreenEnabled: 0 482 | ps4ScriptOptimizationLevel: 3 483 | ps4Audio3dVirtualSpeakerCount: 14 484 | ps4attribCpuUsage: 0 485 | ps4PatchPkgPath: 486 | ps4PatchLatestPkgPath: 487 | ps4PatchChangeinfoPath: 488 | ps4PatchDayOne: 0 489 | ps4attribUserManagement: 0 490 | ps4attribMoveSupport: 0 491 | ps4attrib3DSupport: 0 492 | ps4attribShareSupport: 0 493 | ps4attribExclusiveVR: 0 494 | ps4disableAutoHideSplash: 0 495 | ps4videoRecordingFeaturesUsed: 0 496 | ps4contentSearchFeaturesUsed: 0 497 | ps4attribEyeToEyeDistanceSettingVR: 0 498 | ps4IncludedModules: [] 499 | monoEnv: 500 | psp2Splashimage: {fileID: 0} 501 | psp2NPTrophyPackPath: 502 | psp2NPSupportGBMorGJP: 0 503 | psp2NPAgeRating: 12 504 | psp2NPTitleDatPath: 505 | psp2NPCommsID: 506 | psp2NPCommunicationsID: 507 | psp2NPCommsPassphrase: 508 | psp2NPCommsSig: 509 | psp2ParamSfxPath: 510 | psp2ManualPath: 511 | psp2LiveAreaGatePath: 512 | psp2LiveAreaBackroundPath: 513 | psp2LiveAreaPath: 514 | psp2LiveAreaTrialPath: 515 | psp2PatchChangeInfoPath: 516 | psp2PatchOriginalPackage: 517 | psp2PackagePassword: K5RhRXdCdG5nG5azdNMK66MuCV6GXi5x 518 | psp2KeystoneFile: 519 | psp2MemoryExpansionMode: 0 520 | psp2DRMType: 0 521 | psp2StorageType: 0 522 | psp2MediaCapacity: 0 523 | psp2DLCConfigPath: 524 | psp2ThumbnailPath: 525 | psp2BackgroundPath: 526 | psp2SoundPath: 527 | psp2TrophyCommId: 528 | psp2TrophyPackagePath: 529 | psp2PackagedResourcesPath: 530 | psp2SaveDataQuota: 10240 531 | psp2ParentalLevel: 1 532 | psp2ShortTitle: Not Set 533 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 534 | psp2Category: 0 535 | psp2MasterVersion: 01.00 536 | psp2AppVersion: 01.00 537 | psp2TVBootMode: 0 538 | psp2EnterButtonAssignment: 2 539 | psp2TVDisableEmu: 0 540 | psp2AllowTwitterDialog: 1 541 | psp2Upgradable: 0 542 | psp2HealthWarning: 0 543 | psp2UseLibLocation: 0 544 | psp2InfoBarOnStartup: 0 545 | psp2InfoBarColor: 0 546 | psp2ScriptOptimizationLevel: 0 547 | psmSplashimage: {fileID: 0} 548 | splashScreenBackgroundSourceLandscape: {fileID: 0} 549 | splashScreenBackgroundSourcePortrait: {fileID: 0} 550 | spritePackerPolicy: 551 | webGLMemorySize: 256 552 | webGLExceptionSupport: 1 553 | webGLNameFilesAsHashes: 0 554 | webGLDataCaching: 0 555 | webGLDebugSymbols: 0 556 | webGLEmscriptenArgs: 557 | webGLModulesDirectory: 558 | webGLTemplate: APPLICATION:Default 559 | webGLAnalyzeBuildSize: 0 560 | webGLUseEmbeddedResources: 0 561 | webGLUseWasm: 0 562 | webGLCompressionFormat: 1 563 | scriptingDefineSymbols: {} 564 | platformArchitecture: {} 565 | scriptingBackend: {} 566 | incrementalIl2cppBuild: {} 567 | additionalIl2CppArgs: 568 | scriptingRuntimeVersion: 1 569 | apiCompatibilityLevelPerPlatform: {} 570 | m_RenderingPath: 1 571 | m_MobileRenderingPath: 1 572 | metroPackageName: UnitySettings-Example 573 | metroPackageVersion: 574 | metroCertificatePath: 575 | metroCertificatePassword: 576 | metroCertificateSubject: 577 | metroCertificateIssuer: 578 | metroCertificateNotAfter: 0000000000000000 579 | metroApplicationDescription: UnitySettings-Example 580 | wsaImages: {} 581 | metroTileShortName: 582 | metroCommandLineArgsFile: 583 | metroTileShowName: 0 584 | metroMediumTileShowName: 0 585 | metroLargeTileShowName: 0 586 | metroWideTileShowName: 0 587 | metroDefaultTileSize: 1 588 | metroTileForegroundText: 2 589 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 590 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 591 | a: 1} 592 | metroSplashScreenUseBackgroundColor: 0 593 | platformCapabilities: {} 594 | metroFTAName: 595 | metroFTAFileTypes: [] 596 | metroProtocolName: 597 | metroCompilationOverrides: 1 598 | tizenProductDescription: 599 | tizenProductURL: 600 | tizenSigningProfileName: 601 | tizenGPSPermissions: 0 602 | tizenMicrophonePermissions: 0 603 | tizenDeploymentTarget: 604 | tizenDeploymentTargetType: 0 605 | tizenMinOSVersion: 1 606 | n3dsUseExtSaveData: 0 607 | n3dsCompressStaticMem: 1 608 | n3dsExtSaveDataNumber: 0x12345 609 | n3dsStackSize: 131072 610 | n3dsTargetPlatform: 2 611 | n3dsRegion: 7 612 | n3dsMediaSize: 0 613 | n3dsLogoStyle: 3 614 | n3dsTitle: GameName 615 | n3dsProductCode: 616 | n3dsApplicationId: 0xFF3FF 617 | XboxOneProductId: 618 | XboxOneUpdateKey: 619 | XboxOneSandboxId: 620 | XboxOneContentId: 621 | XboxOneTitleId: 622 | XboxOneSCId: 623 | XboxOneGameOsOverridePath: 624 | XboxOnePackagingOverridePath: 625 | XboxOneAppManifestOverridePath: 626 | XboxOnePackageEncryption: 0 627 | XboxOnePackageUpdateGranularity: 2 628 | XboxOneDescription: 629 | XboxOneLanguage: 630 | - enus 631 | XboxOneCapability: [] 632 | XboxOneGameRating: {} 633 | XboxOneIsContentPackage: 0 634 | XboxOneEnableGPUVariability: 0 635 | XboxOneSockets: {} 636 | XboxOneSplashScreen: {fileID: 0} 637 | XboxOneAllowedProductIds: [] 638 | XboxOnePersistentLocalStorageSize: 0 639 | xboxOneScriptCompiler: 0 640 | vrEditorSettings: 641 | daydream: 642 | daydreamIconForeground: {fileID: 0} 643 | daydreamIconBackground: {fileID: 0} 644 | cloudServicesEnabled: {} 645 | facebookSdkVersion: 7.9.4 646 | apiCompatibilityLevel: 2 647 | cloudProjectId: 648 | projectName: 649 | organizationId: 650 | cloudEnabled: 0 651 | enableNativePlatformBackendsForNewInputSystem: 0 652 | disableOldInputManagerSupport: 0 653 | --------------------------------------------------------------------------------