Skip to content

feat: exclude specific textures from compression by GUID #96

Merged
Limitex merged 9 commits into
mainfrom
feat/ignore-from-guid
Apr 9, 2026
Merged

feat: exclude specific textures from compression by GUID #96
Limitex merged 9 commits into
mainfrom
feat/ignore-from-guid

Conversation

@Limitex
Copy link
Copy Markdown
Owner

@Limitex Limitex commented Mar 29, 2026

Summary by CodeRabbit

  • New Features

    • Added an "Excluded Textures" inspector list to prevent selected textures from being compressed; entries can be added/removed via object picker and duplicates are blocked.
  • UI

    • Unified "Exclusions" section combines excluded textures and paths, shows per-path validity, and provides add/remove controls.
  • Preview / UX

    • Excluded textures appear as "Excluded texture" in previews; changes affect preview/caching behavior.
  • Documentation

    • Changelog updated to document the exclusion feature.
  • Tests

    • Added tests for collection, skip behavior, and settings-hash impact for excluded textures.

@Limitex Limitex self-assigned this Mar 29, 2026
Copilot AI review requested due to automatic review settings March 29, 2026 11:20
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the ability to exclude specific textures from compression by selecting them in the inspector (internally compared via asset GUID), and surfaces the new skip reason throughout preview + tests.

Changes:

  • Add ExcludedTextures list to TextureCompressor and inspector UI for managing it.
  • Pass excluded texture GUIDs into TextureCollector and skip matching textures with a new SkipReason.ExcludedTexture.
  • Extend preview/settings hashing and add/expand unit tests for excluded-texture behavior and GUID conversion.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Tests/Editor/UI/PreviewGeneratorTests.cs Adds settings-hash coverage for excluded texture list changes.
Tests/Editor/Core/Services/TextureCollectorTests.cs Adds constructor/collection behavior tests for excluded texture GUIDs + GUID conversion helper tests.
Tests/Editor/Core/Models/TextureInfoTests.cs Updates enum distinctness tests for the new skip reason.
Runtime/Components/TextureCompressor.cs Introduces serialized ExcludedTextures list on the config component.
Editor/TextureCompressor/UI/Sections/FilterSection.cs Adds inspector foldout UI to edit excluded textures list.
Editor/TextureCompressor/UI/Preview/PreviewSection.cs Displays user-facing skip reason text for excluded textures.
Editor/TextureCompressor/UI/Preview/PreviewGenerator.cs Converts excluded texture refs to GUIDs and includes them in collection + settings hash.
Editor/TextureCompressor/TextureCompressorEditor.cs Wires the new excluded-textures UI section into the inspector.
Editor/TextureCompressor/Core/Services/TextureCompressorService.cs Passes excluded texture GUIDs into TextureCollector for build/compress flow.
Editor/TextureCompressor/Core/Services/TextureCollector.cs Adds excluded GUID set, constructor parameter, skip logic, and ToAssetGuids helper.
Editor/TextureCompressor/Core/Models/TextureInfo.cs Adds SkipReason.ExcludedTexture.
CHANGELOG.md Documents the new excluded textures list feature under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Editor/TextureCompressor/Core/Services/TextureCollector.cs
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

Adds an inspector-driven exclusion list for textures: runtime config field for excluded textures, new SkipReason.ExcludedTexture, GUID-based exclusion in TextureCollector.EvaluateProcessability, editor UI and helper for managing exclusions, Preview hash updates to include excluded textures, and corresponding tests.

Changes

