fix: YooAsset native builder support, bundle granularity, and dropdown stale values (#631, #632)#633
Merged
JasonXuDeveloper merged 8 commits intomasterfrom Apr 23, 2026
Merged
Conversation
Two fixes for issue #632: 1. Add parameterless default constructors to all build-time encryption and manifest services (Aes/Xor/ChaCha20 EncryptionServices, ManifestProcess, ManifestRestore). Each chains to the existing config-taking constructor using the *Config.Instance singleton, which is the same instance JEngine's internal BundleEncryptionConfig resolves to. YooAsset's AssetBundleBuilder calls Activator.CreateInstance(type) with no args, so the previous config-only constructors threw MissingMethodException when selected via the YooAsset panel. 2. Set EnableSharePackRule = true in BuildManager.CreateBuildParameters. YooAsset's own ScriptableBuildPipelineViewer and BuiltinBuildPipelineViewer both set this (YooAsset 2.3.18, line 116 of each), but JEngine left it at the BuildParameters default of false. With it off, TaskGetBuildMap skips shared-bundle extraction, inlining shared assets into every referencing bundle - producing fewer, larger bundles than the YooAsset UI would for the same collector config. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
BootstrapEditorUI dropdowns (Package, Hot Code Assembly, Hot Scene, Entry Class/Method, AOT DLL List, Dynamic Secret Key) passed the serialized value as JDropdown's default without checking it existed in the choices list. When a YooAsset package was renamed or a collector had only one entry, Unity's PopupField silently fell back to index 0 without firing a change event - so the UI displayed a different value than what was serialized, and selecting the same visible entry did not sync them. Prepend a "None" sentinel to every dropdown and route through ResolveCurrentOption / NormalizeSelection helpers. This guarantees at least two entries per dropdown (sidestepping Unity PopupField single-item quirks), shows "None" when the stored value is missing from the current choices, and clears the stored value to empty when the user selects "None". Closes #631 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
SettingsUIBuilder.CreatePackageSettingsGroup had the same pattern as the Bootstrap inspector fields: it passed settings.packageName as the PopupField value without verifying it existed in the choices list, so a renamed YooAsset package still showed the stale value. Mirror the Bootstrap fix: prepend a "None" sentinel to the choices, resolve the current value through a null/not-contained check, and clear the stored value to empty when "None" is selected. Part of #631 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
Extract WithNoneOption / ResolveDropdownValue / NormalizeDropdownSelection plus the NoneDropdownOption constant into EditorUtils so the three package-dropdown call sites (SettingsUIBuilder, BootstrapEditorUI, PanelUI) no longer each reimplement the same sentinel / fallback / clear-on-None logic. Additionally override Panel.OnFocus to rebuild its content when the window regains focus, so the Package dropdown reflects renames made in the AssetBundle Collector window without having to close and reopen the Panel. Skipped while a build is in progress to avoid losing BuildManager state and the log view contents. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
…nges BootstrapEditorUI now calls EditorUtils.WithNoneOption / ResolveDropdownValue / NormalizeDropdownSelection instead of its own local copies, and PanelUI's Package dropdown now uses the same helpers (previously missed in the earlier #631 fix - it still showed the stale package name after a rename). Also add a 500ms polling check on the Bootstrap inspector that compares a signature of the external data sources (packages, asmdefs, scenes, classes, methods, AOT files, dynamic keys) and rebuilds the inspector when they change. Combined with the existing undo/redo handler and a new EditorApplication.focusChanged listener, this means a package rename in the AssetBundle Collector propagates to the Bootstrap inspector without the user having to reselect the asset. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
Rebuild hot update code and main asset package after the build pipeline changes in this branch so a fresh clone runs without a manual rebuild. Bundles are now split via EnableSharePackRule=true; old monolithic bundles are removed. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
Unity Test Results✅ EditMode: All tests passed Unity Version: 2022.3.55f1 ✅ All tests passed! The PR is ready for review. View workflow run |
OnDetachFromPanel no longer takes an Undo.UndoRedoCallback token - after the focus-refresh refactor it unregisters from statically-known handlers (OnUndoRedo, OnEditorFocusChanged) directly. Update the test to call the method with just the event argument. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #633 +/- ##
==========================================
+ Coverage 94.91% 94.99% +0.07%
==========================================
Files 70 71 +1
Lines 10431 10583 +152
==========================================
+ Hits 9901 10053 +152
Misses 530 530
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Adds EditorUtilsTests for the new WithNoneOption / ResolveDropdownValue / NormalizeDropdownSelection helpers, plus roundtrip tests mirroring the rename-then-display-as-None flow. Adds BootstrapEditorUI tests for the new refresh paths: OnEditorFocusChanged (both hasFocus=true rebuild and hasFocus=false early-return), ComputeExternalDataSignature (stability + formatting), and CheckForExternalDataChanges (early-return on match, rebuild on mismatch). Adds Panel.OnFocus tests covering the null-root guard and the IsBuilding guard that preserves BuildManager state + log view contents during an in-progress build. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: JasonXuDeveloper - 傑 <jason@xgamedev.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses two reporter issues plus a related UX gap found during review.
Fixes #632 — YooAsset native builder + bundle granularity
MissingMethodExceptionwhen building with YooAsset'sAssetBundleBuilderYooAsset's
BuildPipelineViewerBase.CreateEncryptionServicesInstance()callsActivator.CreateInstance(type)with no arguments, but JEngine's{Aes,Xor,ChaCha20}EncryptionServicesand{Aes,Xor,ChaCha20}Manifest{Process,Restore}only exposed config-taking constructors. Added parameterless default constructors that chain to the existing ones via*Config.Instance(the same singleton JEngine's internalBundleEncryptionConfig<…>already resolves). Existing internal instantiation — which passes the config viaActivator.CreateInstance(type, new object[] { config })— still matches the parameterized overload, so no behavior change for the JEngine panel path.JEngine output had fewer/larger bundles than YooAsset's native builder for identical collector configs
Root cause: YooAsset's
ScriptableBuildPipelineViewer.ExecuteBuild(andBuiltinBuildPipelineViewer) both setbuildParameters.EnableSharePackRule = true, but JEngine'sBuildManager.CreateBuildParameters()omitted it, falling back to theBuildParameters.csdefault offalse. With it disabled, YooAsset'sTaskGetBuildMapstep 7 skips shared-bundle extraction entirely, inlining shared assets into every referencing bundle — producing fewer/larger bundles and duplicated payload. Matches the reporter's screenshot. Fix: setEnableSharePackRule = trueinBuildManager. Other build params (LZ4, HashName, StripUnityVersion, TrackSpriteAtlasDependencies) already match YooAsset UI defaults or are intentional JEngine overrides.Fixes #631 — Dropdowns show stale values after YooAsset package rename
BootstrapEditorUI(inspector) and the Build Panel (SettingsUIBuilder+PanelUI) passed the serialized value as thePopupFielddefault without checking it existed in thechoiceslist. When a YooAsset package was renamed, Unity'sPopupFieldsilently fell back to index 0 without firing a change event — UI and serialized value desynced. Single-entry dropdowns exhibited the same class of issue."None"sentinel so every dropdown has ≥ 2 entries; when the stored value isn't in the current choices it displays asNone; selectingNoneclears the stored value to empty. Applied uniformly to the 7 dropdowns inBootstrapEditorUI, the Package dropdown inSettingsUIBuilder, and the (previously missed) Package dropdown inPanelUI.Related improvements (not reported, found during review)
WithNoneOption/ResolveDropdownValue/NormalizeDropdownSelection+NoneDropdownOptionintoJEngine.Core.Editor.EditorUtils. All three call sites now share the same implementation.EditorApplication.focusChanged. The Build Panel (EditorWindow) rebuilds onOnFocus(skipped mid-build). A package rename in the AssetBundle Collector window now propagates without requiring the user to reselect the asset.Chore
mainasset package and hot-update AOT assemblies withEnableSharePackRule = trueso a fresh clone of this branch runs without a manual rebuild. Old monolithic bundles are removed; new share-pack-split bundles are committed.PR strategy
Per discussion the PR should be merged via "Rebase and merge" so all six commits land on
masterindividually with their own scopes, rather than squash-merged.Test plan
AssetBundleBuilder→ selectAesEncryptionServices(+ matching manifest services) → build succeeds (previouslyMissingMethodException). Repeat for XOR and ChaCha20.packageName = "main". In AssetBundle Collector, rename the sole package togame. Dropdown updates toNonewithin 500ms without reselecting the asset (polling). Selectinggamepersists.None.