From 0ff49997e80f66fdd82c97050c8024566539831e Mon Sep 17 00:00:00 2001 From: Jakub Szczyrk Date: Thu, 26 Sep 2024 09:54:22 +0200 Subject: [PATCH 1/5] Reset input to default settings after success submit --- Runtime/Scripts/BugReportUI.cs | 77 +++++++++++++++++-------- Runtime/Scripts/DefaultSettings.cs | 26 +++++++++ Runtime/Scripts/DefaultSettings.cs.meta | 11 ++++ Runtime/Scripts/MessagePanelUI.cs | 1 - 4 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 Runtime/Scripts/DefaultSettings.cs create mode 100644 Runtime/Scripts/DefaultSettings.cs.meta diff --git a/Runtime/Scripts/BugReportUI.cs b/Runtime/Scripts/BugReportUI.cs index 19d74b6..941081d 100644 --- a/Runtime/Scripts/BugReportUI.cs +++ b/Runtime/Scripts/BugReportUI.cs @@ -15,11 +15,11 @@ namespace BetaHub public class BugReportUI : MonoBehaviour { private static BugReportUI instance; - + public GameObject bugReportPanel; public TMP_InputField descriptionField; public TMP_InputField stepsField; - + public Toggle IncludeVideoToggle; public Toggle IncludeScreenshotToggle; public Toggle IncludePlayerLogToggle; @@ -35,11 +35,11 @@ public class BugReportUI : MonoBehaviour public string projectID; - #if ENABLE_INPUT_SYSTEM +#if ENABLE_INPUT_SYSTEM public InputAction shortcutAction = new InputAction("BugReportShortcut", binding: "/f12"); - #else +#else public KeyCode shortcutKey = KeyCode.F12; - #endif +#endif public bool includePlayerLog = true; public bool includeVideo = true; @@ -59,12 +59,14 @@ public class BugReportUI : MonoBehaviour // if true, the report is being uploaded, some processes should be paused private bool _uploadingReport = false; + private DefaultSettings _defaultSettings; + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void InitializeLogger() { logger = new Logger(); } - + void Awake() { if (instance == null) @@ -75,34 +77,38 @@ void Awake() { Destroy(gameObject); } + + + messagePanel.SetActive(false); + SaveDefaultValue(); } void OnEnable() { - #if ENABLE_INPUT_SYSTEM +#if ENABLE_INPUT_SYSTEM if (IsNewInputSystemEnabled()) { shortcutAction.Enable(); shortcutAction.performed += OnShortcutActionPerformed; } - #endif +#endif } void OnDisable() { - #if ENABLE_INPUT_SYSTEM +#if ENABLE_INPUT_SYSTEM if (IsNewInputSystemEnabled()) { shortcutAction.performed -= OnShortcutActionPerformed; shortcutAction.Disable(); } - #endif +#endif } - + void Start() { _gameRecorder = GetComponent(); - + bugReportPanel.SetActive(false); submitButton.onClick.AddListener(SubmitBugReport); closeButton.onClick.AddListener(() => @@ -163,13 +169,13 @@ void Update() { RestoreCursorState(); } - - #if !ENABLE_INPUT_SYSTEM + +#if !ENABLE_INPUT_SYSTEM if (shortcutKey != KeyCode.None && Input.GetKeyDown(shortcutKey)) { StartCoroutine(CaptureScreenshotAndShowUI()); } - #endif +#endif } private bool SholdBeRecordingVideo() @@ -201,7 +207,7 @@ private void RestoreCursorState() } } - #if ENABLE_INPUT_SYSTEM +#if ENABLE_INPUT_SYSTEM void OnShortcutActionPerformed(InputAction.CallbackContext context) { StartCoroutine(CaptureScreenshotAndShowUI()); @@ -212,7 +218,7 @@ bool IsNewInputSystemEnabled() // Check if the new input system is enabled return InputSystem.settings != null; } - #endif +#endif IEnumerator CaptureScreenshotAndShowUI() { @@ -224,7 +230,7 @@ IEnumerator CaptureScreenshotAndShowUI() // wait for another frame yield return null; - + bugReportPanel.SetActive(true); } @@ -274,7 +280,7 @@ IEnumerator PostIssue(string description, string steps) { url += "/"; } - + url += "projects/" + projectID + "/issues.json"; using (UnityWebRequest www = UnityWebRequest.Post(url, form)) @@ -307,6 +313,7 @@ IEnumerator PostIssue(string description, string steps) bugReportPanel.SetActive(false); }); + ResetToDefaultValue(); yield return UploadAdditionalFiles(issueId); } } @@ -361,7 +368,7 @@ IEnumerator UploadAdditionalFiles(string issueId) _logFiles.Clear(); } - + // // Upload performance samples (if any) // string samplesFile = Application.persistentDataPath + "/samples.csv"; // GetComponent().SaveSamplesToFile(samplesFile); @@ -370,7 +377,7 @@ IEnumerator UploadAdditionalFiles(string issueId) // yield return StartCoroutine(UploadFile(issueId, "log_files", "log_file[file]", samplesFile, "text/csv")); // File.Delete(samplesFile); // } - + // Upload video file if (includeVideo && IncludeVideoToggle.isOn) { @@ -418,12 +425,36 @@ IEnumerator UploadFile(string issueId, string endpoint, string fieldName, string } } - class ErrorMessage { + // Method to save the current values as defaults + void SaveDefaultValue() + { + _defaultSettings = new DefaultSettings( + descriptionField.text, + stepsField.text, + IncludeVideoToggle.isOn, + IncludeScreenshotToggle.isOn, + IncludePlayerLogToggle.isOn + ); + } + + // Method to reset fields to their default values + void ResetToDefaultValue() + { + descriptionField.text = _defaultSettings.description; + stepsField.text = _defaultSettings.steps; + IncludeVideoToggle.isOn = _defaultSettings.includeVideo; + IncludeScreenshotToggle.isOn = _defaultSettings.includeScreenshot; + IncludePlayerLogToggle.isOn = _defaultSettings.includePlayerLog; + } + + class ErrorMessage + { public string error; public string status; } - class IssueResponse { + class IssueResponse + { public string id; } diff --git a/Runtime/Scripts/DefaultSettings.cs b/Runtime/Scripts/DefaultSettings.cs new file mode 100644 index 0000000..1197cd2 --- /dev/null +++ b/Runtime/Scripts/DefaultSettings.cs @@ -0,0 +1,26 @@ +#if ENABLE_INPUT_SYSTEM +using UnityEngine.InputSystem; +#endif + +namespace BetaHub +{ + [System.Serializable] + public class DefaultSettings + { + public string description; + public string steps; + public bool includeVideo; + public bool includeScreenshot; + public bool includePlayerLog; + + // Constructor to initialize default values + public DefaultSettings(string description, string steps, bool includeVideo, bool includeScreenshot, bool includePlayerLog) + { + this.description = description; + this.steps = steps; + this.includeVideo = includeVideo; + this.includeScreenshot = includeScreenshot; + this.includePlayerLog = includePlayerLog; + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/DefaultSettings.cs.meta b/Runtime/Scripts/DefaultSettings.cs.meta new file mode 100644 index 0000000..8a70584 --- /dev/null +++ b/Runtime/Scripts/DefaultSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39cc2874a7d2847d1b99d47b226c758d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/MessagePanelUI.cs b/Runtime/Scripts/MessagePanelUI.cs index 2e2fba5..fed83ef 100644 --- a/Runtime/Scripts/MessagePanelUI.cs +++ b/Runtime/Scripts/MessagePanelUI.cs @@ -19,7 +19,6 @@ public class MessagePanelUI : MonoBehaviour void Start() { - gameObject.SetActive(false); messagePanelOkButton.onClick.AddListener(CloseMessagePanel); } From 033ce2e0456f8dd58d2ed6174f6a2506c8061b3d Mon Sep 17 00:00:00 2001 From: Jakub Szczyrk Date: Thu, 26 Sep 2024 09:59:27 +0200 Subject: [PATCH 2/5] Implement DrawBox filter system for video recording and UI handling --- Runtime/Scripts/Drawbox.cs | 45 +++++++++++++ Runtime/Scripts/Drawbox.cs.meta | 11 ++++ Runtime/Scripts/GameRecorder.cs | 5 ++ Runtime/Scripts/ITextureFilter.cs | 8 +++ Runtime/Scripts/ITextureFilter.cs.meta | 11 ++++ Runtime/Scripts/RectTransformFilterHandler.cs | 43 ++++++++++++ .../RectTransformFilterHandler.cs.meta | 11 ++++ Runtime/Scripts/TextureFilterManager.cs | 65 +++++++++++++++++++ Runtime/Scripts/TextureFilterManager.cs.meta | 11 ++++ Runtime/Scripts/TexturePainter.cs | 18 ++--- 10 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 Runtime/Scripts/Drawbox.cs create mode 100644 Runtime/Scripts/Drawbox.cs.meta create mode 100644 Runtime/Scripts/ITextureFilter.cs create mode 100644 Runtime/Scripts/ITextureFilter.cs.meta create mode 100644 Runtime/Scripts/RectTransformFilterHandler.cs create mode 100644 Runtime/Scripts/RectTransformFilterHandler.cs.meta create mode 100644 Runtime/Scripts/TextureFilterManager.cs create mode 100644 Runtime/Scripts/TextureFilterManager.cs.meta diff --git a/Runtime/Scripts/Drawbox.cs b/Runtime/Scripts/Drawbox.cs new file mode 100644 index 0000000..fcb08ea --- /dev/null +++ b/Runtime/Scripts/Drawbox.cs @@ -0,0 +1,45 @@ +using UnityEngine; + +namespace BetaHub +{ + public class DrawBox : ITextureFilter + { + // DrawBox settings + private int xPosition; + private int yPosition; + private int boxWidth; + private int boxHeight; + private Color boxColor; + + // Constructor to initialize DrawBox filter + public DrawBox(int x, int y, int width, int height, Color color) + { + if (width <= 0 || height <= 0) + { + throw new System.ArgumentException("Width and height must be positive values."); + } + + xPosition = x; + yPosition = y; + boxWidth = width; + boxHeight = height; + boxColor = color; + } + + public DrawBox(Vector2Int position, Vector2Int size, Color color) + : this(position.x, position.y, size.x, size.y, color) { } + + // Apply the filter on the texture + public void ApplyFilter(TexturePainter texture) + { + if (texture == null) + { + throw new System.ArgumentNullException(nameof(texture), "TexturePainter cannot be null."); + } + + // Draw the rectangle on the texture + texture.DrawRectangle(xPosition, yPosition, boxWidth, boxHeight, boxColor); + } + + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Drawbox.cs.meta b/Runtime/Scripts/Drawbox.cs.meta new file mode 100644 index 0000000..25fe37d --- /dev/null +++ b/Runtime/Scripts/Drawbox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e7d908c1f1bf4956b472b2fa694d623 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/GameRecorder.cs b/Runtime/Scripts/GameRecorder.cs index 590a60c..83661dd 100644 --- a/Runtime/Scripts/GameRecorder.cs +++ b/Runtime/Scripts/GameRecorder.cs @@ -26,6 +26,9 @@ public class GameRecorder : MonoBehaviour private float fps; private float deltaTime = 0.0f; + public TextureFilterManager TextureFilterManager => _textureFilterManager; + private TextureFilterManager _textureFilterManager = new TextureFilterManager(); + void Start() { // Adjust the game resolution to be divisible by 2 @@ -125,6 +128,8 @@ private IEnumerator CaptureFrames() // texturePainter.DrawNumber(50, 10, (int) fps, Color.white, 4); texturePainter.DrawNumber(5, 5, (int)fps, Color.white, 2); + _textureFilterManager.ApplyFilters(texturePainter); + byte[] frameData = screenShot.GetRawTextureData(); videoEncoder.AddFrame(frameData); } diff --git a/Runtime/Scripts/ITextureFilter.cs b/Runtime/Scripts/ITextureFilter.cs new file mode 100644 index 0000000..e0cc111 --- /dev/null +++ b/Runtime/Scripts/ITextureFilter.cs @@ -0,0 +1,8 @@ +namespace BetaHub +{ + public interface ITextureFilter + { + // Now it applies the filter on the given texture + public void ApplyFilter(TexturePainter texture); + } +} \ No newline at end of file diff --git a/Runtime/Scripts/ITextureFilter.cs.meta b/Runtime/Scripts/ITextureFilter.cs.meta new file mode 100644 index 0000000..a902597 --- /dev/null +++ b/Runtime/Scripts/ITextureFilter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df89ad62de92f488baa923f41fa567fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/RectTransformFilterHandler.cs b/Runtime/Scripts/RectTransformFilterHandler.cs new file mode 100644 index 0000000..7f8da5e --- /dev/null +++ b/Runtime/Scripts/RectTransformFilterHandler.cs @@ -0,0 +1,43 @@ +using UnityEngine; +using BetaHub; + +public class RectTransformFilterHandler : MonoBehaviour +{ + public GameRecorder gameRecorder; + public string keyFilter = "box"; // Filter key + public Color boxColor = Color.red; // Color of the box + + private RectTransform _rectTransform; + + // Initialize the component + private void Awake() + { + _rectTransform = GetComponent(); + } + + // Activate the filter when the component is enabled + private void OnEnable() + { + Rect rect = GetScreenCoordinates(_rectTransform); + gameRecorder.TextureFilterManager.AddFilter(keyFilter, new DrawBox(Vector2Int.RoundToInt(rect.position), Vector2Int.RoundToInt(rect.size), boxColor)); + } + + // Remove the filter when the component is disabled + private void OnDisable() + { + gameRecorder.TextureFilterManager.RemoveFilter(keyFilter); + } + + // Calculate the screen coordinates of the UI component + public Rect GetScreenCoordinates(RectTransform uiElement) + { + var worldCorners = new Vector3[4]; + uiElement.GetWorldCorners(worldCorners); + var result = new Rect( + worldCorners[0].x, + worldCorners[0].y, + worldCorners[2].x - worldCorners[0].x, + worldCorners[2].y - worldCorners[0].y); + return result; + } +} \ No newline at end of file diff --git a/Runtime/Scripts/RectTransformFilterHandler.cs.meta b/Runtime/Scripts/RectTransformFilterHandler.cs.meta new file mode 100644 index 0000000..8b0cdeb --- /dev/null +++ b/Runtime/Scripts/RectTransformFilterHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ed00b94780034c7787d9c40f2a3b106 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/TextureFilterManager.cs b/Runtime/Scripts/TextureFilterManager.cs new file mode 100644 index 0000000..f24c354 --- /dev/null +++ b/Runtime/Scripts/TextureFilterManager.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; + +namespace BetaHub +{ + public class TextureFilterManager + { + // Dictionary to store filters with a unique string ID + private Dictionary filters = new Dictionary(); + + // Method to add a filter to the dictionary with a unique string ID + public void AddFilter(string id, ITextureFilter filter) + { + if (string.IsNullOrEmpty(id)) + { + throw new System.ArgumentException("Filter ID cannot be null or empty.", nameof(id)); + } + if (filter == null) + { + throw new System.ArgumentNullException(nameof(filter), "Filter cannot be null."); + } + + filters[id] = filter; + } + + // Method to remove a filter based on its string ID + public void RemoveFilter(string id) + { + if (string.IsNullOrEmpty(id)) + { + throw new System.ArgumentException("Filter ID cannot be null or empty.", nameof(id)); + } + + if (filters.ContainsKey(id)) + { + filters.Remove(id); + } + } + + // Method to get the filter by string ID + public ITextureFilter GetFilter(string id) + { + if (string.IsNullOrEmpty(id)) + { + throw new System.ArgumentException("Filter ID cannot be null or empty.", nameof(id)); + } + + filters.TryGetValue(id, out ITextureFilter filter); + return filter; + } + + // Method to apply all filters on the provided texture + public void ApplyFilters(TexturePainter texture) + { + if (texture == null) + { + throw new System.ArgumentNullException(nameof(texture), "TexturePainter cannot be null."); + } + + foreach (var filter in filters.Values) + { + filter.ApplyFilter(texture); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/TextureFilterManager.cs.meta b/Runtime/Scripts/TextureFilterManager.cs.meta new file mode 100644 index 0000000..9db2d40 --- /dev/null +++ b/Runtime/Scripts/TextureFilterManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e8edbdba616348eca206b3fec4c6ea7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/TexturePainter.cs b/Runtime/Scripts/TexturePainter.cs index 1633dc1..aa7152d 100644 --- a/Runtime/Scripts/TexturePainter.cs +++ b/Runtime/Scripts/TexturePainter.cs @@ -1,3 +1,4 @@ +using System.Linq; using UnityEngine; namespace BetaHub @@ -115,21 +116,10 @@ public void DrawVerticalProgressBar(int x, int y, int width, int height, float p texture.Apply(); } - private void DrawRectangle(int x, int y, int width, int height, Color color) + public void DrawRectangle(int x, int y, int width, int height, Color color) { - // Draw top and bottom borders - for (int i = 0; i < width; i++) - { - texture.SetPixel(x + i, y, color); - texture.SetPixel(x + i, y + height - 1, color); - } - - // Draw left and right borders - for (int i = 0; i < height; i++) - { - texture.SetPixel(x, y + i, color); - texture.SetPixel(x + width - 1, y + i, color); - } + Color[] colors = Enumerable.Repeat(color, width * height).ToArray(); + texture.SetPixels(x, y, width, height, colors); } public void DrawNumber(int x, int y, int number, Color color, int scale = 1) From 5481ccb7a6246b63abbb1cce020402308c8eb2c1 Mon Sep 17 00:00:00 2001 From: Jakub Szczyrk Date: Thu, 26 Sep 2024 10:47:11 +0200 Subject: [PATCH 3/5] Fix screenshot capture to ensure filters (e.g., DrawBox) are applied correctly --- Runtime/Scripts/BugReportUI.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/BugReportUI.cs b/Runtime/Scripts/BugReportUI.cs index 941081d..a422b70 100644 --- a/Runtime/Scripts/BugReportUI.cs +++ b/Runtime/Scripts/BugReportUI.cs @@ -222,9 +222,18 @@ bool IsNewInputSystemEnabled() IEnumerator CaptureScreenshotAndShowUI() { - // Capture screenshot + // Wait for the end of the frame to ensure the screen is fully rendered + yield return new WaitForEndOfFrame(); + + // Capture the screenshot as a texture after the frame has been rendered + Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture(); + + // Apply the filters (including DrawBox) to the RenderTexture + Texture2D screenshot = ApplyFiltersToScreenshot(texture); + + // Save the screenshot to a file string screenshotPath = Application.persistentDataPath + "/screenshot.png"; - ScreenCapture.CaptureScreenshot(screenshotPath); + File.WriteAllBytes(screenshotPath, screenshot.EncodeToPNG()); AddScreenshot(screenshotPath, true); @@ -234,6 +243,15 @@ IEnumerator CaptureScreenshotAndShowUI() bugReportPanel.SetActive(true); } + // Method to apply filters (DrawBox or others) to the screenshot + private Texture2D ApplyFiltersToScreenshot(Texture2D texture) + { + // Use the TextureFilterManager to apply filters, including DrawBox + _gameRecorder.TextureFilterManager.ApplyFilters(new TexturePainter(texture)); + + return texture; + } + // Sets screenshot path to be uploaded. Useful on manual invocation of bug report UI. public void AddScreenshot(string path, bool removeAfterUpload) { @@ -301,6 +319,10 @@ IEnumerator PostIssue(string description, string steps) ErrorMessage message = JsonUtility.FromJson(www.downloadHandler.text); messagePanelUI.ShowMessagePanel("Error", message.error); } + else + { + messagePanelUI.ShowMessagePanel("Error", "An unexpected error occurred. Please try again later."); + } } else { From 84428643e7c8b553aba77f01a0c063bfb5619ed2 Mon Sep 17 00:00:00 2001 From: Jakub Szczyrk Date: Thu, 26 Sep 2024 10:53:56 +0200 Subject: [PATCH 4/5] Refactor: Change includePlayerLog and includeVideo to private access --- Runtime/Scripts/BugReportUI.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Runtime/Scripts/BugReportUI.cs b/Runtime/Scripts/BugReportUI.cs index a422b70..eefc201 100644 --- a/Runtime/Scripts/BugReportUI.cs +++ b/Runtime/Scripts/BugReportUI.cs @@ -41,12 +41,11 @@ public class BugReportUI : MonoBehaviour public KeyCode shortcutKey = KeyCode.F12; #endif - public bool includePlayerLog = true; - public bool includeVideo = true; - public UnityEvent OnBugReportWindowShown; public UnityEvent OnBugReportWindowHidden; + private bool includePlayerLog = true; + private bool includeVideo = true; private List _screenshots = new List(); private List _logFiles = new List(); From 6449314a873f220643c38198764840425aa66bb4 Mon Sep 17 00:00:00 2001 From: Jakub Szczyrk Date: Thu, 3 Oct 2024 09:16:15 +0200 Subject: [PATCH 5/5] Refactoring --- Runtime/Scripts/RectTransformFilterHandler.cs | 124 +++++++++++++----- 1 file changed, 91 insertions(+), 33 deletions(-) diff --git a/Runtime/Scripts/RectTransformFilterHandler.cs b/Runtime/Scripts/RectTransformFilterHandler.cs index 7f8da5e..7d58ea9 100644 --- a/Runtime/Scripts/RectTransformFilterHandler.cs +++ b/Runtime/Scripts/RectTransformFilterHandler.cs @@ -1,43 +1,101 @@ using UnityEngine; -using BetaHub; -public class RectTransformFilterHandler : MonoBehaviour +namespace BetaHub { - public GameRecorder gameRecorder; - public string keyFilter = "box"; // Filter key - public Color boxColor = Color.red; // Color of the box + public class RectTransformFilterHandler : MonoBehaviour + { + [Tooltip("Reference to the GameRecorder object. If not set, it will try to find one in the scene.")] + public GameRecorder gameRecorder; - private RectTransform _rectTransform; + [Tooltip("Unique key to identify this filter in the GameRecorder.")] + public string keyFilter = "box"; - // Initialize the component - private void Awake() - { - _rectTransform = GetComponent(); - } + [Tooltip("Color of the rectangle drawn on screen.")] + public Color boxColor = Color.red; - // Activate the filter when the component is enabled - private void OnEnable() - { - Rect rect = GetScreenCoordinates(_rectTransform); - gameRecorder.TextureFilterManager.AddFilter(keyFilter, new DrawBox(Vector2Int.RoundToInt(rect.position), Vector2Int.RoundToInt(rect.size), boxColor)); - } + // Private field to cache RectTransform + private RectTransform _rectTransform; - // Remove the filter when the component is disabled - private void OnDisable() - { - gameRecorder.TextureFilterManager.RemoveFilter(keyFilter); - } + // Initialize the component + private void Awake() + { + _rectTransform = GetComponent(); - // Calculate the screen coordinates of the UI component - public Rect GetScreenCoordinates(RectTransform uiElement) - { - var worldCorners = new Vector3[4]; - uiElement.GetWorldCorners(worldCorners); - var result = new Rect( - worldCorners[0].x, - worldCorners[0].y, - worldCorners[2].x - worldCorners[0].x, - worldCorners[2].y - worldCorners[0].y); - return result; + // If RectTransform is missing, print an error and disable this component + if (_rectTransform == null) + { + Debug.LogError($"{nameof(RectTransform)} component is missing on {gameObject.name}. Disabling {nameof(RectTransformFilterHandler)}."); + enabled = false; // Disable this script to avoid further errors + return; + } + + // Check if gameRecorder is not assigned + if (gameRecorder == null) + { + // Print a warning and try to find the GameRecorder in the scene + Debug.LogWarning("gameRecorder is not set! Trying to find GameRecorder by lookup."); + gameRecorder = FindObjectOfType(); + + // If still null, print an error to avoid null reference exceptions later + if (gameRecorder == null) + { + Debug.LogError("GameRecorder could not be found! Make sure GameRecorder is in the scene and assigned."); + } + } + } + + // Activate the filter when the component is enabled + private void OnEnable() + { + // Ensure we have a valid gameRecorder before proceeding + if (!ValidateGameRecorder()) return; + + // Get screen coordinates of the RectTransform + Rect rect = GetScreenCoordinates(_rectTransform); + + // Add the filter to the GameRecorder's TextureFilterManager + gameRecorder.TextureFilterManager.AddFilter( + keyFilter, + new DrawBox( + Vector2Int.RoundToInt(rect.position), + Vector2Int.RoundToInt(rect.size), + boxColor + ) + ); + } + + // Remove the filter when the component is disabled + private void OnDisable() + { + // Ensure we have a valid gameRecorder before proceeding + if (!ValidateGameRecorder()) return; + + // Remove the filter when the component is disabled + gameRecorder.TextureFilterManager.RemoveFilter(keyFilter); + } + + // Validate if the gameRecorder is properly assigned + private bool ValidateGameRecorder() + { + if (gameRecorder == null) + { + Debug.LogError($"{nameof(gameRecorder)} is null. Cannot proceed with filter handling."); + return false; + } + return true; + } + + // Calculate the screen coordinates of the UI component + public Rect GetScreenCoordinates(RectTransform uiElement) + { + var worldCorners = new Vector3[4]; + uiElement.GetWorldCorners(worldCorners); + var result = new Rect( + worldCorners[0].x, + worldCorners[0].y, + worldCorners[2].x - worldCorners[0].x, + worldCorners[2].y - worldCorners[0].y); + return result; + } } } \ No newline at end of file