Cohort / File(s) Summary
Runtime config & model
Runtime/Components/TextureCompressor.cs, Editor/TextureCompressor/Core/Models/TextureInfo.cs
Added List<Texture2D> ExcludedTextures to runtime config and new enum value SkipReason.ExcludedTexture.
Collection & service logic
Editor/TextureCompressor/Core/Services/TextureCollector.cs, Editor/TextureCompressor/Core/Services/TextureCompressorService.cs
TextureCollector constructor updated to accept IEnumerable<Texture2D> excludedTextures and IEnumerable<FrozenTextureSettings> frozenTextures; builds internal excluded GUID set; EvaluateProcessability marks textures with SkipReason.ExcludedTexture. Service now forwards excluded textures/frozen settings rather than precomputed GUIDs.
Preview generation & UI
Editor/TextureCompressor/UI/Preview/PreviewGenerator.cs, Editor/TextureCompressor/UI/Preview/PreviewSection.cs
PreviewGenerator now receives excluded textures and includes excluded-list data in ComputeSettingsHash; Preview UI maps SkipReason.ExcludedTexture to "Excluded texture".
Editor inspector & filter UI
Editor/TextureCompressor/TextureCompressorEditor.cs, Editor/TextureCompressor/UI/Sections/FilterSection.cs
Inspector section renamed to a unified "Exclusions" foldout; FilterSection draws excluded textures and paths (object fields and path entries), prevents duplicate texture additions, and updated add/remove undo handling.
UI helper
Editor/Common/UI/Controls/ExclusionListDrawer.cs, Editor/Common/UI/Controls/ExclusionListDrawer.cs.meta
Added generic ExclusionListDrawer utility to render editable exclusion lists (draw, add, remove, validation, undo/dirty marking) and its .meta file.
Tests
Tests/Editor/Core/Models/TextureInfoTests.cs, Tests/Editor/Core/Services/TextureCollectorTests.cs, Tests/Editor/UI/PreviewGeneratorTests.cs
Updated tests to include ExcludedTexture enum, added TextureCollector tests for excluded-texture behavior (collectAll true/false), updated frozen-skip tests to use FrozenTextureSettings, and added PreviewGenerator hash tests for excluded textures.
Changelog
CHANGELOG.md
Added "Excluded Textures list" entry under Unreleased → Added.

Sequence Diagram

sequenceDiagram
    participant User as User/Inspector
    participant Editor as TextureCompressorEditor
    participant Filter as FilterSection
    participant Config as TextureCompressor (Config)
    participant Service as TextureCompressorService / PreviewGenerator
    participant Collector as TextureCollector
    participant Eval as EvaluateProcessability

    User->>Editor: Open inspector / edit exclusions
    Editor->>Filter: DrawExclusions(config, ref showSection)
    Filter->>User: Render excluded textures (ObjectField) and paths
    User->>Filter: Add/Remove/Modify Texture2D entry
    Filter->>Config: Undo.RecordObject + update ExcludedTextures
    Config->>Service: Start preview/compression
    Service->>Collector: new TextureCollector(..., excludedTextures, frozenTextures)
    Collector->>Eval: EvaluateProcessability(texture)
    Eval->>Eval: resolve texture asset GUID
    Eval-->>Collector: if GUID in excluded set => SkipReason.ExcludedTexture
    Collector-->>Service: return textures marked/skipped
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

🐰
I hopped the inspector, ears alert and bright,
Marked leaves (textures) that should be spared from squeeze,
GUIDs saved safe in my tiny list of light,
Skips now whisper "Excluded" with gentle ease,
A rabbit's nibble keeps the compressor pleased 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is completely empty, missing all required template sections including the PR type, description summary, related issue, changes list, breaking changes declaration, and testing verification. Add a comprehensive description following the template: specify PR type (✨ New feature), summarize the feature, list all changes, confirm backward compatibility, document testing performed, and mention any special reviewer focus areas.
Docstring Coverage ⚠️ Warning Docstring coverage is 30.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature being added: the ability to exclude specific textures from compression, which is the primary focus of all changes across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ignore-from-guid

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Tests/Editor/Core/Models/TextureInfoTests.cs (1)

167-181: ⚠️ Potential issue | 🟡 Minor

Test is missing UnknownUncompressedProperty enum value.

The SkipReason_AllValues_AreDistinct test doesn't include all enum members. UnknownUncompressedProperty exists in the enum (line 29 in TextureInfo.cs) but is missing from this test array.

🧪 Proposed fix to include all enum values
             var values = new[]
             {
                 SkipReason.None,
                 SkipReason.TooSmall,
                 SkipReason.FilteredByType,
                 SkipReason.FrozenSkip,
                 SkipReason.RuntimeGenerated,
                 SkipReason.ExcludedPath,
                 SkipReason.ExcludedTexture,
+                SkipReason.UnknownUncompressedProperty,
             };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/Editor/Core/Models/TextureInfoTests.cs` around lines 167 - 181, The
SkipReason_AllValues_AreDistinct test is missing the enum member
UnknownUncompressedProperty; update the values array in
TextureInfoTests.SkipReason_AllValues_AreDistinct to include
SkipReason.UnknownUncompressedProperty so the HashSet uniqueness assertion
covers all members of the SkipReason enum (defined in TextureInfo.cs).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@Tests/Editor/Core/Models/TextureInfoTests.cs`:
- Around line 167-181: The SkipReason_AllValues_AreDistinct test is missing the
enum member UnknownUncompressedProperty; update the values array in
TextureInfoTests.SkipReason_AllValues_AreDistinct to include
SkipReason.UnknownUncompressedProperty so the HashSet uniqueness assertion
covers all members of the SkipReason enum (defined in TextureInfo.cs).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 81ac39b9-caaf-4e59-9f94-50c213a42a6f

