├── .gitignore ├── LICENSE ├── README.md ├── Runtime ├── CONSOLA.TTF ├── CheatAttribute.cs ├── CheatConsole.cs ├── CheatManager.cs └── Pyton.CheatConsole.asmdef ├── Sample ├── Scenes │ └── SampleScene.unity └── Scripts │ └── Test.cs └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.meta -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 BenPyton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cheat Console for Unity 2 | ## Overview 3 | This is an in-game cheat console that allow you to execute cheat command during runtime.\ 4 | Press the quote key in-game to display the console and enter a command. 5 | 6 | The cheat console is available only in Unity editor and in development build, but no code are generated in release build.\ 7 | Thus, players will not be able to enable cheat console in the game by using a tool like dnSpy to open and modify your game assemblies. 8 | 9 | ## Installation 10 | Download the [package](https://github.com/BenPyton/cheatconsole/archive/master.zip).\ 11 | Extract the content into `YourProject\Packages\` folder (not in a subfolder).\ 12 | Unity will load automatically the package. 13 | 14 | ## Usage 15 | To add a cheat console in your game, simply go into `GameObject` menu or right click in your scene hierarchy and add a `Cheat Console` in the scene. 16 | 17 | To define cheat commands, add the `[Cheat]` attribute above static methods. 18 | 19 | You can listen for `OnOpen` and `OnClose` events to execute specific code when the console is displayed or hidden (like pausing your game). 20 | 21 | Example: 22 | ``` 23 | public class YourClass : MonoBehaviour 24 | { 25 | private void Start() 26 | { 27 | CheatConsole.OnOpen.AddListener(() => Debug.Log("Opened")); 28 | CheatConsole.OnClose.AddListener(() => Debug.Log("Closed")); 29 | } 30 | 31 | [Cheat] 32 | private static void CheatMethod() 33 | { 34 | CheatConsole.Log("Hello"); 35 | } 36 | 37 | [Cheat] 38 | private static void CheatMethodWithString(string str) 39 | { 40 | CheatConsole.Log("Hello " + str); 41 | } 42 | } 43 | ``` 44 | 45 | Then in-game, you only have to open the console, and type the method name (case sensitive) followed by all parameters separated by a space.\ 46 | If you want to enter a string parameter with spaces inside, wrap your string with double quotes `"`. 47 | 48 | Examples (output in the console): 49 | ``` 50 | > CheatMethod 51 | Hello 52 | > CheatMethodWithString world! 53 | Hello world! 54 | > CheatMethodWithString "everybody, and the world too!" 55 | Hello everybody, and the world too! 56 | ``` 57 | 58 | ## Limitations 59 | The attribute work with public, protected and private methods, but only with static methods (until I find a way to reference a class instance). 60 | 61 | Currently, only string, int and float parameters work in these methods. 62 | You will not be able to call a method if there is any other type of parameter. -------------------------------------------------------------------------------- /Runtime/CONSOLA.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenPyton/cheatconsole/3457cfa929d57c5fe8d8d2bd1081c72087269f26/Runtime/CONSOLA.TTF -------------------------------------------------------------------------------- /Runtime/CheatAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [AttributeUsage(AttributeTargets.Method)] 4 | public class CheatAttribute : Attribute 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /Runtime/CheatConsole.cs: -------------------------------------------------------------------------------- 1 | #if DEVELOPMENT_BUILD || UNITY_EDITOR 2 | #define CONSOLE_DEBUG 3 | #endif 4 | 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using UnityEngine; 8 | using UnityEngine.Events; 9 | using UnityEngine.UI; 10 | 11 | #if UNITY_EDITOR 12 | using UnityEditor; 13 | #endif 14 | 15 | public sealed class CheatConsole : MonoBehaviour 16 | { 17 | public readonly static UnityEvent OnOpen = new UnityEvent(); 18 | public readonly static UnityEvent OnClose = new UnityEvent(); 19 | 20 | public static void Log(string message) 21 | { 22 | #if CONSOLE_DEBUG 23 | if (s_instance != null) 24 | { 25 | s_instance.m_outputLog += "\n" + message; 26 | } 27 | #endif 28 | } 29 | 30 | public static void LogError(string message) 31 | { 32 | #if CONSOLE_DEBUG 33 | if (s_instance != null) 34 | { 35 | s_instance.m_outputLog += "\n[Error] " + message + ""; 36 | } 37 | #endif 38 | } 39 | 40 | #region Private 41 | 42 | // Start is called before the first frame update 43 | void Awake() 44 | { 45 | #if CONSOLE_DEBUG 46 | if (s_instance == null) 47 | { 48 | s_instance = this; 49 | DontDestroyOnLoad(gameObject); 50 | m_container?.SetActive(m_consoleEnabled); 51 | m_cursor = Instantiate(m_inputText, m_container?.transform); 52 | m_outputText.text = string.Empty; 53 | m_inputText.text = string.Empty; 54 | CheatManager.GetAllMethodNames(); // used only to init cheat manager, but used later to autocomplete 55 | } 56 | else 57 | { 58 | Destroy(gameObject); 59 | } 60 | #else 61 | Destroy(gameObject); 62 | #endif 63 | } 64 | 65 | 66 | #if CONSOLE_DEBUG 67 | void Update() 68 | { 69 | if (Input.GetKeyDown(KeyCode.Quote)) 70 | { 71 | m_consoleEnabled = !m_consoleEnabled; 72 | m_container?.SetActive(m_consoleEnabled); 73 | if(m_consoleEnabled) 74 | { 75 | OnOpen.Invoke(); 76 | } 77 | else 78 | { 79 | OnClose.Invoke(); 80 | } 81 | } 82 | else if (m_consoleEnabled) 83 | { 84 | UpdateInputField(); 85 | UpdateOutputLog(); 86 | } 87 | } 88 | 89 | private void UpdateInputField() 90 | { 91 | if (Input.GetKeyDown(KeyCode.UpArrow)) 92 | PreviousCommand(); 93 | else if (Input.GetKeyDown(KeyCode.DownArrow)) 94 | NextCommand(); 95 | else if (Input.GetKeyDown(KeyCode.RightArrow)) 96 | { 97 | m_cursorIndex++; 98 | m_cursorIndex = Mathf.Min(m_cursorIndex, m_inputCommand.Length); 99 | m_dirty = true; 100 | } 101 | else if (Input.GetKeyDown(KeyCode.LeftArrow)) 102 | { 103 | m_cursorIndex--; 104 | m_cursorIndex = Mathf.Max(m_cursorIndex, 0); 105 | m_dirty = true; 106 | } 107 | else if (Input.GetKeyDown(KeyCode.Delete) 108 | && m_cursorIndex < m_inputCommand.Length) 109 | { 110 | m_inputCommand = m_inputCommand.Remove(m_cursorIndex, 1); 111 | m_dirty = true; 112 | } 113 | else if (Input.GetKeyDown(KeyCode.Tab)) 114 | { 115 | string[] allMethodNames = CheatManager.GetAllMethodNames(); 116 | List matchingNames = new(allMethodNames.Where(s => s.Contains(m_inputCommand, System.StringComparison.CurrentCultureIgnoreCase))); 117 | if (matchingNames.Count == 0) 118 | { 119 | LogError($"No methods found that contain {m_inputCommand}"); 120 | } 121 | else if (matchingNames.Count == 1) 122 | { 123 | m_inputCommand = matchingNames[0]; 124 | m_cursorIndex = m_inputCommand.Count(); 125 | m_dirty = true; 126 | } 127 | else 128 | { 129 | foreach (string methodName in matchingNames) 130 | { 131 | Log($"[Suggestion] {methodName}"); 132 | } 133 | } 134 | } 135 | else 136 | { 137 | foreach (char c in Input.inputString) 138 | { 139 | if (c == '\n' || c == '\r') 140 | { 141 | ExecuteCommand(); 142 | m_cursorIndex = 0; 143 | m_dirty = true; 144 | break; 145 | } 146 | else if (c == '\b') 147 | { 148 | if (m_cursorIndex > 0) 149 | { 150 | m_inputCommand = m_inputCommand.Remove(m_cursorIndex - 1, 1); 151 | m_cursorIndex--; 152 | m_dirty = true; 153 | } 154 | } 155 | else 156 | { 157 | m_inputCommand = m_inputCommand.Insert(m_cursorIndex, c.ToString()); 158 | m_cursorIndex++; 159 | m_dirty = true; 160 | } 161 | } 162 | } 163 | 164 | if (m_dirty) 165 | { 166 | m_inputText.text = m_prefix + m_inputCommand; 167 | m_cursor.text = new string(' ', m_prefix.Length + m_cursorIndex) + '_'; 168 | m_dirty = false; 169 | } 170 | 171 | m_cursor.gameObject.SetActive((int)(Time.realtimeSinceStartup * 1000) % 1000 < 500); 172 | } 173 | 174 | private void UpdateOutputLog() 175 | { 176 | m_outputText.text = m_outputLog; 177 | } 178 | 179 | private void ExecuteCommand() 180 | { 181 | if (string.IsNullOrWhiteSpace(m_inputCommand)) 182 | return; 183 | 184 | Log(m_prefix + m_inputCommand); 185 | 186 | m_currentHistoryIndex = -1; 187 | m_commandHistory.Add(m_inputCommand); 188 | if(!CheatManager.Execute(m_inputCommand)) 189 | { 190 | LogError(CheatManager.ErrorMessage); 191 | } 192 | m_inputCommand = string.Empty; 193 | 194 | while(m_commandHistory.Count > MAX_COMMAND_HISTORY) 195 | { 196 | m_commandHistory.RemoveAt(0); 197 | } 198 | } 199 | 200 | private void PreviousCommand() 201 | { 202 | if(m_currentHistoryIndex < 0) 203 | m_currentHistoryIndex = m_commandHistory.Count - 1; 204 | else if(m_currentHistoryIndex > 0) 205 | m_currentHistoryIndex--; 206 | 207 | m_inputCommand = m_commandHistory[m_currentHistoryIndex]; 208 | m_cursorIndex = m_inputCommand.Length; 209 | m_dirty = true; 210 | } 211 | 212 | private void NextCommand() 213 | { 214 | if (m_currentHistoryIndex < 0) 215 | return; 216 | 217 | if (m_currentHistoryIndex >= m_commandHistory.Count - 1) 218 | m_currentHistoryIndex = -1; 219 | else 220 | m_currentHistoryIndex++; 221 | 222 | m_inputCommand = m_currentHistoryIndex < 0 ? string.Empty : m_commandHistory[m_currentHistoryIndex]; 223 | m_cursorIndex = m_inputCommand.Length; 224 | m_dirty = true; 225 | } 226 | 227 | private const int MAX_COMMAND_HISTORY = 20; 228 | private static CheatConsole s_instance = null; 229 | private List m_commandHistory = new List(); 230 | private Text m_cursor = null; 231 | private string m_prefix = "> "; 232 | private string m_inputCommand = string.Empty; 233 | private string m_outputLog = string.Empty; 234 | private int m_currentHistoryIndex = 0; 235 | private int m_cursorIndex = 0; 236 | private bool m_dirty = true; 237 | private bool m_consoleEnabled = false; 238 | #endif 239 | 240 | [SerializeField] private GameObject m_container = null; 241 | [SerializeField] private Text m_inputText = null; 242 | [SerializeField] private Text m_outputText = null; 243 | 244 | #endregion // Private 245 | 246 | #region Editor 247 | 248 | #if UNITY_EDITOR 249 | [MenuItem("GameObject/Cheat Console", false, 30)] 250 | public static void CreateConsole(MenuCommand menuCommand) 251 | { 252 | CheatConsole canvas = CreateCanvas(); 253 | RectTransform container = CreateContainer(canvas.gameObject); 254 | ScrollRect scrollView = CreateScrollview(container.gameObject); 255 | RectTransform viewport = CreateViewport(scrollView.gameObject); 256 | Scrollbar scrollbar = CreateScrollbar(scrollView.gameObject); 257 | RectTransform slidingArea = CreateSlidingArea(scrollbar.gameObject); 258 | RectTransform handle = CreateHandle(slidingArea.gameObject); 259 | RectTransform outputText = CreateOutputText(viewport.gameObject); 260 | RectTransform inputText = CreateInputText(container.gameObject); 261 | 262 | scrollbar.handleRect = handle; 263 | scrollbar.targetGraphic = handle.GetComponent(); 264 | scrollView.viewport = viewport.GetComponent(); 265 | scrollView.verticalScrollbar = scrollbar; 266 | scrollView.content = outputText; 267 | canvas.m_container = container.gameObject; 268 | canvas.m_outputText = outputText.GetComponent(); 269 | canvas.m_inputText = inputText.GetComponent(); 270 | container.gameObject.SetActive(false); 271 | 272 | Undo.RegisterCreatedObjectUndo(canvas.gameObject, "Create " + canvas.gameObject.name); 273 | Selection.activeObject = canvas.gameObject; 274 | } 275 | 276 | private static CheatConsole CreateCanvas() 277 | { 278 | GameObject canvas = new GameObject("CheatConsole" 279 | , typeof(RectTransform) 280 | , typeof(Canvas) 281 | , typeof(CanvasScaler) 282 | , typeof(GraphicRaycaster) 283 | , typeof(CheatConsole)); 284 | 285 | canvas.GetComponent().renderMode = RenderMode.ScreenSpaceOverlay; 286 | canvas.GetComponent().uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; 287 | canvas.GetComponent().referenceResolution = new Vector2(1920, 1080); 288 | canvas.gameObject.layer = LayerMask.NameToLayer("UI"); 289 | 290 | return canvas.GetComponent(); 291 | } 292 | 293 | private static RectTransform CreateContainer(GameObject parent) 294 | { 295 | GameObject container = new GameObject("Container" 296 | , typeof(RectTransform) 297 | , typeof(CanvasRenderer) 298 | , typeof(Image)); 299 | GameObjectUtility.SetParentAndAlign(container, parent); 300 | 301 | container.GetComponent().anchorMin = Vector2.zero; 302 | container.GetComponent().anchorMax = Vector2.one; 303 | container.GetComponent().offsetMin = Vector2.zero; 304 | container.GetComponent().offsetMax = Vector2.zero; 305 | container.GetComponent().color = new Color(0, 0, 0, 0.4f); 306 | 307 | return container.GetComponent(); 308 | } 309 | 310 | private static ScrollRect CreateScrollview(GameObject parent) 311 | { 312 | GameObject scrollView = new GameObject("ScrollView" 313 | , typeof(RectTransform) 314 | , typeof(CanvasRenderer) 315 | , typeof(ScrollRect)); 316 | GameObjectUtility.SetParentAndAlign(scrollView, parent); 317 | 318 | scrollView.GetComponent().anchorMin = Vector2.zero; 319 | scrollView.GetComponent().anchorMax = Vector2.one; 320 | scrollView.GetComponent().offsetMin = new Vector2(10, 50); 321 | scrollView.GetComponent().offsetMax = new Vector2(-10, -10); 322 | scrollView.GetComponent().horizontal = false; 323 | scrollView.GetComponent().movementType = ScrollRect.MovementType.Clamped; 324 | scrollView.GetComponent().inertia = false; 325 | scrollView.GetComponent().scrollSensitivity = 5; 326 | scrollView.GetComponent().verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; 327 | scrollView.GetComponent().verticalScrollbarSpacing = -3; 328 | 329 | return scrollView.GetComponent(); 330 | } 331 | 332 | private static RectTransform CreateViewport(GameObject parent) 333 | { 334 | GameObject viewport = new GameObject("Viewport" 335 | , typeof(RectTransform) 336 | , typeof(CanvasRenderer) 337 | , typeof(Image) 338 | , typeof(Mask)); 339 | GameObjectUtility.SetParentAndAlign(viewport, parent); 340 | 341 | viewport.GetComponent().pivot = new Vector2(0, 1); 342 | viewport.GetComponent().color = Color.white; 343 | viewport.GetComponent().sprite = AssetDatabase.GetBuiltinExtraResource("UI/Skin/UIMask.psd"); 344 | viewport.GetComponent().type = Image.Type.Sliced; 345 | viewport.GetComponent().showMaskGraphic = false; 346 | 347 | return viewport.GetComponent(); 348 | } 349 | 350 | private static Scrollbar CreateScrollbar(GameObject parent) 351 | { 352 | GameObject scrollbar = new GameObject("Scrollbar" 353 | , typeof(RectTransform) 354 | , typeof(CanvasRenderer) 355 | , typeof(Image) 356 | , typeof(Scrollbar)); 357 | GameObjectUtility.SetParentAndAlign(scrollbar, parent); 358 | 359 | scrollbar.GetComponent().pivot = Vector2.one; 360 | scrollbar.GetComponent().anchorMin = new Vector2(1, 0); 361 | scrollbar.GetComponent().anchorMax = Vector2.one; 362 | scrollbar.GetComponent().offsetMin = new Vector2(-20, 0); 363 | scrollbar.GetComponent().offsetMax = Vector2.zero; 364 | scrollbar.GetComponent().color = new Color(0.2f, 0.2f, 0.2f); 365 | scrollbar.GetComponent().sprite = AssetDatabase.GetBuiltinExtraResource("UI/Skin/Background.psd"); 366 | scrollbar.GetComponent().type = Image.Type.Sliced; 367 | 368 | return scrollbar.GetComponent(); 369 | } 370 | 371 | private static RectTransform CreateSlidingArea(GameObject parent) 372 | { 373 | GameObject slidingArea = new GameObject("SlidingArea" 374 | , typeof(RectTransform)); 375 | GameObjectUtility.SetParentAndAlign(slidingArea, parent); 376 | 377 | slidingArea.GetComponent().anchorMin = Vector2.zero; 378 | slidingArea.GetComponent().anchorMax = Vector2.one; 379 | slidingArea.GetComponent().offsetMin = new Vector2(10, 10); 380 | slidingArea.GetComponent().offsetMax = new Vector2(-10, -10); 381 | 382 | return slidingArea.GetComponent(); 383 | } 384 | 385 | private static RectTransform CreateHandle(GameObject parent) 386 | { 387 | GameObject handle = new GameObject("Handle" 388 | , typeof(RectTransform) 389 | , typeof(CanvasRenderer) 390 | , typeof(Image)); 391 | GameObjectUtility.SetParentAndAlign(handle, parent); 392 | 393 | handle.GetComponent().offsetMin = new Vector2(-10, -10); 394 | handle.GetComponent().offsetMax = new Vector2(10, 10); 395 | handle.GetComponent().color = new Color(0.3f, 0.3f, 0.3f); 396 | handle.GetComponent().sprite = AssetDatabase.GetBuiltinExtraResource("UI/Skin/UISprite.psd"); 397 | handle.GetComponent().type = Image.Type.Sliced; 398 | 399 | return handle.GetComponent(); 400 | } 401 | 402 | private static RectTransform CreateOutputText(GameObject parent) 403 | { 404 | GameObject outputText = new GameObject("OutputText" 405 | , typeof(RectTransform) 406 | , typeof(CanvasRenderer) 407 | , typeof(Text) 408 | , typeof(ContentSizeFitter)); 409 | GameObjectUtility.SetParentAndAlign(outputText, parent); 410 | 411 | outputText.GetComponent().pivot = new Vector2(0.5f, 0); 412 | outputText.GetComponent().anchorMin = Vector2.zero; 413 | outputText.GetComponent().anchorMax = new Vector2(1, 0); 414 | outputText.GetComponent().offsetMin = Vector2.zero; 415 | outputText.GetComponent().offsetMax = Vector2.zero; 416 | outputText.GetComponent().color = Color.white; 417 | outputText.GetComponent().font = GetFont(); 418 | outputText.GetComponent().fontSize = 24; 419 | outputText.GetComponent().supportRichText = true; 420 | outputText.GetComponent().alignment = TextAnchor.LowerLeft; 421 | outputText.GetComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize; 422 | 423 | return outputText.GetComponent(); 424 | } 425 | 426 | private static RectTransform CreateInputText(GameObject parent) 427 | { 428 | GameObject inputText = new GameObject("InputText" 429 | , typeof(RectTransform) 430 | , typeof(CanvasRenderer) 431 | , typeof(Text)); 432 | GameObjectUtility.SetParentAndAlign(inputText, parent); 433 | 434 | inputText.GetComponent().pivot = new Vector2(0.5f, 0); 435 | inputText.GetComponent().anchorMin = Vector2.zero; 436 | inputText.GetComponent().anchorMax = new Vector2(1, 0); 437 | inputText.GetComponent().offsetMin = new Vector2(10, 10); 438 | inputText.GetComponent().offsetMax = new Vector2(-10, 40); 439 | inputText.GetComponent().color = Color.white; 440 | inputText.GetComponent().font = GetFont(); 441 | inputText.GetComponent().fontSize = 24; 442 | inputText.GetComponent().supportRichText = false; 443 | inputText.GetComponent().alignment = TextAnchor.MiddleLeft; 444 | inputText.GetComponent().horizontalOverflow = HorizontalWrapMode.Overflow; 445 | inputText.GetComponent().verticalOverflow = VerticalWrapMode.Overflow; 446 | 447 | return inputText.GetComponent(); 448 | } 449 | 450 | private static Font m_cachedFont = null; 451 | private static Font GetFont() 452 | { 453 | if(m_cachedFont == null) 454 | { 455 | string fontPath = "Packages/com.pyton.cheatconsole/Runtime/CONSOLA.TTF"; 456 | m_cachedFont = AssetDatabase.LoadAssetAtPath(fontPath); 457 | if (m_cachedFont == null) 458 | Debug.LogWarning(string.Format("Can't load font from \"{0}\"", fontPath)); 459 | } 460 | return m_cachedFont; 461 | } 462 | #endif 463 | 464 | #endregion // Editor 465 | } 466 | -------------------------------------------------------------------------------- /Runtime/CheatManager.cs: -------------------------------------------------------------------------------- 1 | #if DEVELOPMENT_BUILD || UNITY_EDITOR 2 | #define CONSOLE_DEBUG 3 | #endif 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | 10 | public static class CheatManager 11 | { 12 | public static string ErrorMessage { 13 | get { 14 | #if CONSOLE_DEBUG 15 | return m_errorMsg; 16 | #else 17 | return string.Empty; 18 | #endif 19 | } 20 | } 21 | 22 | public static bool Execute(string command) 23 | { 24 | #if CONSOLE_DEBUG 25 | return Execute_Impl(command); 26 | #else 27 | return true; 28 | #endif 29 | } 30 | 31 | public static string[] GetAllMethodNames() 32 | { 33 | #if CONSOLE_DEBUG 34 | return Methods.Select((method) => method.Name).ToArray(); 35 | #else 36 | return new string[0]; 37 | #endif 38 | } 39 | 40 | #region Private 41 | 42 | #if CONSOLE_DEBUG 43 | private static bool Execute_Impl(string command) 44 | { 45 | string methodName = string.Empty; 46 | string[] methodParams = null; 47 | 48 | ParseCommand(command, out methodName, out methodParams); 49 | 50 | string strParams = ""; 51 | foreach (string p in methodParams) 52 | { 53 | strParams += "\"" + p + "\", "; 54 | } 55 | 56 | MethodInfo[] matchingMethod = Methods.Where(m => m.Name == methodName).ToArray(); 57 | if (matchingMethod.Length <= 0) 58 | { 59 | m_errorMsg = string.Format("Command \"{0}\" doesn't exists.", methodName); 60 | return false; 61 | } 62 | 63 | matchingMethod = matchingMethod.Where(m => m.GetParameters().Length == methodParams.Length).ToArray(); 64 | if (matchingMethod.Length <= 0) 65 | { 66 | m_errorMsg = string.Format("Wrong number of argument for command \"{0}\".", methodName); 67 | return false; 68 | } 69 | 70 | object[] values = methodParams.Select(x => ConvertParameter(x)).ToArray(); 71 | 72 | matchingMethod = matchingMethod.Where(m => { 73 | bool found = true; 74 | ParameterInfo[] parameters = m.GetParameters(); 75 | for (int i = 0; found && i < parameters.Length; i++) 76 | { 77 | if (parameters[i].ParameterType != values[i].GetType()) 78 | { 79 | m_errorMsg = string.Format("Parameter {0} should be of type {1}.", i, parameters[i].ParameterType); 80 | found = false; 81 | } 82 | } 83 | return found; 84 | }).ToArray(); 85 | 86 | if (matchingMethod.Length <= 0) 87 | { 88 | return false; 89 | } 90 | 91 | matchingMethod[0].Invoke(null, values); 92 | return true; 93 | } 94 | 95 | private static void CacheCheatMethods() 96 | { 97 | m_methodsCached = new MethodInfo[0]; 98 | Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 99 | foreach (Assembly assembly in assemblies) 100 | { 101 | m_methodsCached = m_methodsCached.Concat 102 | (assembly.GetTypes() 103 | .SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod)) 104 | .Where(m => m.GetCustomAttributes(typeof(CheatAttribute), false).Length > 0) 105 | ).ToArray(); 106 | } 107 | } 108 | 109 | private static bool ParseCommand(string command, out string methodName, out string[] methodParams) 110 | { 111 | List paramList = new List(); 112 | int prevIndex = 0; 113 | int index = command.IndexOf(' '); 114 | methodName = (index < 0) ? command : command.Substring(0, index); 115 | 116 | while (index > 0) 117 | { 118 | prevIndex = index + 1; 119 | 120 | // trim first whitespaces 121 | while (prevIndex < command.Length && command[prevIndex] == ' ') 122 | prevIndex++; 123 | 124 | // get whole string without splitting by whitespace 125 | if (prevIndex < command.Length && command[prevIndex] == '"') 126 | { 127 | prevIndex++; 128 | index = command.IndexOf('"', prevIndex); 129 | } 130 | // split by whitespace 131 | else 132 | { 133 | index = command.IndexOf(' ', prevIndex); 134 | } 135 | 136 | // add command only if not at the end 137 | if (prevIndex < command.Length) 138 | { 139 | paramList.Add((index > 0) ? command.Substring(prevIndex, index - prevIndex) : command.Substring(prevIndex)); 140 | } 141 | } 142 | 143 | methodParams = paramList.ToArray(); 144 | 145 | return !string.IsNullOrWhiteSpace(methodName); 146 | } 147 | 148 | private static object ConvertParameter(string parameter) 149 | { 150 | object convertedValue = parameter; 151 | 152 | int intValue = 0; 153 | float floatValue = 0.0f; 154 | 155 | if(int.TryParse(parameter, out intValue)) 156 | { 157 | convertedValue = intValue; 158 | } 159 | else if(float.TryParse(parameter, out floatValue)) 160 | { 161 | convertedValue = floatValue; 162 | } 163 | 164 | return convertedValue; 165 | } 166 | 167 | 168 | private static string m_errorMsg = string.Empty; 169 | private static MethodInfo[] m_methodsCached = null; 170 | private static MethodInfo[] Methods 171 | { 172 | get 173 | { 174 | if (m_methodsCached == null) 175 | CacheCheatMethods(); 176 | return m_methodsCached; 177 | } 178 | } 179 | 180 | #endif 181 | 182 | #endregion // Private 183 | } 184 | -------------------------------------------------------------------------------- /Runtime/Pyton.CheatConsole.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pyton.CheatConsole", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": false, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [] 12 | } -------------------------------------------------------------------------------- /Sample/Scenes/SampleScene.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: 9 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: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 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: 705507994} 41 | m_IndirectSpecularColor: {r: 0.44657874, g: 0.49641258, b: 0.5748172, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 0 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 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: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightingDataAsset: {fileID: 0} 100 | m_UseShadowmask: 1 101 | --- !u!196 &4 102 | NavMeshSettings: 103 | serializedVersion: 2 104 | m_ObjectHideFlags: 0 105 | m_BuildSettings: 106 | serializedVersion: 2 107 | agentTypeID: 0 108 | agentRadius: 0.5 109 | agentHeight: 2 110 | agentSlope: 45 111 | agentClimb: 0.4 112 | ledgeDropHeight: 0 113 | maxJumpAcrossDistance: 0 114 | minRegionArea: 2 115 | manualCellSize: 0 116 | cellSize: 0.16666667 117 | manualTileSize: 0 118 | tileSize: 256 119 | accuratePlacement: 0 120 | debug: 121 | m_Flags: 0 122 | m_NavMeshData: {fileID: 0} 123 | --- !u!1 &132701313 124 | GameObject: 125 | m_ObjectHideFlags: 0 126 | m_CorrespondingSourceObject: {fileID: 0} 127 | m_PrefabInstance: {fileID: 0} 128 | m_PrefabAsset: {fileID: 0} 129 | serializedVersion: 6 130 | m_Component: 131 | - component: {fileID: 132701314} 132 | - component: {fileID: 132701317} 133 | - component: {fileID: 132701316} 134 | - component: {fileID: 132701315} 135 | m_Layer: 5 136 | m_Name: Scrollbar 137 | m_TagString: Untagged 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!224 &132701314 143 | RectTransform: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 132701313} 149 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 150 | m_LocalPosition: {x: 0, y: 0, z: 0} 151 | m_LocalScale: {x: 1, y: 1, z: 1} 152 | m_Children: 153 | - {fileID: 360971373} 154 | m_Father: {fileID: 202526666} 155 | m_RootOrder: 1 156 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 157 | m_AnchorMin: {x: 1, y: 0} 158 | m_AnchorMax: {x: 1, y: 1} 159 | m_AnchoredPosition: {x: 0, y: 0} 160 | m_SizeDelta: {x: 20, y: 0} 161 | m_Pivot: {x: 1, y: 1} 162 | --- !u!114 &132701315 163 | MonoBehaviour: 164 | m_ObjectHideFlags: 0 165 | m_CorrespondingSourceObject: {fileID: 0} 166 | m_PrefabInstance: {fileID: 0} 167 | m_PrefabAsset: {fileID: 0} 168 | m_GameObject: {fileID: 132701313} 169 | m_Enabled: 1 170 | m_EditorHideFlags: 0 171 | m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} 172 | m_Name: 173 | m_EditorClassIdentifier: 174 | m_Navigation: 175 | m_Mode: 3 176 | m_SelectOnUp: {fileID: 0} 177 | m_SelectOnDown: {fileID: 0} 178 | m_SelectOnLeft: {fileID: 0} 179 | m_SelectOnRight: {fileID: 0} 180 | m_Transition: 1 181 | m_Colors: 182 | m_NormalColor: {r: 1, g: 1, b: 1, a: 1} 183 | m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} 184 | m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} 185 | m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} 186 | m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} 187 | m_ColorMultiplier: 1 188 | m_FadeDuration: 0.1 189 | m_SpriteState: 190 | m_HighlightedSprite: {fileID: 0} 191 | m_PressedSprite: {fileID: 0} 192 | m_SelectedSprite: {fileID: 0} 193 | m_DisabledSprite: {fileID: 0} 194 | m_AnimationTriggers: 195 | m_NormalTrigger: Normal 196 | m_HighlightedTrigger: Highlighted 197 | m_PressedTrigger: Pressed 198 | m_SelectedTrigger: Selected 199 | m_DisabledTrigger: Disabled 200 | m_Interactable: 1 201 | m_TargetGraphic: {fileID: 1927497583} 202 | m_HandleRect: {fileID: 1927497582} 203 | m_Direction: 0 204 | m_Value: 0 205 | m_Size: 0.2 206 | m_NumberOfSteps: 0 207 | m_OnValueChanged: 208 | m_PersistentCalls: 209 | m_Calls: [] 210 | --- !u!114 &132701316 211 | MonoBehaviour: 212 | m_ObjectHideFlags: 0 213 | m_CorrespondingSourceObject: {fileID: 0} 214 | m_PrefabInstance: {fileID: 0} 215 | m_PrefabAsset: {fileID: 0} 216 | m_GameObject: {fileID: 132701313} 217 | m_Enabled: 1 218 | m_EditorHideFlags: 0 219 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 220 | m_Name: 221 | m_EditorClassIdentifier: 222 | m_Material: {fileID: 0} 223 | m_Color: {r: 0.2, g: 0.2, b: 0.2, a: 1} 224 | m_RaycastTarget: 1 225 | m_OnCullStateChanged: 226 | m_PersistentCalls: 227 | m_Calls: [] 228 | m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} 229 | m_Type: 1 230 | m_PreserveAspect: 0 231 | m_FillCenter: 1 232 | m_FillMethod: 4 233 | m_FillAmount: 1 234 | m_FillClockwise: 1 235 | m_FillOrigin: 0 236 | m_UseSpriteMesh: 0 237 | m_PixelsPerUnitMultiplier: 1 238 | --- !u!222 &132701317 239 | CanvasRenderer: 240 | m_ObjectHideFlags: 0 241 | m_CorrespondingSourceObject: {fileID: 0} 242 | m_PrefabInstance: {fileID: 0} 243 | m_PrefabAsset: {fileID: 0} 244 | m_GameObject: {fileID: 132701313} 245 | m_CullTransparentMesh: 0 246 | --- !u!1 &152642159 247 | GameObject: 248 | m_ObjectHideFlags: 0 249 | m_CorrespondingSourceObject: {fileID: 0} 250 | m_PrefabInstance: {fileID: 0} 251 | m_PrefabAsset: {fileID: 0} 252 | serializedVersion: 6 253 | m_Component: 254 | - component: {fileID: 152642163} 255 | - component: {fileID: 152642162} 256 | - component: {fileID: 152642160} 257 | - component: {fileID: 152642161} 258 | m_Layer: 5 259 | m_Name: OutputText 260 | m_TagString: Untagged 261 | m_Icon: {fileID: 0} 262 | m_NavMeshLayer: 0 263 | m_StaticEditorFlags: 0 264 | m_IsActive: 1 265 | --- !u!114 &152642160 266 | MonoBehaviour: 267 | m_ObjectHideFlags: 0 268 | m_CorrespondingSourceObject: {fileID: 0} 269 | m_PrefabInstance: {fileID: 0} 270 | m_PrefabAsset: {fileID: 0} 271 | m_GameObject: {fileID: 152642159} 272 | m_Enabled: 1 273 | m_EditorHideFlags: 0 274 | m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} 275 | m_Name: 276 | m_EditorClassIdentifier: 277 | m_Material: {fileID: 0} 278 | m_Color: {r: 1, g: 1, b: 1, a: 1} 279 | m_RaycastTarget: 1 280 | m_OnCullStateChanged: 281 | m_PersistentCalls: 282 | m_Calls: [] 283 | m_FontData: 284 | m_Font: {fileID: 12800000, guid: bf12c688961730246ad42c1312512913, type: 3} 285 | m_FontSize: 24 286 | m_FontStyle: 0 287 | m_BestFit: 0 288 | m_MinSize: 10 289 | m_MaxSize: 40 290 | m_Alignment: 6 291 | m_AlignByGeometry: 0 292 | m_RichText: 1 293 | m_HorizontalOverflow: 0 294 | m_VerticalOverflow: 0 295 | m_LineSpacing: 1 296 | m_Text: 297 | --- !u!114 &152642161 298 | MonoBehaviour: 299 | m_ObjectHideFlags: 0 300 | m_CorrespondingSourceObject: {fileID: 0} 301 | m_PrefabInstance: {fileID: 0} 302 | m_PrefabAsset: {fileID: 0} 303 | m_GameObject: {fileID: 152642159} 304 | m_Enabled: 1 305 | m_EditorHideFlags: 0 306 | m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} 307 | m_Name: 308 | m_EditorClassIdentifier: 309 | m_HorizontalFit: 0 310 | m_VerticalFit: 2 311 | --- !u!222 &152642162 312 | CanvasRenderer: 313 | m_ObjectHideFlags: 0 314 | m_CorrespondingSourceObject: {fileID: 0} 315 | m_PrefabInstance: {fileID: 0} 316 | m_PrefabAsset: {fileID: 0} 317 | m_GameObject: {fileID: 152642159} 318 | m_CullTransparentMesh: 0 319 | --- !u!224 &152642163 320 | RectTransform: 321 | m_ObjectHideFlags: 0 322 | m_CorrespondingSourceObject: {fileID: 0} 323 | m_PrefabInstance: {fileID: 0} 324 | m_PrefabAsset: {fileID: 0} 325 | m_GameObject: {fileID: 152642159} 326 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 327 | m_LocalPosition: {x: 0, y: 0, z: 0} 328 | m_LocalScale: {x: 1, y: 1, z: 1} 329 | m_Children: [] 330 | m_Father: {fileID: 1670941963} 331 | m_RootOrder: 0 332 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 333 | m_AnchorMin: {x: 0, y: 0} 334 | m_AnchorMax: {x: 1, y: 0} 335 | m_AnchoredPosition: {x: 0, y: 0} 336 | m_SizeDelta: {x: 0, y: 0} 337 | m_Pivot: {x: 0.5, y: 0} 338 | --- !u!1 &202526665 339 | GameObject: 340 | m_ObjectHideFlags: 0 341 | m_CorrespondingSourceObject: {fileID: 0} 342 | m_PrefabInstance: {fileID: 0} 343 | m_PrefabAsset: {fileID: 0} 344 | serializedVersion: 6 345 | m_Component: 346 | - component: {fileID: 202526666} 347 | - component: {fileID: 202526668} 348 | - component: {fileID: 202526667} 349 | m_Layer: 5 350 | m_Name: ScrollView 351 | m_TagString: Untagged 352 | m_Icon: {fileID: 0} 353 | m_NavMeshLayer: 0 354 | m_StaticEditorFlags: 0 355 | m_IsActive: 1 356 | --- !u!224 &202526666 357 | RectTransform: 358 | m_ObjectHideFlags: 0 359 | m_CorrespondingSourceObject: {fileID: 0} 360 | m_PrefabInstance: {fileID: 0} 361 | m_PrefabAsset: {fileID: 0} 362 | m_GameObject: {fileID: 202526665} 363 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 364 | m_LocalPosition: {x: 0, y: 0, z: 0} 365 | m_LocalScale: {x: 1, y: 1, z: 1} 366 | m_Children: 367 | - {fileID: 1670941963} 368 | - {fileID: 132701314} 369 | m_Father: {fileID: 1053727430} 370 | m_RootOrder: 0 371 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 372 | m_AnchorMin: {x: 0, y: 0} 373 | m_AnchorMax: {x: 1, y: 1} 374 | m_AnchoredPosition: {x: 0, y: 20} 375 | m_SizeDelta: {x: -20, y: -60} 376 | m_Pivot: {x: 0.5, y: 0.5} 377 | --- !u!114 &202526667 378 | MonoBehaviour: 379 | m_ObjectHideFlags: 0 380 | m_CorrespondingSourceObject: {fileID: 0} 381 | m_PrefabInstance: {fileID: 0} 382 | m_PrefabAsset: {fileID: 0} 383 | m_GameObject: {fileID: 202526665} 384 | m_Enabled: 1 385 | m_EditorHideFlags: 0 386 | m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} 387 | m_Name: 388 | m_EditorClassIdentifier: 389 | m_Content: {fileID: 152642163} 390 | m_Horizontal: 0 391 | m_Vertical: 1 392 | m_MovementType: 2 393 | m_Elasticity: 0.1 394 | m_Inertia: 0 395 | m_DecelerationRate: 0.135 396 | m_ScrollSensitivity: 5 397 | m_Viewport: {fileID: 1670941963} 398 | m_HorizontalScrollbar: {fileID: 0} 399 | m_VerticalScrollbar: {fileID: 132701315} 400 | m_HorizontalScrollbarVisibility: 0 401 | m_VerticalScrollbarVisibility: 2 402 | m_HorizontalScrollbarSpacing: 0 403 | m_VerticalScrollbarSpacing: -3 404 | m_OnValueChanged: 405 | m_PersistentCalls: 406 | m_Calls: [] 407 | --- !u!222 &202526668 408 | CanvasRenderer: 409 | m_ObjectHideFlags: 0 410 | m_CorrespondingSourceObject: {fileID: 0} 411 | m_PrefabInstance: {fileID: 0} 412 | m_PrefabAsset: {fileID: 0} 413 | m_GameObject: {fileID: 202526665} 414 | m_CullTransparentMesh: 0 415 | --- !u!1 &360971372 416 | GameObject: 417 | m_ObjectHideFlags: 0 418 | m_CorrespondingSourceObject: {fileID: 0} 419 | m_PrefabInstance: {fileID: 0} 420 | m_PrefabAsset: {fileID: 0} 421 | serializedVersion: 6 422 | m_Component: 423 | - component: {fileID: 360971373} 424 | m_Layer: 5 425 | m_Name: SlidingArea 426 | m_TagString: Untagged 427 | m_Icon: {fileID: 0} 428 | m_NavMeshLayer: 0 429 | m_StaticEditorFlags: 0 430 | m_IsActive: 1 431 | --- !u!224 &360971373 432 | RectTransform: 433 | m_ObjectHideFlags: 0 434 | m_CorrespondingSourceObject: {fileID: 0} 435 | m_PrefabInstance: {fileID: 0} 436 | m_PrefabAsset: {fileID: 0} 437 | m_GameObject: {fileID: 360971372} 438 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 439 | m_LocalPosition: {x: 0, y: 0, z: 0} 440 | m_LocalScale: {x: 1, y: 1, z: 1} 441 | m_Children: 442 | - {fileID: 1927497582} 443 | m_Father: {fileID: 132701314} 444 | m_RootOrder: 0 445 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 446 | m_AnchorMin: {x: 0, y: 0} 447 | m_AnchorMax: {x: 1, y: 1} 448 | m_AnchoredPosition: {x: 0, y: 0} 449 | m_SizeDelta: {x: -20, y: -20} 450 | m_Pivot: {x: 0.5, y: 0.5} 451 | --- !u!1 &689889530 452 | GameObject: 453 | m_ObjectHideFlags: 0 454 | m_CorrespondingSourceObject: {fileID: 0} 455 | m_PrefabInstance: {fileID: 0} 456 | m_PrefabAsset: {fileID: 0} 457 | serializedVersion: 6 458 | m_Component: 459 | - component: {fileID: 689889535} 460 | - component: {fileID: 689889534} 461 | - component: {fileID: 689889533} 462 | - component: {fileID: 689889532} 463 | - component: {fileID: 689889531} 464 | m_Layer: 5 465 | m_Name: CheatConsole 466 | m_TagString: Untagged 467 | m_Icon: {fileID: 0} 468 | m_NavMeshLayer: 0 469 | m_StaticEditorFlags: 0 470 | m_IsActive: 1 471 | --- !u!114 &689889531 472 | MonoBehaviour: 473 | m_ObjectHideFlags: 0 474 | m_CorrespondingSourceObject: {fileID: 0} 475 | m_PrefabInstance: {fileID: 0} 476 | m_PrefabAsset: {fileID: 0} 477 | m_GameObject: {fileID: 689889530} 478 | m_Enabled: 1 479 | m_EditorHideFlags: 0 480 | m_Script: {fileID: 11500000, guid: efaa55ae49b3f144e9ec3db7620e756a, type: 3} 481 | m_Name: 482 | m_EditorClassIdentifier: 483 | m_container: {fileID: 1053727429} 484 | m_inputText: {fileID: 1352327078} 485 | m_outputText: {fileID: 152642160} 486 | --- !u!114 &689889532 487 | MonoBehaviour: 488 | m_ObjectHideFlags: 0 489 | m_CorrespondingSourceObject: {fileID: 0} 490 | m_PrefabInstance: {fileID: 0} 491 | m_PrefabAsset: {fileID: 0} 492 | m_GameObject: {fileID: 689889530} 493 | m_Enabled: 1 494 | m_EditorHideFlags: 0 495 | m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} 496 | m_Name: 497 | m_EditorClassIdentifier: 498 | m_IgnoreReversedGraphics: 1 499 | m_BlockingObjects: 0 500 | m_BlockingMask: 501 | serializedVersion: 2 502 | m_Bits: 4294967295 503 | --- !u!114 &689889533 504 | MonoBehaviour: 505 | m_ObjectHideFlags: 0 506 | m_CorrespondingSourceObject: {fileID: 0} 507 | m_PrefabInstance: {fileID: 0} 508 | m_PrefabAsset: {fileID: 0} 509 | m_GameObject: {fileID: 689889530} 510 | m_Enabled: 1 511 | m_EditorHideFlags: 0 512 | m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} 513 | m_Name: 514 | m_EditorClassIdentifier: 515 | m_UiScaleMode: 1 516 | m_ReferencePixelsPerUnit: 100 517 | m_ScaleFactor: 1 518 | m_ReferenceResolution: {x: 1920, y: 1080} 519 | m_ScreenMatchMode: 0 520 | m_MatchWidthOrHeight: 0 521 | m_PhysicalUnit: 3 522 | m_FallbackScreenDPI: 96 523 | m_DefaultSpriteDPI: 96 524 | m_DynamicPixelsPerUnit: 1 525 | --- !u!223 &689889534 526 | Canvas: 527 | m_ObjectHideFlags: 0 528 | m_CorrespondingSourceObject: {fileID: 0} 529 | m_PrefabInstance: {fileID: 0} 530 | m_PrefabAsset: {fileID: 0} 531 | m_GameObject: {fileID: 689889530} 532 | m_Enabled: 1 533 | serializedVersion: 3 534 | m_RenderMode: 0 535 | m_Camera: {fileID: 0} 536 | m_PlaneDistance: 100 537 | m_PixelPerfect: 0 538 | m_ReceivesEvents: 1 539 | m_OverrideSorting: 0 540 | m_OverridePixelPerfect: 0 541 | m_SortingBucketNormalizedSize: 0 542 | m_AdditionalShaderChannelsFlag: 0 543 | m_SortingLayerID: 0 544 | m_SortingOrder: 0 545 | m_TargetDisplay: 0 546 | --- !u!224 &689889535 547 | RectTransform: 548 | m_ObjectHideFlags: 0 549 | m_CorrespondingSourceObject: {fileID: 0} 550 | m_PrefabInstance: {fileID: 0} 551 | m_PrefabAsset: {fileID: 0} 552 | m_GameObject: {fileID: 689889530} 553 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 554 | m_LocalPosition: {x: 0, y: 0, z: 0} 555 | m_LocalScale: {x: 0, y: 0, z: 0} 556 | m_Children: 557 | - {fileID: 1053727430} 558 | m_Father: {fileID: 0} 559 | m_RootOrder: 4 560 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 561 | m_AnchorMin: {x: 0, y: 0} 562 | m_AnchorMax: {x: 0, y: 0} 563 | m_AnchoredPosition: {x: 0, y: 0} 564 | m_SizeDelta: {x: 0, y: 0} 565 | m_Pivot: {x: 0, y: 0} 566 | --- !u!1 &705507993 567 | GameObject: 568 | m_ObjectHideFlags: 0 569 | m_CorrespondingSourceObject: {fileID: 0} 570 | m_PrefabInstance: {fileID: 0} 571 | m_PrefabAsset: {fileID: 0} 572 | serializedVersion: 6 573 | m_Component: 574 | - component: {fileID: 705507995} 575 | - component: {fileID: 705507994} 576 | m_Layer: 0 577 | m_Name: Directional Light 578 | m_TagString: Untagged 579 | m_Icon: {fileID: 0} 580 | m_NavMeshLayer: 0 581 | m_StaticEditorFlags: 0 582 | m_IsActive: 1 583 | --- !u!108 &705507994 584 | Light: 585 | m_ObjectHideFlags: 0 586 | m_CorrespondingSourceObject: {fileID: 0} 587 | m_PrefabInstance: {fileID: 0} 588 | m_PrefabAsset: {fileID: 0} 589 | m_GameObject: {fileID: 705507993} 590 | m_Enabled: 1 591 | serializedVersion: 9 592 | m_Type: 1 593 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 594 | m_Intensity: 1 595 | m_Range: 10 596 | m_SpotAngle: 30 597 | m_InnerSpotAngle: 21.80208 598 | m_CookieSize: 10 599 | m_Shadows: 600 | m_Type: 2 601 | m_Resolution: -1 602 | m_CustomResolution: -1 603 | m_Strength: 1 604 | m_Bias: 0.05 605 | m_NormalBias: 0.4 606 | m_NearPlane: 0.2 607 | m_CullingMatrixOverride: 608 | e00: 1 609 | e01: 0 610 | e02: 0 611 | e03: 0 612 | e10: 0 613 | e11: 1 614 | e12: 0 615 | e13: 0 616 | e20: 0 617 | e21: 0 618 | e22: 1 619 | e23: 0 620 | e30: 0 621 | e31: 0 622 | e32: 0 623 | e33: 1 624 | m_UseCullingMatrixOverride: 0 625 | m_Cookie: {fileID: 0} 626 | m_DrawHalo: 0 627 | m_Flare: {fileID: 0} 628 | m_RenderMode: 0 629 | m_CullingMask: 630 | serializedVersion: 2 631 | m_Bits: 4294967295 632 | m_RenderingLayerMask: 1 633 | m_Lightmapping: 1 634 | m_LightShadowCasterMode: 0 635 | m_AreaSize: {x: 1, y: 1} 636 | m_BounceIntensity: 1 637 | m_ColorTemperature: 6570 638 | m_UseColorTemperature: 0 639 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 640 | m_UseBoundingSphereOverride: 0 641 | m_ShadowRadius: 0 642 | m_ShadowAngle: 0 643 | --- !u!4 &705507995 644 | Transform: 645 | m_ObjectHideFlags: 0 646 | m_CorrespondingSourceObject: {fileID: 0} 647 | m_PrefabInstance: {fileID: 0} 648 | m_PrefabAsset: {fileID: 0} 649 | m_GameObject: {fileID: 705507993} 650 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 651 | m_LocalPosition: {x: 0, y: 3, z: 0} 652 | m_LocalScale: {x: 1, y: 1, z: 1} 653 | m_Children: [] 654 | m_Father: {fileID: 0} 655 | m_RootOrder: 1 656 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 657 | --- !u!1 &963194225 658 | GameObject: 659 | m_ObjectHideFlags: 0 660 | m_CorrespondingSourceObject: {fileID: 0} 661 | m_PrefabInstance: {fileID: 0} 662 | m_PrefabAsset: {fileID: 0} 663 | serializedVersion: 6 664 | m_Component: 665 | - component: {fileID: 963194228} 666 | - component: {fileID: 963194227} 667 | - component: {fileID: 963194226} 668 | m_Layer: 0 669 | m_Name: Main Camera 670 | m_TagString: MainCamera 671 | m_Icon: {fileID: 0} 672 | m_NavMeshLayer: 0 673 | m_StaticEditorFlags: 0 674 | m_IsActive: 1 675 | --- !u!81 &963194226 676 | AudioListener: 677 | m_ObjectHideFlags: 0 678 | m_CorrespondingSourceObject: {fileID: 0} 679 | m_PrefabInstance: {fileID: 0} 680 | m_PrefabAsset: {fileID: 0} 681 | m_GameObject: {fileID: 963194225} 682 | m_Enabled: 1 683 | --- !u!20 &963194227 684 | Camera: 685 | m_ObjectHideFlags: 0 686 | m_CorrespondingSourceObject: {fileID: 0} 687 | m_PrefabInstance: {fileID: 0} 688 | m_PrefabAsset: {fileID: 0} 689 | m_GameObject: {fileID: 963194225} 690 | m_Enabled: 1 691 | serializedVersion: 2 692 | m_ClearFlags: 1 693 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 694 | m_projectionMatrixMode: 1 695 | m_GateFitMode: 2 696 | m_FOVAxisMode: 0 697 | m_SensorSize: {x: 36, y: 24} 698 | m_LensShift: {x: 0, y: 0} 699 | m_FocalLength: 50 700 | m_NormalizedViewPortRect: 701 | serializedVersion: 2 702 | x: 0 703 | y: 0 704 | width: 1 705 | height: 1 706 | near clip plane: 0.3 707 | far clip plane: 1000 708 | field of view: 60 709 | orthographic: 0 710 | orthographic size: 5 711 | m_Depth: -1 712 | m_CullingMask: 713 | serializedVersion: 2 714 | m_Bits: 4294967295 715 | m_RenderingPath: -1 716 | m_TargetTexture: {fileID: 0} 717 | m_TargetDisplay: 0 718 | m_TargetEye: 3 719 | m_HDR: 1 720 | m_AllowMSAA: 1 721 | m_AllowDynamicResolution: 0 722 | m_ForceIntoRT: 0 723 | m_OcclusionCulling: 1 724 | m_StereoConvergence: 10 725 | m_StereoSeparation: 0.022 726 | --- !u!4 &963194228 727 | Transform: 728 | m_ObjectHideFlags: 0 729 | m_CorrespondingSourceObject: {fileID: 0} 730 | m_PrefabInstance: {fileID: 0} 731 | m_PrefabAsset: {fileID: 0} 732 | m_GameObject: {fileID: 963194225} 733 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 734 | m_LocalPosition: {x: 0, y: 1, z: -10} 735 | m_LocalScale: {x: 1, y: 1, z: 1} 736 | m_Children: [] 737 | m_Father: {fileID: 0} 738 | m_RootOrder: 0 739 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 740 | --- !u!1 &1053727429 741 | GameObject: 742 | m_ObjectHideFlags: 0 743 | m_CorrespondingSourceObject: {fileID: 0} 744 | m_PrefabInstance: {fileID: 0} 745 | m_PrefabAsset: {fileID: 0} 746 | serializedVersion: 6 747 | m_Component: 748 | - component: {fileID: 1053727430} 749 | - component: {fileID: 1053727432} 750 | - component: {fileID: 1053727431} 751 | m_Layer: 5 752 | m_Name: Container 753 | m_TagString: Untagged 754 | m_Icon: {fileID: 0} 755 | m_NavMeshLayer: 0 756 | m_StaticEditorFlags: 0 757 | m_IsActive: 0 758 | --- !u!224 &1053727430 759 | RectTransform: 760 | m_ObjectHideFlags: 0 761 | m_CorrespondingSourceObject: {fileID: 0} 762 | m_PrefabInstance: {fileID: 0} 763 | m_PrefabAsset: {fileID: 0} 764 | m_GameObject: {fileID: 1053727429} 765 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 766 | m_LocalPosition: {x: 0, y: 0, z: 0} 767 | m_LocalScale: {x: 1, y: 1, z: 1} 768 | m_Children: 769 | - {fileID: 202526666} 770 | - {fileID: 1352327076} 771 | m_Father: {fileID: 689889535} 772 | m_RootOrder: 0 773 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 774 | m_AnchorMin: {x: 0, y: 0} 775 | m_AnchorMax: {x: 1, y: 1} 776 | m_AnchoredPosition: {x: 0, y: 0} 777 | m_SizeDelta: {x: 0, y: 0} 778 | m_Pivot: {x: 0.5, y: 0.5} 779 | --- !u!114 &1053727431 780 | MonoBehaviour: 781 | m_ObjectHideFlags: 0 782 | m_CorrespondingSourceObject: {fileID: 0} 783 | m_PrefabInstance: {fileID: 0} 784 | m_PrefabAsset: {fileID: 0} 785 | m_GameObject: {fileID: 1053727429} 786 | m_Enabled: 1 787 | m_EditorHideFlags: 0 788 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 789 | m_Name: 790 | m_EditorClassIdentifier: 791 | m_Material: {fileID: 0} 792 | m_Color: {r: 0, g: 0, b: 0, a: 0.4} 793 | m_RaycastTarget: 1 794 | m_OnCullStateChanged: 795 | m_PersistentCalls: 796 | m_Calls: [] 797 | m_Sprite: {fileID: 0} 798 | m_Type: 0 799 | m_PreserveAspect: 0 800 | m_FillCenter: 1 801 | m_FillMethod: 4 802 | m_FillAmount: 1 803 | m_FillClockwise: 1 804 | m_FillOrigin: 0 805 | m_UseSpriteMesh: 0 806 | m_PixelsPerUnitMultiplier: 1 807 | --- !u!222 &1053727432 808 | CanvasRenderer: 809 | m_ObjectHideFlags: 0 810 | m_CorrespondingSourceObject: {fileID: 0} 811 | m_PrefabInstance: {fileID: 0} 812 | m_PrefabAsset: {fileID: 0} 813 | m_GameObject: {fileID: 1053727429} 814 | m_CullTransparentMesh: 0 815 | --- !u!1 &1352327075 816 | GameObject: 817 | m_ObjectHideFlags: 0 818 | m_CorrespondingSourceObject: {fileID: 0} 819 | m_PrefabInstance: {fileID: 0} 820 | m_PrefabAsset: {fileID: 0} 821 | serializedVersion: 6 822 | m_Component: 823 | - component: {fileID: 1352327076} 824 | - component: {fileID: 1352327077} 825 | - component: {fileID: 1352327078} 826 | m_Layer: 5 827 | m_Name: InputText 828 | m_TagString: Untagged 829 | m_Icon: {fileID: 0} 830 | m_NavMeshLayer: 0 831 | m_StaticEditorFlags: 0 832 | m_IsActive: 1 833 | --- !u!224 &1352327076 834 | RectTransform: 835 | m_ObjectHideFlags: 0 836 | m_CorrespondingSourceObject: {fileID: 0} 837 | m_PrefabInstance: {fileID: 0} 838 | m_PrefabAsset: {fileID: 0} 839 | m_GameObject: {fileID: 1352327075} 840 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 841 | m_LocalPosition: {x: 0, y: 0, z: 0} 842 | m_LocalScale: {x: 1, y: 1, z: 1} 843 | m_Children: [] 844 | m_Father: {fileID: 1053727430} 845 | m_RootOrder: 1 846 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 847 | m_AnchorMin: {x: 0, y: 0} 848 | m_AnchorMax: {x: 1, y: 0} 849 | m_AnchoredPosition: {x: 0, y: 10} 850 | m_SizeDelta: {x: -20, y: 30} 851 | m_Pivot: {x: 0.5, y: 0} 852 | --- !u!222 &1352327077 853 | CanvasRenderer: 854 | m_ObjectHideFlags: 0 855 | m_CorrespondingSourceObject: {fileID: 0} 856 | m_PrefabInstance: {fileID: 0} 857 | m_PrefabAsset: {fileID: 0} 858 | m_GameObject: {fileID: 1352327075} 859 | m_CullTransparentMesh: 0 860 | --- !u!114 &1352327078 861 | MonoBehaviour: 862 | m_ObjectHideFlags: 0 863 | m_CorrespondingSourceObject: {fileID: 0} 864 | m_PrefabInstance: {fileID: 0} 865 | m_PrefabAsset: {fileID: 0} 866 | m_GameObject: {fileID: 1352327075} 867 | m_Enabled: 1 868 | m_EditorHideFlags: 0 869 | m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} 870 | m_Name: 871 | m_EditorClassIdentifier: 872 | m_Material: {fileID: 0} 873 | m_Color: {r: 1, g: 1, b: 1, a: 1} 874 | m_RaycastTarget: 1 875 | m_OnCullStateChanged: 876 | m_PersistentCalls: 877 | m_Calls: [] 878 | m_FontData: 879 | m_Font: {fileID: 12800000, guid: bf12c688961730246ad42c1312512913, type: 3} 880 | m_FontSize: 24 881 | m_FontStyle: 0 882 | m_BestFit: 0 883 | m_MinSize: 10 884 | m_MaxSize: 40 885 | m_Alignment: 3 886 | m_AlignByGeometry: 0 887 | m_RichText: 0 888 | m_HorizontalOverflow: 1 889 | m_VerticalOverflow: 1 890 | m_LineSpacing: 1 891 | m_Text: 892 | --- !u!1 &1429601301 893 | GameObject: 894 | m_ObjectHideFlags: 0 895 | m_CorrespondingSourceObject: {fileID: 0} 896 | m_PrefabInstance: {fileID: 0} 897 | m_PrefabAsset: {fileID: 0} 898 | serializedVersion: 6 899 | m_Component: 900 | - component: {fileID: 1429601303} 901 | - component: {fileID: 1429601302} 902 | m_Layer: 0 903 | m_Name: Test 904 | m_TagString: Untagged 905 | m_Icon: {fileID: 0} 906 | m_NavMeshLayer: 0 907 | m_StaticEditorFlags: 0 908 | m_IsActive: 1 909 | --- !u!114 &1429601302 910 | MonoBehaviour: 911 | m_ObjectHideFlags: 0 912 | m_CorrespondingSourceObject: {fileID: 0} 913 | m_PrefabInstance: {fileID: 0} 914 | m_PrefabAsset: {fileID: 0} 915 | m_GameObject: {fileID: 1429601301} 916 | m_Enabled: 1 917 | m_EditorHideFlags: 0 918 | m_Script: {fileID: 11500000, guid: c10f452ae72adaa49a87950aa69fc781, type: 3} 919 | m_Name: 920 | m_EditorClassIdentifier: 921 | --- !u!4 &1429601303 922 | Transform: 923 | m_ObjectHideFlags: 0 924 | m_CorrespondingSourceObject: {fileID: 0} 925 | m_PrefabInstance: {fileID: 0} 926 | m_PrefabAsset: {fileID: 0} 927 | m_GameObject: {fileID: 1429601301} 928 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 929 | m_LocalPosition: {x: 248, y: 158.5, z: 0} 930 | m_LocalScale: {x: 1, y: 1, z: 1} 931 | m_Children: [] 932 | m_Father: {fileID: 0} 933 | m_RootOrder: 3 934 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 935 | --- !u!1 &1492572160 936 | GameObject: 937 | m_ObjectHideFlags: 0 938 | m_CorrespondingSourceObject: {fileID: 0} 939 | m_PrefabInstance: {fileID: 0} 940 | m_PrefabAsset: {fileID: 0} 941 | serializedVersion: 6 942 | m_Component: 943 | - component: {fileID: 1492572163} 944 | - component: {fileID: 1492572162} 945 | - component: {fileID: 1492572161} 946 | m_Layer: 0 947 | m_Name: EventSystem 948 | m_TagString: Untagged 949 | m_Icon: {fileID: 0} 950 | m_NavMeshLayer: 0 951 | m_StaticEditorFlags: 0 952 | m_IsActive: 1 953 | --- !u!114 &1492572161 954 | MonoBehaviour: 955 | m_ObjectHideFlags: 0 956 | m_CorrespondingSourceObject: {fileID: 0} 957 | m_PrefabInstance: {fileID: 0} 958 | m_PrefabAsset: {fileID: 0} 959 | m_GameObject: {fileID: 1492572160} 960 | m_Enabled: 1 961 | m_EditorHideFlags: 0 962 | m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} 963 | m_Name: 964 | m_EditorClassIdentifier: 965 | m_HorizontalAxis: Horizontal 966 | m_VerticalAxis: Vertical 967 | m_SubmitButton: Submit 968 | m_CancelButton: Cancel 969 | m_InputActionsPerSecond: 10 970 | m_RepeatDelay: 0.5 971 | m_ForceModuleActive: 0 972 | --- !u!114 &1492572162 973 | MonoBehaviour: 974 | m_ObjectHideFlags: 0 975 | m_CorrespondingSourceObject: {fileID: 0} 976 | m_PrefabInstance: {fileID: 0} 977 | m_PrefabAsset: {fileID: 0} 978 | m_GameObject: {fileID: 1492572160} 979 | m_Enabled: 1 980 | m_EditorHideFlags: 0 981 | m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} 982 | m_Name: 983 | m_EditorClassIdentifier: 984 | m_FirstSelected: {fileID: 0} 985 | m_sendNavigationEvents: 1 986 | m_DragThreshold: 10 987 | --- !u!4 &1492572163 988 | Transform: 989 | m_ObjectHideFlags: 0 990 | m_CorrespondingSourceObject: {fileID: 0} 991 | m_PrefabInstance: {fileID: 0} 992 | m_PrefabAsset: {fileID: 0} 993 | m_GameObject: {fileID: 1492572160} 994 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 995 | m_LocalPosition: {x: 0, y: 0, z: 0} 996 | m_LocalScale: {x: 1, y: 1, z: 1} 997 | m_Children: [] 998 | m_Father: {fileID: 0} 999 | m_RootOrder: 2 1000 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 1001 | --- !u!1 &1670941962 1002 | GameObject: 1003 | m_ObjectHideFlags: 0 1004 | m_CorrespondingSourceObject: {fileID: 0} 1005 | m_PrefabInstance: {fileID: 0} 1006 | m_PrefabAsset: {fileID: 0} 1007 | serializedVersion: 6 1008 | m_Component: 1009 | - component: {fileID: 1670941963} 1010 | - component: {fileID: 1670941966} 1011 | - component: {fileID: 1670941965} 1012 | - component: {fileID: 1670941964} 1013 | m_Layer: 5 1014 | m_Name: Viewport 1015 | m_TagString: Untagged 1016 | m_Icon: {fileID: 0} 1017 | m_NavMeshLayer: 0 1018 | m_StaticEditorFlags: 0 1019 | m_IsActive: 1 1020 | --- !u!224 &1670941963 1021 | RectTransform: 1022 | m_ObjectHideFlags: 0 1023 | m_CorrespondingSourceObject: {fileID: 0} 1024 | m_PrefabInstance: {fileID: 0} 1025 | m_PrefabAsset: {fileID: 0} 1026 | m_GameObject: {fileID: 1670941962} 1027 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 1028 | m_LocalPosition: {x: 0, y: 0, z: 0} 1029 | m_LocalScale: {x: 1, y: 1, z: 1} 1030 | m_Children: 1031 | - {fileID: 152642163} 1032 | m_Father: {fileID: 202526666} 1033 | m_RootOrder: 0 1034 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 1035 | m_AnchorMin: {x: 0.5, y: 0.5} 1036 | m_AnchorMax: {x: 0.5, y: 0.5} 1037 | m_AnchoredPosition: {x: 0, y: 0} 1038 | m_SizeDelta: {x: 100, y: 100} 1039 | m_Pivot: {x: 0, y: 1} 1040 | --- !u!114 &1670941964 1041 | MonoBehaviour: 1042 | m_ObjectHideFlags: 0 1043 | m_CorrespondingSourceObject: {fileID: 0} 1044 | m_PrefabInstance: {fileID: 0} 1045 | m_PrefabAsset: {fileID: 0} 1046 | m_GameObject: {fileID: 1670941962} 1047 | m_Enabled: 1 1048 | m_EditorHideFlags: 0 1049 | m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} 1050 | m_Name: 1051 | m_EditorClassIdentifier: 1052 | m_ShowMaskGraphic: 0 1053 | --- !u!114 &1670941965 1054 | MonoBehaviour: 1055 | m_ObjectHideFlags: 0 1056 | m_CorrespondingSourceObject: {fileID: 0} 1057 | m_PrefabInstance: {fileID: 0} 1058 | m_PrefabAsset: {fileID: 0} 1059 | m_GameObject: {fileID: 1670941962} 1060 | m_Enabled: 1 1061 | m_EditorHideFlags: 0 1062 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 1063 | m_Name: 1064 | m_EditorClassIdentifier: 1065 | m_Material: {fileID: 0} 1066 | m_Color: {r: 1, g: 1, b: 1, a: 1} 1067 | m_RaycastTarget: 1 1068 | m_OnCullStateChanged: 1069 | m_PersistentCalls: 1070 | m_Calls: [] 1071 | m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} 1072 | m_Type: 1 1073 | m_PreserveAspect: 0 1074 | m_FillCenter: 1 1075 | m_FillMethod: 4 1076 | m_FillAmount: 1 1077 | m_FillClockwise: 1 1078 | m_FillOrigin: 0 1079 | m_UseSpriteMesh: 0 1080 | m_PixelsPerUnitMultiplier: 1 1081 | --- !u!222 &1670941966 1082 | CanvasRenderer: 1083 | m_ObjectHideFlags: 0 1084 | m_CorrespondingSourceObject: {fileID: 0} 1085 | m_PrefabInstance: {fileID: 0} 1086 | m_PrefabAsset: {fileID: 0} 1087 | m_GameObject: {fileID: 1670941962} 1088 | m_CullTransparentMesh: 0 1089 | --- !u!1 &1927497581 1090 | GameObject: 1091 | m_ObjectHideFlags: 0 1092 | m_CorrespondingSourceObject: {fileID: 0} 1093 | m_PrefabInstance: {fileID: 0} 1094 | m_PrefabAsset: {fileID: 0} 1095 | serializedVersion: 6 1096 | m_Component: 1097 | - component: {fileID: 1927497582} 1098 | - component: {fileID: 1927497584} 1099 | - component: {fileID: 1927497583} 1100 | m_Layer: 5 1101 | m_Name: Handle 1102 | m_TagString: Untagged 1103 | m_Icon: {fileID: 0} 1104 | m_NavMeshLayer: 0 1105 | m_StaticEditorFlags: 0 1106 | m_IsActive: 1 1107 | --- !u!224 &1927497582 1108 | RectTransform: 1109 | m_ObjectHideFlags: 0 1110 | m_CorrespondingSourceObject: {fileID: 0} 1111 | m_PrefabInstance: {fileID: 0} 1112 | m_PrefabAsset: {fileID: 0} 1113 | m_GameObject: {fileID: 1927497581} 1114 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 1115 | m_LocalPosition: {x: 0, y: 0, z: 0} 1116 | m_LocalScale: {x: 1, y: 1, z: 1} 1117 | m_Children: [] 1118 | m_Father: {fileID: 360971373} 1119 | m_RootOrder: 0 1120 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 1121 | m_AnchorMin: {x: 0, y: 0} 1122 | m_AnchorMax: {x: 0.2, y: 1} 1123 | m_AnchoredPosition: {x: 0, y: 0} 1124 | m_SizeDelta: {x: 20, y: 20} 1125 | m_Pivot: {x: 0.5, y: 0.5} 1126 | --- !u!114 &1927497583 1127 | MonoBehaviour: 1128 | m_ObjectHideFlags: 0 1129 | m_CorrespondingSourceObject: {fileID: 0} 1130 | m_PrefabInstance: {fileID: 0} 1131 | m_PrefabAsset: {fileID: 0} 1132 | m_GameObject: {fileID: 1927497581} 1133 | m_Enabled: 1 1134 | m_EditorHideFlags: 0 1135 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 1136 | m_Name: 1137 | m_EditorClassIdentifier: 1138 | m_Material: {fileID: 0} 1139 | m_Color: {r: 0.3, g: 0.3, b: 0.3, a: 1} 1140 | m_RaycastTarget: 1 1141 | m_OnCullStateChanged: 1142 | m_PersistentCalls: 1143 | m_Calls: [] 1144 | m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} 1145 | m_Type: 1 1146 | m_PreserveAspect: 0 1147 | m_FillCenter: 1 1148 | m_FillMethod: 4 1149 | m_FillAmount: 1 1150 | m_FillClockwise: 1 1151 | m_FillOrigin: 0 1152 | m_UseSpriteMesh: 0 1153 | m_PixelsPerUnitMultiplier: 1 1154 | --- !u!222 &1927497584 1155 | CanvasRenderer: 1156 | m_ObjectHideFlags: 0 1157 | m_CorrespondingSourceObject: {fileID: 0} 1158 | m_PrefabInstance: {fileID: 0} 1159 | m_PrefabAsset: {fileID: 0} 1160 | m_GameObject: {fileID: 1927497581} 1161 | m_CullTransparentMesh: 0 1162 | -------------------------------------------------------------------------------- /Sample/Scripts/Test.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public class Test : MonoBehaviour 4 | { 5 | private void Awake() 6 | { 7 | CheatConsole.OnOpen.AddListener(() => Debug.Log("Console opened")); 8 | CheatConsole.OnClose.AddListener(() => Debug.Log("Console closed")); 9 | } 10 | 11 | [Cheat] 12 | private static void CheatMethod(int test) 13 | { 14 | CheatConsole.Log("Hello " + test); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.pyton.cheatconsole", 3 | "version": "1.0.0", 4 | "displayName": "Cheat Console", 5 | "description": "Add easily a cheat console in your game to debug it with cheat methods.\n\n**Usage**\n Add a [Cheat] attribute above static methods you want to use as cheat, and create a cheat console in your scene (GameObject > ConsoleCommand).\n\n**Important**\nThe cheat console is available only in Unity editor and development build, but no code are generated in release build, so don't worry players can't enable it by modifying your game's assemblies with dnSpy for example.", 6 | "unity": "2018.1", 7 | "keywords": [ 8 | "cheat", 9 | "cheatconsole", 10 | "console", 11 | "command" 12 | ], 13 | "author": { 14 | "name": "Ben Pyton", 15 | "url": "https://github.com/BenPyton" 16 | }, 17 | "samples": [ 18 | { 19 | "displayName": "Sample", 20 | "description": "Simple scene with a cheat console and a test script", 21 | "path": "Sample" 22 | } 23 | ] 24 | } --------------------------------------------------------------------------------