### Coroutine Management with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Starts and stops coroutines using UniverseLib's RuntimeHelper. Ensure a coroutine method is defined to be started. ```csharp Coroutine routine = RuntimeHelper.StartCoroutine(MyCoroutine()); // Stop the coroutine RuntimeHelper.StopCoroutine(routine); ``` -------------------------------- ### Begin and End Key Rebinding with InputManager Source: https://github.com/sinai-dev/universelib/wiki/InputManager Use InputManager.BeginRebind to start the rebinding process and InputManager.EndRebind to stop it. The OnSelection callback provides feedback on the key pressed, and OnFinished is called when rebinding is complete, potentially with a null value if no key was bound. ```csharp void OnBeginRebindPressed() { InputManager.BeginRebind(OnSelection, OnFinished); } void OnEndRebindPressed() { InputManager.EndRebind(); } void OnSelection(KeyCode pressed) { // Perhaps update a displayed label with the pressed key to give the user some feedback } void OnFinished(KeyCode? bound) { // The bound key may be null, indicating the user didn't press anything. } ``` -------------------------------- ### Get Actual Object Type Source: https://github.com/sinai-dev/universelib/wiki/ReflectionUtility Retrieves the underlying type of an object, including deobfuscation for IL2CPP games. ```csharp object.GetActualType() ``` -------------------------------- ### Parse Utility for Type Parsing Source: https://context7.com/sinai-dev/universelib/llms.txt ParseUtility facilitates parsing of primitive and common Unity types from strings, useful for handling user input. It includes methods to check parseability, perform parsing with error handling, and generate example input strings. ```csharp using System; using UnityEngine; using UniverseLib.Utility; public class ParseExamples { void ParsingExamples() { // Check if a type can be parsed bool canParse = ParseUtility.CanParse(typeof(Vector3)); // true bool canParseInt = ParseUtility.CanParse(); // true // Parse primitive types if (ParseUtility.TryParse("42", typeof(int), out object intResult, out Exception ex)) Console.WriteLine($"Parsed int: {intResult}"); // 42 // Parse Unity Vector types (space-separated values) if (ParseUtility.TryParse("10.5 20.3", out Vector2 vec2, out ex)) Console.WriteLine($"Vector2: {vec2}"); // (10.5, 20.3) if (ParseUtility.TryParse("1 2 3", out Vector3 vec3, out ex)) Console.WriteLine($"Vector3: {vec3}"); // (1, 2, 3) if (ParseUtility.TryParse("1 2 3 4", out Vector4 vec4, out ex)) Console.WriteLine($"Vector4: {vec4}"); // (1, 2, 3, 4) // Parse Quaternion (as euler angles or quaternion components) if (ParseUtility.TryParse("0 90 0", out Quaternion quat, out ex)) Console.WriteLine($"Quaternion: {quat}"); // Euler angles 0, 90, 0 // Parse Rect (x y width height) if (ParseUtility.TryParse("10 20 100 50", out Rect rect, out ex)) Console.WriteLine($"Rect: {rect}"); // x:10, y:20, width:100, height:50 // Parse Color (r g b [a], values 0-1) if (ParseUtility.TryParse("1 0 0 1", out Color color, out ex)) Console.WriteLine($"Color: {color}"); // Red // Parse Color32 (r g b [a], values 0-255) if (ParseUtility.TryParse("255 128 0 255", out Color32 color32, out ex)) Console.WriteLine($"Color32: {color32}"); // Orange // Parse enums if (ParseUtility.TryParse("UpperLeft", typeof(TextAnchor), out object anchor, out ex)) Console.WriteLine($"TextAnchor: {anchor}"); // TextAnchor.UpperLeft // Parse LayerMask if (ParseUtility.TryParse("256", out LayerMask mask, out ex)) Console.WriteLine($"LayerMask: {mask.value}"); // 256 } void ToStringExamples() { // Format objects back to parseable string format Vector3 position = new(1.5f, 2.5f, 3.5f); string posString = ParseUtility.ToStringForInput(position, typeof(Vector3)); Console.WriteLine(posString); // "1.5 2.5 3.5" Color myColor = Color.red; string colorString = ParseUtility.ToStringForInput(myColor, typeof(Color)); Console.WriteLine(colorString); // "1 0 0 1" } void ExampleInputExamples() { // Get example input strings for UI placeholders string vec2Example = ParseUtility.GetExampleInput(); Console.WriteLine(vec2Example); // "0 0" string colorExample = ParseUtility.GetExampleInput(); Console.WriteLine(colorExample); // "0 0 0 0" string rectExample = ParseUtility.GetExampleInput(typeof(Rect)); Console.WriteLine(rectExample); // "0 0 0 0" } } ``` -------------------------------- ### Get Actual Type with ReflectionExtensions Source: https://context7.com/sinai-dev/universelib/llms.txt Use GetActualType() for IL2CPP-safe retrieval of an object's underlying type, especially when dealing with boxed types. ```csharp using System; using UniverseLib; public class ExtensionExamples { void ActualTypeExample() { object obj = new UnityEngine.GameObject("Test"); // Get the actual underlying type (works correctly with IL2CPP boxing) Type actualType = obj.GetActualType(); Console.WriteLine(actualType.Name); // GameObject } void TryCastExample() { object obj = new UnityEngine.UI.Button(); // IL2CPP-safe casting var selectable = obj.TryCast(typeof(UnityEngine.UI.Selectable)); if (selectable != null) Console.WriteLine("Successfully cast to Selectable"); } } ``` -------------------------------- ### Initialize UniverseLib with full configuration Source: https://github.com/sinai-dev/universelib/wiki/Initialization Use this overload when UI features are required or specific startup parameters need to be defined. The onInitialized callback executes after the startup delay. ```csharp void MyModEntryPoint() { float startupDelay = 1f; UniverseLib.Config.UniverseLibConfig config = new() { Disable_EventSystem_Override = false, // or null Force_Unlock_Mouse = true, // or null Unhollowed_Modules_Folder = System.IO.Path.Combine("Some", "Path", "To", "Modules") // or null }; UniverseLib.Universe.Init(startupDelay, OnInitialized, LogHandler, config); } void OnInitialized() { // ... } void LogHandler(string message, LogType type) { // ... } ``` -------------------------------- ### Universe.Init Source: https://context7.com/sinai-dev/universelib/llms.txt Initializes the UniverseLib library, setting up core utilities like ReflectionUtility, RuntimeHelper, and the UI system. ```APIDOC ## Universe.Init ### Description Initializes the UniverseLib library. This must be called before using any other features. It sets up internal managers and starts the initialization coroutine. ### Method Static Method ### Parameters - **startupDelay** (float) - Optional - Time in seconds to wait before initializing InputManager and UniversalUI. - **onInitialized** (Action) - Optional - Callback invoked when initialization is complete. - **logHandler** (Action) - Optional - Delegate to handle internal library logs. - **config** (UniverseLibConfig) - Optional - Configuration object to customize library behavior (e.g., mouse unlocking, event system overrides). ``` -------------------------------- ### Initialize UniverseLib with default settings Source: https://github.com/sinai-dev/universelib/wiki/Initialization Use this method when UI features are not required. Multiple calls to Init are safe. ```csharp UniverseLib.Universe.Init(); ``` -------------------------------- ### Register a UIBase instance Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Use UniversalUI.RegisterUI to initialize a UI instance with a unique ID and an update callback. ```csharp public static UIBase UiBase { get; private set; } void Universe_OnInitialized() { UiBase = UniversalUI.RegisterUI("my.unique.ID", UiUpdate); } void UiUpdate() { // Called once per frame when your UI is being displayed. } ``` -------------------------------- ### Initialize UniverseLib Source: https://context7.com/sinai-dev/universelib/llms.txt Initialize the library to set up core utilities and UI systems. This must be called before accessing other library features. ```csharp using UniverseLib; using UniverseLib.Config; using UnityEngine; public class MyMod { void Start() { // Simple initialization without configuration Universe.Init(); // Full initialization with custom configuration float startupDelay = 1f; UniverseLibConfig config = new() { Disable_EventSystem_Override = false, Force_Unlock_Mouse = true, Unhollowed_Modules_Folder = System.IO.Path.Combine("Some", "Path", "To", "Modules"), Disable_Fallback_EventSystem_Search = false, Allow_UI_Selection_Outside_UIBase = false }; Universe.Init(startupDelay, OnInitialized, LogHandler, config); } void OnInitialized() { // UniverseLib is ready, safe to create UI elements Debug.Log("UniverseLib initialized!"); } void LogHandler(string message, LogType type) { // Handle UniverseLib internal logs Debug.Log($"[UniverseLib] {message}"); } } ``` -------------------------------- ### Create UI Elements with UIFactory Source: https://context7.com/sinai-dev/universelib/llms.txt Demonstrates the instantiation and layout configuration of various UI components including panels, labels, buttons, inputs, toggles, dropdowns, sliders, and scroll views. ```csharp using UnityEngine; using UnityEngine.UI; using UniverseLib.UI; using UniverseLib.UI.Models; public class UIFactoryExamples { GameObject parent; // Your panel's content root void CreateUIElements() { // Create a panel with content holder GameObject panel = UIFactory.CreatePanel("MainPanel", parent, out GameObject content, new Color(0.1f, 0.1f, 0.1f)); // Create a label Text label = UIFactory.CreateLabel(content, "MyLabel", "Welcome to my mod!", TextAnchor.MiddleCenter, Color.white, true, 16); UIFactory.SetLayoutElement(label.gameObject, minHeight: 30, flexibleWidth: 9999); // Create a button with click handler ButtonRef button = UIFactory.CreateButton(content, "ActionButton", "Do Something", new Color(0.2f, 0.4f, 0.2f)); UIFactory.SetLayoutElement(button.GameObject, minWidth: 150, minHeight: 35); button.OnClick += () => Debug.Log("Action performed!"); // Create an input field InputFieldRef inputField = UIFactory.CreateInputField(content, "TextInput", "Enter text..."); UIFactory.SetLayoutElement(inputField.UIRoot, minHeight: 30, flexibleWidth: 9999); inputField.OnValueChanged += (string text) => Debug.Log($"Input changed: {text}"); // Create a toggle GameObject toggleObj = UIFactory.CreateToggle(content, "MyToggle", out Toggle toggle, out Text toggleText); toggleText.text = "Enable Feature"; toggle.onValueChanged.AddListener((bool value) => Debug.Log($"Toggle: {value}")); // Create a dropdown GameObject dropdownObj = UIFactory.CreateDropdown(content, "MyDropdown", out Dropdown dropdown, "Select Option", 14, OnDropdownChanged, new[] { "Option A", "Option B", "Option C" }); UIFactory.SetLayoutElement(dropdownObj, minHeight: 30, flexibleWidth: 9999); // Create a slider GameObject sliderObj = UIFactory.CreateSlider(content, "VolumeSlider", out Slider slider); UIFactory.SetLayoutElement(sliderObj, minHeight: 25, flexibleWidth: 9999); slider.minValue = 0f; slider.maxValue = 100f; slider.onValueChanged.AddListener((float value) => Debug.Log($"Slider: {value}")); // Create horizontal/vertical layout groups GameObject hGroup = UIFactory.CreateHorizontalGroup(content, "ButtonRow", false, false, true, true, spacing: 5, padding: new Vector4(5, 5, 5, 5)); // Create a scroll view for non-pooled content GameObject scrollView = UIFactory.CreateScrollView(content, "MyScrollView", out GameObject scrollContent, out AutoSliderScrollbar scrollbar); UIFactory.SetLayoutElement(scrollView, minHeight: 200, flexibleWidth: 9999); } void OnDropdownChanged(int index) { Debug.Log($"Selected index: {index}"); } } ``` -------------------------------- ### Create ScrollPool and Initialize with DataSource Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Demonstrates creating a ScrollPool for custom cells and initializing it with an ICellPoolDataSource. Ensure all necessary interface members are implemented for MyCell and MyCellHandler. ```csharp public class MyCell : ICell { // Implement interface members... } public class MyCellHandler : ICellPoolDataSource { GameObject myPanel; GameObject panelContent; ScrollPool ScrollPool; void ConstructUI() { myPanel = UIFactory.CreatePanel("MyPanel", UiBase.RootObject, out panelContent, Color.black); ScrollPool = UIFactory.CreateScrollPool(panelContent, "MyScrollPool", out GameObject scrollRoot, out GameObject scrollContent, Color.blue); ScrollPool.Initialize(this); } // Implement interface members... } ``` -------------------------------- ### Create a custom PanelBase Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Inherit from PanelBase to define custom panel properties and content. Override ConstructPanelContent to add UI elements using UIFactory. ```csharp public class MyPanel : UniverseLib.UI.Panels.PanelBase { public MyPanel(UIBase owner) : base(owner) { } public override string Name => "My Panel"; public override int MinWidth => 100; public override int MinHeight => 200; public override Vector2 DefaultAnchorMin => new(0.25f, 0.25f); public override Vector2 DefaultAnchorMax => new(0.75f, 0.75f); public override bool CanDragAndResize => true; protected override void ConstructPanelContent() { Text myText = UIFactory.CreateLabel(ContentRoot, "myText", "Hello world"); UIFactory.SetLayoutElement(myText.gameObject, minWidth: 200, minHeight: 25); } // override other methods as desired } ``` -------------------------------- ### Instantiate a custom panel Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Create an instance of a PanelBase-derived class by passing the UIBase owner to the constructor. ```csharp UIBase myUIBase = UniversalUI.RegisterUI("me.mymod", MyUpdateMethod); MyPanel myPanel = new(myUIBase); ``` -------------------------------- ### Create Draggable Panels with PanelBase Source: https://context7.com/sinai-dev/universelib/llms.txt Inherit from PanelBase to create custom UI panels that support dragging and resizing. Use ConstructPanelContent to define the panel's layout and widgets. ```csharp using UnityEngine; using UnityEngine.UI; using UniverseLib.UI; using UniverseLib.UI.Panels; public class MyPanel : PanelBase { public MyPanel(UIBase owner) : base(owner) { } public override string Name => "My Custom Panel"; public override int MinWidth => 400; public override int MinHeight => 300; public override Vector2 DefaultAnchorMin => new(0.25f, 0.25f); public override Vector2 DefaultAnchorMax => new(0.75f, 0.75f); public override bool CanDragAndResize => true; protected override void ConstructPanelContent() { // Add a label to the panel Text titleText = UIFactory.CreateLabel(ContentRoot, "TitleLabel", "Hello World!"); UIFactory.SetLayoutElement(titleText.gameObject, minWidth: 200, minHeight: 25); // Add a button ButtonRef myButton = UIFactory.CreateButton(ContentRoot, "MyButton", "Click Me"); UIFactory.SetLayoutElement(myButton.GameObject, minWidth: 150, minHeight: 30); myButton.OnClick += () => Debug.Log("Button clicked!"); } } // Usage: // UIBase myUIBase = UniversalUI.RegisterUI("me.mymod", MyUpdateMethod); // MyPanel myPanel = new(myUIBase); ``` -------------------------------- ### Implementing and Using Object Pooling Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Create a class implementing IPooledObject to define poolable content, then use the Pool class to borrow and return instances. ```csharp public class MyPoolableObject : IPooledObject { public GameObject UIRoot { get; set; } // Used by ScrollPool. Not necessary if your object is not an ICell. public float DefaultHeight => -1; public GameObject CreateContent(GameObject parent) { UIRoot = UIFactory.CreateUIObject(...); } } static void Example() { var borrowed = Pool.Borrow(); Pool.Return(borrowed); } ``` -------------------------------- ### Creating ScriptableObjects with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Creates an instance of a ScriptableObject at runtime using RuntimeHelper. Requires the Type of the ScriptableObject to be created. ```csharp // Create ScriptableObject instance at runtime ScriptableObject instance = RuntimeHelper.CreateScriptable(typeof(MyScriptableObject)); ``` -------------------------------- ### Graphic Raycasting with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Performs a graphic raycast using a GraphicRaycaster, PointerEventData, and a list to store results. Populates the results list with RaycastResult objects. ```csharp // Perform graphic raycast RuntimeHelper.GraphicRaycast(raycaster, eventData, results); foreach (var result in results) Debug.Log($ ``` -------------------------------- ### Register a UIBase Source: https://context7.com/sinai-dev/universelib/llms.txt Register a UIBase instance to create a canvas for plugin UI elements. The UIBase provides the root GameObject and management for panels. ```csharp using UniverseLib.UI; public class MyModUI { public static UIBase UiBase { get; private set; } void OnUniverseInitialized() { // Register a UIBase with a unique ID and update callback UiBase = UniversalUI.RegisterUI("my.unique.mod.id", UiUpdate); } void UiUpdate() { // Called once per frame when your UI is displayed // Use this for UI-related updates } void ToggleUI() { // Enable or disable your UI UiBase.Enabled = !UiBase.Enabled; } } ``` -------------------------------- ### Implement ScrollPool with ICell and ICellPoolDataSource Source: https://context7.com/sinai-dev/universelib/llms.txt Define a custom cell class implementing ICell and a data source implementing ICellPoolDataSource to manage virtualized list items. ```csharp using UnityEngine; using UnityEngine.UI; using UniverseLib.UI; using UniverseLib.UI.Widgets.ScrollView; // Define your cell class public class MyCell : ICell { public GameObject UIRoot { get; set; } public RectTransform Rect { get; set; } public float DefaultHeight => 30f; public bool Enabled { get; set; } private Text label; public GameObject CreateContent(GameObject parent) { UIRoot = UIFactory.CreateUIObject("MyCell", parent); Rect = UIRoot.GetComponent(); // Create cell content label = UIFactory.CreateLabel(UIRoot, "CellLabel", ""); UIFactory.SetLayoutElement(label.gameObject, flexibleWidth: 9999, minHeight: 25); return UIRoot; } public void SetText(string text) { label.text = text; } public void Disable() { Enabled = false; UIRoot.SetActive(false); } public void Enable() { Enabled = true; UIRoot.SetActive(true); } } // Define your data source public class MyCellHandler : ICellPoolDataSource { public ScrollPool ScrollPool { get; private set; } private List dataItems = new(); public int ItemCount => dataItems.Count; public void Initialize(GameObject parent) { // Create the ScrollPool ScrollPool = UIFactory.CreateScrollPool(parent, "MyScrollPool", out GameObject scrollRoot, out GameObject scrollContent, new Color(0.1f, 0.1f, 0.1f)); UIFactory.SetLayoutElement(scrollRoot, flexibleWidth: 9999, flexibleHeight: 9999); ScrollPool.Initialize(this); // Add sample data for (int i = 0; i < 1000; i++) dataItems.Add($"Item {i}"); ScrollPool.Refresh(true, true); } public void OnCellBorrowed(MyCell cell) { } public void SetCell(MyCell cell, int index) { if (index < 0 || index >= dataItems.Count) { cell.Disable(); return; } cell.Enable(); cell.SetText(dataItems[index]); } } ``` -------------------------------- ### Generic Object Pooling - Bulk Operations Source: https://context7.com/sinai-dev/universelib/llms.txt Demonstrates borrowing multiple objects from the pool and then returning them all. This is useful for scenarios requiring several instances of a pooled object. ```csharp // Borrow multiple objects List objects = new(); for (int i = 0; i < 10; i++) { objects.Add(Pool.Borrow()); } // Return all objects foreach (var obj in objects) { Pool.Return(obj); } objects.Clear(); ``` -------------------------------- ### UniversalUI.RegisterUI Source: https://context7.com/sinai-dev/universelib/llms.txt Registers a new UI base instance to create a canvas for plugin UI elements. ```APIDOC ## UniversalUI.RegisterUI ### Description Registers a new UIBase instance, which provides a root GameObject, Canvas, and PanelManager for organizing UI elements. ### Method Static Method ### Parameters - **id** (string) - Required - A unique identifier for the UI instance. - **updateCallback** (Action) - Required - A method called once per frame when the UI is enabled. ``` -------------------------------- ### Perform Reflection and Type Lookups Source: https://context7.com/sinai-dev/universelib/llms.txt ReflectionUtility provides cross-platform reflection helpers, including support for IL2CPP-specific type lookups, collection iteration, and type caching. ```csharp using System; using System.Collections.Generic; using System.Reflection; using UniverseLib; public class ReflectionExamples { void TypeLookup() { // Find a type by its full name Type playerType = ReflectionUtility.GetTypeByName("MyGame.Player"); // Supports shorthand type names Type stringType = ReflectionUtility.GetTypeByName("string"); Type intType = ReflectionUtility.GetTypeByName("int"); // For generic types, use backtick notation Type listType = ReflectionUtility.GetTypeByName("System.Collections.Generic.List`1"); // Get all base types including the type itself Type[] baseTypes = ReflectionUtility.GetAllBaseTypes(typeof(UnityEngine.UI.Button)); // Returns: [Button, Selectable, UIBehaviour, MonoBehaviour, Behaviour, Component, Object] // Check if a type is an enumerable (including IL2CPP enumerables) bool isEnumerable = ReflectionUtility.IsEnumerable(typeof(List)); // true // Check if a type is a dictionary (including IL2CPP dictionaries) bool isDictionary = ReflectionUtility.IsDictionary(typeof(Dictionary)); // true } void EnumerableHelpers() { List myList = new() { "A", "B", "C" }; // Get enumerator (works for IL2CPP too) if (ReflectionUtility.TryGetEnumerator(myList, out var enumerator)) { while (enumerator.MoveNext()) Console.WriteLine(enumerator.Current); } // Get the entry type of a collection if (ReflectionUtility.TryGetEntryType(typeof(List), out Type entryType)) Console.WriteLine($"Entry type: {entryType.Name}"); // String } void DictionaryHelpers() { Dictionary myDict = new() { { "one", 1 }, { "two", 2 } }; // Get dictionary enumerator (works for IL2CPP too) if (ReflectionUtility.TryGetDictEnumerator(myDict, out var dictEnumerator)) { while (dictEnumerator.MoveNext()) { var entry = dictEnumerator.Current; Console.WriteLine($"{entry.Key}: {entry.Value}"); } } // Get key and value types if (ReflectionUtility.TryGetEntryTypes(typeof(Dictionary), out Type keyType, out Type valueType)) Console.WriteLine($"Key: {keyType.Name}, Value: {valueType.Name}"); // Key: String, Value: Int32 } void GetImplementations() { // Asynchronously find all implementations of a base type ReflectionUtility.GetImplementationsOf( typeof(UnityEngine.MonoBehaviour), (HashSet results) => { Console.WriteLine($"Found {results.Count} MonoBehaviour implementations"); foreach (Type type in results) Console.WriteLine($" - {type.FullName}"); }, allowAbstract: false, allowGeneric: false, allowEnum: false ); } void TypeCaching() { // Access all cached types in the AppDomain foreach (var kvp in ReflectionUtility.AllTypes) Console.WriteLine($"Type: {kvp.Key}"); // Get all namespaces foreach (string ns in ReflectionUtility.AllNamespaces) Console.WriteLine($"Namespace: {ns}"); // Listen for newly loaded types ReflectionUtility.OnTypeLoaded += (Type newType) => { Console.WriteLine($"New type loaded: {newType.FullName}"); }; } } ``` -------------------------------- ### Handle Input with InputManager Source: https://context7.com/sinai-dev/universelib/llms.txt Use InputManager to query mouse, keyboard, and button states consistently across Legacy Input and InputSystem. ```csharp using UnityEngine; using UniverseLib.Input; public class InputExample { void Update() { // Get mouse position (0,0 is bottom-left) Vector3 mousePos = InputManager.MousePosition; // Get mouse scroll delta Vector2 scrollDelta = InputManager.MouseScrollDelta; // Check key states (works with both Legacy and InputSystem) if (InputManager.GetKeyDown(KeyCode.F1)) Debug.Log("F1 pressed this frame"); if (InputManager.GetKey(KeyCode.LeftShift)) Debug.Log("Shift is held down"); if (InputManager.GetKeyUp(KeyCode.Escape)) Debug.Log("Escape released this frame"); // Check mouse button states // 0 = left, 1 = right, 2 = middle, 3 = back, 4 = forward if (InputManager.GetMouseButtonDown(0)) Debug.Log("Left mouse button pressed"); if (InputManager.GetMouseButton(1)) Debug.Log("Right mouse button held"); if (InputManager.GetMouseButtonUp(2)) Debug.Log("Middle mouse button released"); // Check which input system is active InputType currentInput = InputManager.CurrentType; Debug.Log($"Using input type: {currentInput}"); // Legacy, InputSystem, or None } void ResetInput() { // Reset all input axes InputManager.ResetInputAxes(); } } ``` -------------------------------- ### PanelBase Source: https://context7.com/sinai-dev/universelib/llms.txt Base class for creating custom draggable and resizable UI panels within the UniverseLib framework. ```APIDOC ## PanelBase ### Description Inherit from this class to create custom panels. Panels automatically integrate with the UIBase system and support dragging and resizing. ### Properties - **Name** (string) - The display name of the panel. - **MinWidth** (int) - Minimum width of the panel. - **MinHeight** (int) - Minimum height of the panel. - **DefaultAnchorMin** (Vector2) - Initial anchor minimum position. - **DefaultAnchorMax** (Vector2) - Initial anchor maximum position. - **CanDragAndResize** (bool) - Enables or disables panel manipulation. ### Methods - **ConstructPanelContent()** - Override this method to add UI elements (labels, buttons, etc.) to the panel's ContentRoot. ``` -------------------------------- ### Scene Root GameObjects with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Retrieves all root GameObjects within a given scene and counts them using RuntimeHelper. Requires a valid Scene object. ```csharp GameObject[] rootObjects = RuntimeHelper.GetRootGameObjects(activeScene); foreach (var obj in rootObjects) Debug.Log($ ``` -------------------------------- ### Setting Button Colors with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Automatically sets the color block for a Button component or sets individual colors for normal, highlighted, pressed, and disabled states using RuntimeHelper. Requires a Button component. ```csharp // Set color block automatically (generates highlight and pressed colors) RuntimeHelper.SetColorBlockAuto(button, new Color(0.2f, 0.4f, 0.2f)); // Set specific colors RuntimeHelper.SetColorBlock(button, normal: new Color(0.2f, 0.2f, 0.2f), highlighted: new Color(0.3f, 0.3f, 0.3f), pressed: new Color(0.15f, 0.15f, 0.15f), disabled: new Color(0.1f, 0.1f, 0.1f)); ``` -------------------------------- ### Layer Name Conversion with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Converts a layer index to its corresponding layer name using RuntimeHelper. Input is an integer representing the layer index. ```csharp // Get layer name from layer index string layerName = RuntimeHelper.LayerToName(5); Debug.Log($ ``` -------------------------------- ### Adding Components with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Adds a component of a specified runtime type to a GameObject using RuntimeHelper. Requires a GameObject and a Type object for the component. ```csharp // Add component with runtime type Type componentType = typeof(BoxCollider); BoxCollider collider = RuntimeHelper.AddComponent(obj, componentType); ``` -------------------------------- ### Create TransformTree ScrollPool Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) Initializes a ScrollPool for displaying a Transform hierarchy and creates a TransformTree instance. Remember to call TransformTree.RefreshData to update the tree, ideally not more than once per second. ```csharp transformScrollPool = UIFactory.CreateScrollPool(parent, "TransformTree", out GameObject transformObj, out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f)); TransformTree = new TransformTree(transformScrollPool, GetTransformEntries, OnTransformCellClicked); IEnumerable GetTransformEntries() { // ... } void OnTransformCellClicked(GameObject obj) { // ... } ``` -------------------------------- ### Generic Object Pooling - Borrow and Return Source: https://context7.com/sinai-dev/universelib/llms.txt Borrows an object from a pool of a specified type, creating a new one if the pool is empty. Returns the object to the pool when it's no longer needed. Requires the object to implement IPooledObject. ```csharp // Borrow an object from the pool (creates new if pool is empty) MyPoolableObject obj = Pool.Borrow(); // Use the object... obj.UIRoot.SetActive(true); // Return the object to the pool when done Pool.Return(obj); ``` -------------------------------- ### ConfigManager Configuration Source: https://github.com/sinai-dev/universelib/wiki/Config Details on the properties available within the ConfigManager class to control UniverseLib runtime features. ```APIDOC ## ConfigManager Properties ### Description The ConfigManager class allows mods to modify global settings that affect UniverseLib behavior at runtime. Properties are nullable; null values are ignored by the manager. ### Properties - **Disable_EventSystem_Override** (bool) - Optional - If true, disables UniverseLib from overriding the game's EventSystem when a UniversalUI is in use. - **Force_Unlock_Mouse** (bool) - Optional - If true, attempts to force-unlock the mouse cursor when a UniversalUI is in use. - **Unhollowed_Modules_Folder** (string) - Optional - For IL2CPP games, the full path to a folder containing Unhollowed assemblies. Used during initial startup. ``` -------------------------------- ### Implement Key Rebinding with InputManager Source: https://context7.com/sinai-dev/universelib/llms.txt Use InputManager to capture user key presses for rebinding hotkeys. Ensure InputManager.Rebinding is checked to prevent overlapping rebinding sessions. ```csharp using UnityEngine; using UniverseLib.Input; public class RebindingExample { private KeyCode currentHotkey = KeyCode.F5; void OnRebindButtonPressed() { if (InputManager.Rebinding) return; Debug.Log("Press a key to rebind..."); InputManager.BeginRebind(OnKeySelection, OnRebindFinished); } void OnCancelRebindPressed() { InputManager.EndRebind(); } void OnKeySelection(KeyCode pressedKey) { // Called whenever any key is pressed during rebinding // Use this to show feedback to the user Debug.Log($"Key pressed: {pressedKey}"); } void OnRebindFinished(KeyCode? boundKey) { // Called when EndRebind is invoked if (boundKey.HasValue) { currentHotkey = boundKey.Value; Debug.Log($"New hotkey set: {currentHotkey}"); } else { Debug.Log("Rebind cancelled, no key was pressed"); } } } ``` -------------------------------- ### Finding Objects with RuntimeHelper Source: https://context7.com/sinai-dev/universelib/llms.txt Finds all objects of a specified type, including inactive ones, using RuntimeHelper. Supports generic type parameters or explicit type objects. ```csharp // Find all objects of type (including inactive) Camera[] allCameras = RuntimeHelper.FindObjectsOfTypeAll(); Debug.Log($ ``` -------------------------------- ### Conditional NuGet Package References for Mono and IL2CPP Source: https://github.com/sinai-dev/universelib/wiki/Home Use conditional ItemGroups to include the correct UniverseLib NuGet package based on the build configuration (IL2CPP or Mono). Ensure your build configurations match the specified names. ```xml ``` -------------------------------- ### Find a Type by Name Source: https://github.com/sinai-dev/universelib/wiki/ReflectionUtility Locates a Type using its full name. Generic types require the `1 notation. ```csharp ReflectionUtility.GetTypeByName("Some.Full.Name"); ``` -------------------------------- ### Perform IL2CPP-Safe Casting Source: https://github.com/sinai-dev/universelib/wiki/ReflectionUtility Casts an object to a specified type safely within an IL2CPP context. ```csharp object.TryCast(type) ``` -------------------------------- ### Update TransformTree Data Periodically Source: https://github.com/sinai-dev/universelib/wiki/User-Interface-(UI) This code snippet shows how to periodically call TransformTree.RefreshData to update the displayed transform hierarchy. It's recommended to call this method no more than once per second to avoid performance issues. ```csharp float timeOfLastTransformTreeUpdate; void Update() { if (Time.realtimeSinceStartup - timeOfLastTransformTreeUpdate > 1f) { timeOfLastTransformTreeUpdate = Time.realtimeSinceStartup; TransformTree.RefreshData(true, false, false, false); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.