📥 Commits

Reviewing files that changed from the base of the PR and between d0f5144 and 96882bb.

📒 Files selected for processing (12)
  • CHANGELOG.md
  • Editor/TextureCompressor/Core/Models/TextureInfo.cs
  • Editor/TextureCompressor/Core/Services/TextureCollector.cs
  • Editor/TextureCompressor/Core/Services/TextureCompressorService.cs
  • Editor/TextureCompressor/TextureCompressorEditor.cs
  • Editor/TextureCompressor/UI/Preview/PreviewGenerator.cs
  • Editor/TextureCompressor/UI/Preview/PreviewSection.cs
  • Editor/TextureCompressor/UI/Sections/FilterSection.cs
  • Runtime/Components/TextureCompressor.cs
  • Tests/Editor/Core/Models/TextureInfoTests.cs
  • Tests/Editor/Core/Services/TextureCollectorTests.cs
  • Tests/Editor/UI/PreviewGeneratorTests.cs

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
Tests/Editor/Core/Services/TextureCollectorTests.cs (1)

1010-1126: Consider adding one integration test for replaced textures + excluded GUID.

You already validate ObjectRegistry replacement behavior for ExcludedPath/FrozenSkip later; adding the same scenario for excluded GUID would close a likely regression gap for this feature path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/Editor/Core/Services/TextureCollectorTests.cs` around lines 1010 -
1126, Add an integration test that verifies ObjectRegistry replacement is
honored when a texture's GUID is in the excluded GUID list: create an original
texture and a replacement texture, obtain the original's GUID, construct a
TextureCollector with that GUID in its excluded-guids parameter, register the
replacement via the ObjectRegistry replacement API for the original texture,
assign the original to a Material, call TextureCollector.CollectFromMaterials
(collectAll: true), and assert the collected dictionary contains the replacement
Texture2D (not the original), that the replacement entry IsProcessed is false,
and its SkipReason equals SkipReason.ExcludedTexture; reference
TextureCollector, CollectFromMaterials, ObjectRegistry (the register-replacement
method used elsewhere in tests), and SkipReason to locate the correct APIs.
Editor/Common/UI/Controls/ExclusionListDrawer.cs (1)

27-38: Consider adding null guards for required parameters.

The undoTarget and list parameters are critical for the method's operation. Passing null for list would cause a NullReferenceException at line 40 or 49, and null for undoTarget would cause issues with Undo.RecordObject. Adding early validation would provide clearer error messages.

🛡️ Optional: Add parameter validation
         )
         {
+            if (undoTarget == null)
+                throw new ArgumentNullException(nameof(undoTarget));
+            if (list == null)
+                throw new ArgumentNullException(nameof(list));
+
             int count = list.Count;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Editor/Common/UI/Controls/ExclusionListDrawer.cs` around lines 27 - 38, The
