3.3.0 #253
wallstop
announced in
Announcements
3.3.0
#253
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Changelog
Added
Tools > Wallstop Studios > Unity Helpersto export or clear captured failuresProject Settings > Wallstop Studios > Unity HelpersFixed
ScriptableObjectSingletonMetadataandAttributeMetadataCachenow skipSetDirty/SaveAssetswork when regenerated metadata is unchanged. This prevents initialize-on-load and explicit singleton ensure passes from repeatedly re-saving identical assets during Unity test runs or editor refreshes, reducing the chance of Unity's "infinite import loop" detector tripping on native runs.AssetPostprocessorDeferraldedup regressing structurally-equal-but-distinct drains:AssetPostprocessorDeferral.Schedulenow dedups pending drains viaReferenceEqualsinstead ofList<Action>.Contains(which invokesDelegate.Equals). The prior structural-equality behavior silently coalesced two distinct delegates that shared the sameMethod+Target-- common when a local helper returns a lambda that captures only outer-method variables -- so a self-rescheduling drain could be dropped entirely. Matches the documented intent in the AssetPostprocessor safety skill and is pinned by the newScheduleStructurallyEqualButDistinctDelegatesAreNotDeduplicatedregression testDetectAssetChangeProcessorand related editor processors (LlmArtifactCleaner,SpriteLabelProcessor) by deferring callback invocation out of Unity's asset-import phase via a sharedAssetPostprocessorDeferralhelper backed byEditorApplication.delayCall. The prior synchronous path calledAssetDatabase.LoadAllAssetsAtPath/GetComponentsInChildren/ user callbacks during the import phase, which triggered Unity's internal sprite/renderer lifecycle relays and produced per-import warning storms. A new opt-out setting (Project Settings > Wallstop Studios > Unity Helpers > Detect Asset Changes, option Defer Post-process Callbacks, default on) restores the old synchronous behavior for users who require it. (#234)WallstopGenericPool<T>.PurgeInternalCoreletting the 1-secondMinAutoPurgeIntervalSecondsthrottle blockMaxPoolSizeenforcement. A Rent/Return that advanced_lastAutoPurgeTimeon a healthy-pool scan would block a subsequent same-tick call that pushed the pool pastMaxPoolSize, silently skipping theCapacityExceededpurge and dropping the matchingOnPurgenotification. The throttle now has two orthogonal rules: (1) when the pool is observably overMaxPoolSize, the throttle is bypassed entirely so a burst of returns cannot accumulate beyond capacity within a single clock tick; (2) otherwise the throttle still rate-limits scans (preserving the O(1) amortized fast path for healthy pools under contention). The multithreaded variant also guards the timestamp advance with CAS max-semantics so concurrent out-of-order writes cannot regress the throttle clock. Applies to both the multithreaded and SINGLE_THREADED pool variantsRollingHighWaterMark(used by pool purge system) performing O(n) operations on every pool rent/return, causing 100x slowdowns under sustained load. ReplacedList<Sample>withCyclicBuffer<Sample>for O(1) add/remove, added incremental running sum for O(1) average computation, and added a monotonic deque for O(1) amortized peak tracking. Previously, 100K rent/return cycles took 20+ seconds; now completes within 200ms budgetOnGUIwriting toSerializedPropertyvalues every frame withoutBeginChangeCheck/EndChangeCheckguards. Direct assignments likeapply.boolValue = EditorGUI.ToggleLeft(...)andnameProp.stringValue = EditorGUI.TextField(...)dirtied theSerializedObjecton every repaint, corrupting undo history. Also removed a redundant render-phase writeback of the computed display label to the platform name propertyGenericMenucallback not callingUndo.RecordObjectsbefore mutation and not handling the "Custom" menu option. Selecting "Custom" from the dropdown now correctly sets the platform name tostring.Empty(triggering custom mode), and all selections are undoableEnumFlagsFieldfor selection mode writing tomodeProp.intValueevery frame without aBeginChangeCheck/EndChangeCheckguardAttributeMetadataCacheGenerator.GetOrCreateCache()using hardcoded asset paths that did not match the[ScriptableSingletonPath("Wallstop Studios/Unity Helpers")]attribute onAttributeMetadataCache. The generator was creating and loading the cache asset fromAssets/Resources/Wallstop Studios/instead of the correctAssets/Resources/Wallstop Studios/Unity Helpers/path, causing cache generation to silently fail when the singleton was already loaded at the correct pathIntDropDownDrawerto properly handle property values that fall outside the configured options. Invalid values (values not in the options array) are now preserved without modification during render and clearly displayed with an "(Invalid)" suffix. Previously, invalid values were displayed as-is without any visual indication. The UI ToolkitIntDropDownSelector.GetDefaultValue()now returns the first option instead of 0EditorGUI.Popupusage withGenericMenu-based dropdowns to eliminate phantom empty rows when selected index is -1 on Linux. Affected drawers:WValueDropDownDrawer,IntDropDownDrawer,StringInListDrawer,TexturePlatformOverrideEntryDrawer(standard variants), andWValueDropDownOdinDrawer,IntDropDownOdinDrawer,StringInListOdinDrawer(Odin Inspector variants). Odin drawers now always useGenericMenuregardless of the page limit setting, sinceGenericMenuhandles all list sizes correctly without the rendering issues that required the threshold (#209)SerializedPropertysetters for Unity-native types (Vector2,Vector3,Vector4,Color,Rect,Bounds,Quaternion,AnimationCurve,Hash128, and theirIntvariants) inWValueDropDownDrawer.ApplyOptionto avoid the reflection fallback for known property types. The generic reflection path now iterates over allserializedObject.targetObjectsfor proper multi-object editing support instead of only updating the first selected objectTryClearSet,TryAddNewElement,TryCommitPendingEntry,AppendNullPlaceholderEntry, andTrySortElementsinSerializableSetPropertyDrawernot callingUndo.FlushUndoRecordObjects()after direct object mutation. These methods usedUndo.RecordObjectsto snapshot pre-change state but never finalized the undo record, causingUndo.PerformUndo()to silently do nothingGUIContentallocations inIntDropDownDrawer.DrawGenericMenuDropDownandPoolTypeConfigurationDrawer.OnGUIthat created avoidable garbage collection pressure in the Inspector. Both drawers now reuse staticGUIContentinstances (consistent withWValueDropDownDrawerandStringInListDrawerwhich already followed this pattern)Pull Requests
Contributors
@Copilot, @dependabot[bot], @wallstop, copilot-swe-agent[bot] and dependabot[bot]
This discussion was created from the release 3.3.0.
Beta Was this translation helpful? Give feedback.
All reactions