Draw<T> method should validate required inputs to avoid NullReferenceException
and Undo.RecordObject failures: at the top of Draw, check that 'list' and
'undoTarget' are not null and throw ArgumentNullException (or
ArgumentNullException(nameof(list)) / ArgumentNullException(nameof(undoTarget)))
with clear messages if they are null; keep the rest of the logic unchanged so
callers get a fast, descriptive failure rather than a later NRE when Draw uses
'list' or calls Undo.RecordObject on 'undoTarget'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Editor/Common/UI/Controls/ExclusionListDrawer.cs`:
- Around line 27-38: The Draw<T> method should validate required inputs to avoid
NullReferenceException and Undo.RecordObject failures: at the top of Draw, check
that 'list' and 'undoTarget' are not null and throw ArgumentNullException (or
ArgumentNullException(nameof(list)) / ArgumentNullException(nameof(undoTarget)))
with clear messages if they are null; keep the rest of the logic unchanged so
callers get a fast, descriptive failure rather than a later NRE when Draw uses
'list' or calls Undo.RecordObject on 'undoTarget'.

In `@Tests/Editor/Core/Services/TextureCollectorTests.cs`:
- Around line 1010-1126: Add an integration test that verifies ObjectRegistry
replacement is honored when a texture's GUID is in the excluded GUID list:
create an original texture and a replacement texture, obtain the original's
GUID, construct a TextureCollector with that GUID in its excluded-guids
parameter, register the replacement via the ObjectRegistry replacement API for
the original texture, assign the original to a Material, call
TextureCollector.CollectFromMaterials (collectAll: true), and assert the
collected dictionary contains the replacement Texture2D (not the original), that
the replacement entry IsProcessed is false, and its SkipReason equals
SkipReason.ExcludedTexture; reference TextureCollector, CollectFromMaterials,
ObjectRegistry (the register-replacement method used elsewhere in tests), and
SkipReason to locate the correct APIs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 18720b76-92c0-480c-882b-b85dcd73cdb4

📥 Commits

Reviewing files that changed from the base of the PR and between 96882bb and 752af6b.

📒 Files selected for processing (4)
  • Editor/Common/UI/Controls/ExclusionListDrawer.cs
  • Editor/Common/UI/Controls/ExclusionListDrawer.cs.meta
  • Editor/TextureCompressor/UI/Sections/FilterSection.cs
  • Tests/Editor/Core/Services/TextureCollectorTests.cs
✅ Files skipped from review due to trivial changes (1)
  • Editor/Common/UI/Controls/ExclusionListDrawer.cs.meta

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
Tests/Editor/Core/Services/TextureCollectorTests.cs (1)

1162-1167: Align null-frozen test body with its stated intent.

Line 1166 currently tests default optional-parameter behavior, not an explicit null frozenTextures argument. Pass frozenTextures: null explicitly to match the test name and avoid ambiguity.

Proposed test adjustment
 [Test]
 public void Constructor_WithNullFrozenTextures_DoesNotThrow()
 {
     Assert.DoesNotThrow(() =>
     {
-        var collector = new TextureCollector(64, 0, true, true, true, true, true);
+        var collector = new TextureCollector(
+            64,
+            0,
+            true,
+            true,
+            true,
+            true,
+            true,
+            excludedPathPrefixes: null,
+            excludedTextures: null,
+            frozenTextures: null
+        );
     });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Tests/Editor/Core/Services/TextureCollectorTests.cs` around lines 1162 -
1167, The test Constructor_WithNullFrozenTextures_DoesNotThrow currently relies
on default optional parameters instead of explicitly passing a null
frozenTextures; update the test body to call the TextureCollector constructor
with frozenTextures: null (e.g., new TextureCollector(64, 0, true, true, true,
true, true, frozenTextures: null)) so the assertion truly verifies that passing
a null frozenTextures to the TextureCollector constructor does not throw; keep
the Assert.DoesNotThrow wrapper and refer to the TextureCollector constructor
overload being tested.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Tests/Editor/Core/Services/TextureCollectorTests.cs`:
- Around line 1162-1167: The test
Constructor_WithNullFrozenTextures_DoesNotThrow currently relies on default
optional parameters instead of explicitly passing a null frozenTextures; update
the test body to call the TextureCollector constructor with frozenTextures: null
(e.g., new TextureCollector(64, 0, true, true, true, true, true, frozenTextures:
null)) so the assertion truly verifies that passing a null frozenTextures to the
TextureCollector constructor does not throw; keep the Assert.DoesNotThrow
wrapper and refer to the TextureCollector constructor overload being tested.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bac4ff46-806d-404f-8267-be0bd3358404

📥 Commits

Reviewing files that changed from the base of the PR and between 752af6b and fdf4bb3.

📒 Files selected for processing (7)
  • Editor/Common/UI/Controls/ExclusionListDrawer.cs
  • Editor/TextureCompressor/Core/Services/TextureCollector.cs
  • Editor/TextureCompressor/Core/Services/TextureCompressorService.cs
  • Editor/TextureCompressor/TextureCompressorEditor.cs
  • Editor/TextureCompressor/UI/Preview/PreviewGenerator.cs
  • Editor/TextureCompressor/UI/Sections/FilterSection.cs
  • Tests/Editor/Core/Services/TextureCollectorTests.cs
🚧 Files skipped from review as they are similar to previous changes (5)
  • Editor/TextureCompressor/TextureCompressorEditor.cs
  • Editor/TextureCompressor/UI/Preview/PreviewGenerator.cs
  • Editor/TextureCompressor/Core/Services/TextureCompressorService.cs
  • Editor/TextureCompressor/UI/Sections/FilterSection.cs
  • Editor/Common/UI/Controls/ExclusionListDrawer.cs

@Limitex Limitex merged commit 2dcea66 into main Apr 9, 2026
5 checks passed
@Limitex Limitex deleted the feat/ignore-from-guid branch April 9, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants