Changelog¶
All notable changes to this package will be documented in this file.
[Unreleased]¶
Changed (single-process slots)¶
- Host process slots are single
IProcessfields: everyList<IProcess>body slot (reactor-target reactions Bool/Int/Float/Double/String/Vector3/GameObject/Event/Exclusive,ProcessReactiononBegin/whileRunning/onEnd,GameObjectCycleReactiononBegin/onEnd,BoolCycleReaction,ValueReference.onValueChanged) is now a single[SerializeReference] IProcess(processwhere it wasprocesses). Run several processes by picking a Process List (sequential/parallel) in the slot. TheList<IProcess>extension surface onProcessRunsandReactionProcessExtensions.Stopis removed;ReactionTargetAutoWirebinds a single process. Example prefabs/scenes were rewritten in place (multi-entry lists wrapped in a parallelProcessList); no migration path — dev-only change.
Added (graph-mandatory types)¶
[GraphMandatory](Jungle.Attributes, inherited): marks types whose editing context is always the Execution Graph — the inspector shows the type row plus a full-width "☷ Open Graph" row, at any nesting depth. Applied only to structures that read as a graph: multi-process containers (ProcessList,SelectiveParallelProcess) and thePipelineOperation<T,TTarget>family (transform/float/color/… pipelines — complex operations over time). Simple commands (transform, rigidbody, …) always render their full inline inspector; the field's small ☷ icon button remains the optional way into the graph.- Graph-only inspector row keeps the type visible: the compact view no longer replaces the row with a lone button — the field keeps its swappable type pill (and count badge), and the Open Graph button spans a full row beneath it (TypeSelectableField + ContainerProcessDrawer via the new GraphOnlyFieldUI, which defers the compact decision to attach time so graph-window nodes stay inline).
Removed (graph-first mode)¶
- "Graph-First Inspectors" toggle (
Jungle.GraphFirstInspectorsEditorPref, the Window/Jungle menu item, and the Project Settings toggle): graph-only inspectors are now purely type-driven via[GraphMandatory]— there is no mode that compacts single commands.
Added¶
- Subject-scoped retrigger (
RetriggerScope): non-Parallel retrigger strategies now apply only to live runs whose captured subject matches the incoming trigger's subject by default (RetriggerScope.SameSubject) — re-triggering a process for object A never disturbs object B's run. Opt back into the old behavior per call or per process withRetriggerScope.AllRuns.IRetriggerablegains an optionalRetriggerScopemember. ProcessRetriggerStrategy.Buffer: queues the trigger and begins automatically when the in-scope live runs finish (coalesced per subject; dropped by explicitCompleteAll/Complete). Replaces the ProcessComponent/ProcessList-local buffering.- Execution Graph — transparent containers: a bare
ProcessListno longer draws a card; its children splice into the parent flow as a chain (sequential) or bracketed lanes (parallel). Right-click the group for element actions. - Execution Graph — single-operation command collapse: a command holding exactly one operation renders as that operation's card, titled with the command's name (dimmed, as context) ahead of the operation pill, the command itself reduced to a target chip; a header "+" grows it back into the multi-operation view.
- Execution Graph — structural drops: dragging a step BETWEEN cards moves it (also
across lists when types allow); dropping it ONTO a card groups the two in a
cross-axis
ProcessList(parallel in a sequence, sequential in a lane), matching the add-chip semantics. Same-mode bare lists absorb drops instead of nesting; single-child wrappers keep auto-dissolving. - Context targets name their context: a value set to
Contextnow repeats the description from the nearest enclosing[ProcessContext]slot. SmartX targets show it in the status pill —⊙ the attaching objectContext— replacing the duplicated "Context Context" the pill pair used to read; bare[SerializeReference]value fields read "Context (the attaching object)". Stays the plain type name outside a contextual slot, and the full context explanation is on the pill's tooltip. - Execution Graph — pipelines keep their zones inline: a pipeline nested in another graph now draws the same titled zone chain as the full view (Target ⟹ Modifiers ⟹ …), so its modifiers stay grouped in one "Modifiers" zone instead of scattering as loose cards into the surrounding flow. In vertical flow a single-card zone (Target) now stretches across its zone like the modifier chain does, instead of hugging the left edge.
- Execution Graph — instant honesty: a command whose operations are all instant
(
Instant*Operationbases) draws them as a sequential chain — they run in list order, so parallel lanes were misleading.
Removed¶
- "List Style" project setting (
JungleListStyle,JungleSettings.ListStyle): Jungle lists now always use the collapsible foldout layout. Lists markedJungleListLayout.Flator drawn inline keep their plain header, as before. RetriggerBehaviorenum and its fields onProcessComponentandProcessList: retrigger policy now lives at the run entry point only (BeginRun/ProcessComponent.RetriggerStrategy, bothProcessRetriggerStrategy). The legacyRetriggerBehavior→RetriggerStrategymigration shim (legacyRetriggerBehaviorfield +MigrateLegacyRetrigger) is gone; pre-consolidation example scenes were re-baked in place (all heldIgnore, the field default — no behavior change) and no runtime remap remains. TheProcessListfield is dropped (nested retrigger was a no-op by construction — a nested list's Begin is only ever called once per run by its parent).ProcessListre-begin now mirrorsCommand: ignored while running, complete-then-restart from paused.- Class-selection popup ordering (
JungleClassInfoAttribute.Order): new optionalOrdernamed property (defaultint.MaxValue= unordered). Lower numbers appear first in the type picker; entries sharing an order fall back to alphabetical. A category's position floats up to its lowest-ordered member, so numbering one obvious entry pulls its whole category to the top. Sorting is centralized inTypePickerModelso the AdvancedDropdown, detailed window, and toggle-set list order identically. The obvious entries across the value, condition, filter, process, reaction, event, data, modifier, transform-target/applier/modifier, operation, constraint, and per-component action families are now numbered so the common picks surface first. ProcessReaction.whileRunningslot (Jungle.Data, cycle reactions): the renamedEventCycleReaction(nowProcessReaction) gains a third process list that starts on cycle begin and is force-stopped on cycle end. Use for tweens, looping sounds, follow effects, or any process that should last exactly as long as the cycle.- Scene value type:
SceneReference(build-safe scene link — drag a scene asset in the inspector),ISceneValue/ISettableSceneValue, inlineSceneValue, and the generatedSmartScenesmart-value struct. Editor drawerSceneReferenceDrawerprovides the scene drag field plus a Build Settings warning. - Scene commands/operations:
SceneCommandhosting a list ofISceneOperation, withLoadSceneOperation(sync),LoadSceneAsyncOperation(background, optional activation gating),UnloadSceneOperation(async, optional wait), andSetActiveSceneOperation. Operations target anISceneSource, so one op set covers every delivery mechanism. - Scene delivery modes:
SceneReferencegains aDeliverysetting (SceneDeliveryMode.BuildSettings/Addressable) and the load/unload API the operations drive. Keeping this on the one concrete type — rather than a hierarchy of scene-source classes — is what letsSmartScenehold it inline and still offer a dynamic source. Addressable delivery goes through theISceneDeliveryhook that the optionalJungle.Addressablesassembly registers, keyed by the asset GUID thatSceneReferencealready stores (and which is a valid Addressables runtime key), so no Addressables types reach Jungle.Core.ISceneOperationHandlenormalises Unity'sAsyncOperationand Addressables'AsyncOperationHandle, including the activation gate both express differently.SceneLoadRegistryrefcounts shared loads and holds the provider handle an Addressable unload needs. Load Scenerefuses non-blocking delivery: Addressables has no synchronous load, and faking one withWaitForCompletionblocks the main thread on the download for remote content. The operation now errors and points atLoad Scene (Async)instead.- Scene object references:
SceneObjectReference/SceneObjectReference<T>— a serializable link from an asset to an object in a scene, which Unity cannot serialize natively. Stores aSceneReferenceplus the target'sSceneObjectId, and resolves throughSceneObjectRegistryonce the scene is loaded.Resolve()answers "is it here now";Request()loads the owning scene on demand and calls back, paired withRelease().SceneObjectReferenceDrawerdrivesDragAndDropdirectly (anObjectFieldcannot accept a scene object on an asset) and stamps the marker component onto the drop target automatically. - Optional Addressables module (
Jungle.Addressablesasmdef, compiles only whencom.unity.addressablesis installed):AddressableSceneDeliveryandAddressableSceneHandle, plugging Addressable scenes into the sharedSceneCommandop set. NewJungle.Addressables.Editorasmdef contributes the inspector warning for a scene set to Addressable delivery that is not in an Addressables group, viaSceneDeliveryWarnings. Zero impact when the package is absent. ITraversableShapeshape capability (Jungle.Spatial): opt-in interface (TraversalLength+DistanceToU) for shapes with a single measurable travel path. Implemented byLineShape,ArcShape,CircleShape, andCurveShape(delegates to the wrappedICurve3D).PlaneShape/MeshUVShapedeliberately do not implement it. Lets consumers walk any such shape at a constant world-units/sec speed regardless of how it parametrises U.
Changed¶
- Execution Graph — scroll instead of squash: the vertical content column caps at 1100px instead of 640px, so wide windows are actually used. Cards now publish an explicit width floor while building — header chips at full size (including the hover-revealed "?"/"❖" actions and the floating edge chip), plus whatever their body needs — and side-by-side lanes publish the sum of theirs. The column adopts the deepest floor, which outranks the max-width cap: content that no longer fits widens the column and brings in the horizontal scrollbar rather than compressing the lanes. Header chips also opt out of flex-shrink; width pressure lands on the title and class pill, which ellipsize.
- Execution Graph — one add per flow: the atomic-command header "+" now only shows while the card is collapsed. Expanded cards already carry the add at the end of their steps, so the same action no longer appears twice (title and end of sequence).
- Attachment filter checks consolidated (Octoputs): the duplicate "Object Filter"
pair (
AttachableGameObjectFilterCheck,AttachmentPointGameObjectFilterCheck) was a strict superset of the "Filter" pair — same filter evaluation plus anIComponentLookupStrategyhop. Thelookupfield moved ontoGameObjectFilterAttachableCheck/GameObjectFilterAttachmentPointCheckand the redundant pair was deleted, leaving one "Filter" entry per domain in the picker. Existing serialized references are redirected by twoRenameTypeRuleentries in the Jungle.Core migration manifest; thefilterandlookupfield data carries over verbatim. Assets using the kept checks are unaffected — a missinglookupresolves to Self, which is the previous behaviour. EventCycleReaction→ProcessReaction(Jungle.Data): renamed to better reflect its new role as the no-autowire cycle reaction that hosts begin/while/end process slots. Class label is now "Process". Auto-migrated via[MovedFrom]— existing serialized references update on next inspector touch.CurveTransformTarget→ShapeTraversalTransformTarget(breaking, Octoputs): the curve-only "Curve Transform" target is now a shape-agnostic "Walk Along Shape" target driven byITraversableShape. Type rename is auto-migrated via[MovedFrom]. Field migration is NOT automatic: the oldalignToTangent(bool) +tangentUp(Vector3) were replaced by the sharedShapeRotationModeenum (Preserve/AlignToShapeNormal/AlignToTangent/Override). Existing serialized data loads withrotationMode = Preserve— re-select the rotation mode on affected targets. Rotation now uses the shared shape normal as the tangent "up" instead of a per-target up vector (defaults are unchanged).- Editor chrome spacing harmonized (Jungle Core editor): one shared
--jungle-foldout-indent(15px, = Unity's native nested-foldoutmargin-left) now drives section, subsection, list-nested-foldout andTypeSelectableFieldchild indents — previously 4 divergent values (8/12/18/0px). New--jungle-section-gaptoken is the single knob a field-style variant may use to widen inter-section spacing (Pill's 6px moved off a raw.jungle-section-foldablerule onto the token). Inline / smart-value child rows no longer get a tallermin-height:24/ looserpadding:3pxtreatment — they use the same row metrics as every other TSF row. Pillmin-heightand.tsf__buttonsize are unified across all four field styles, so row height no longer changes with the selected style. An expanded TSF keeps its list-box visual but no longer adds margin/padding, so opening a foldout no longer reflows siblings. The TSF label column is now stable: assigning or clearing a type no longer shifts the label. ThedrawInlinebranch also reserves the toggle slot (reserveSpace: true) so non-expandable TSF rows (smart-value / DrawInline) land their leading content/label in the same column as expandable TSF rows. Pill field style only: the header row's vertical padding is raised (_Pill.uss.tsf-row5px top/bottom vs base 2px) so the Pill header isn't cramped; horizontal padding unchanged so the label column holds. Managed-ref types with[Subsection]but no top-level[Section](e.g.SphereCastHitProvider) no longer render flush-left inside their TSF: inSectionedPropertyDrawer.CreateSectionElementthe ungrouped branch tags each DIRECT property field with.jungle-section-ungrouped-propertyand indents it to the foldout- content column via.tsf__details .jungle-section-ungrouped-property(TSF-scoped — top-level inspectors unaffected). The indent lives on the property, not on the wrapping container, so a subsection-only ungrouped section (e.g.TransformTargetValuewith only[Subsection]attributes) isn't double-indented — its subsections keep their natural position and contribute only their own content padding.
Fixed¶
- TSF row hover no longer reads as "selected": a
TypeSelectableFieldrow used Unity's--unity-colors-highlight-background-hover— the selection blue — so hovering a row whose value is an ObjectField washed the whole field blue. It now uses the same neutral grey the expanded title strip and list headers already use (#3d3d3d / #b5b5b5 light). - Execution Graph — inline TSF child indent: the graph restates the 15px TSF child indent
at a higher specificity than the base sheet's inline reset, so DrawInline values (e.g. a
[SerializeReference] IGameObjectValuerendering as an ObjectField) sat 15px right of the plain fields beside them. The reset is restated for the graph too. - Execution Graph — field label column: fields in the graph now use the inspector's
label metrics (45% of the row, floor 123px, ellipsis past that) so values line up in a
column. Unity only applies those metrics inside an
InspectorElement, which the graph window has none of, so labels used to size to their own text and every value started at a different x. Composite sub-fields (Vector3 x/y/z) keep their compact labels. - Execution Graph — add chip placement: a pipeline zone's "+" (Modifiers, target steps) now rides at the trailing edge of the zone's title row, like a card header's add button, instead of floating under the chain — in an empty zone it was the only thing on its line. The "+" that appends to a flow column moved to the trailing (right) edge too, instead of hugging the left flow line.
- Empty
[Section]foldouts: a section whose every field is hidden or claimed elsewhere (shown as a graph zone, for instance) is no longer drawn — "Targeting" and "Modifier Chain" stopped appearing as empty foldouts above the pipeline zones that hold their fields. Sections carrying a description keep their header. - SceneCommand / LoadSceneOperation preferred path over build index (Jungle Core):
LoadSceneOperationandLoadSceneAsyncOperationnow tryBuildIndexfirst and fall back toScenePathonly when the index is unavailable. Prevents broken loads when scenes are renamed but their build index stays stable.SceneCommandalso guards against null/unassignedSceneReferencemore defensively. - JungleTagFilter null-tag resilience (Jungle Core):
JungleTagFilterno longer throws when aTaggercontains null tag entries or when the filter's own required tags list has nulls. Null entries are silently skipped during matching. - GameObjectFilter / Tagger null-safety (Jungle Core):
GameObjectFilterbase class andTagger.HasTaghandle destroyed or null GameObjects gracefully instead of throwing.GameObjectFilterAttachableCheckandGameObjectFilterAttachmentPointCheck(Octoputs) guard against null filter fields consistently with the "null = all allowed" convention. ShapeProjectionTransformTargetignoredAlignToTangent(Octoputs): selecting the Align To Tangent rotation mode silently fell through to a no-op (only Preserve/AlignToShapeNormal/Override were handled). Rotation resolution for all shape-driven targets/modifiers is now a single sharedShapeRotation.Resolveso the four modes behave identically everywhere.- Inspector "Tools" section: the lone bottom-of-inspector "Open in Debug Window" button is now a regular Jungle-styled button inside a foldable "Tools" section (ComponentLevel importance, collapsed by default, state persisted), next to a new Open in Graph button. The graph button appears only when the component has graphable execution — one graphable property opens it directly, several open the component's graph browser. The section is omitted entirely when neither tool applies. The per-field "Open in Debug Window" link keeps its inline style.
- Section model — one structure, importance only (breaking, editor API):
every
[Section]now renders as the same always-foldable Unity component-header bar that bleeds edge-to-edge across the inspector. The foldable-vs-static distinction and the five visualFoldoutStylevariants are gone.FoldoutStyle(Highlight/Normal/Discrete/Underline/TitleBar) andSectionFoldability(Inherit/Never/Always) andSectionAttribute.FoldableMode/SubsectionAttribute.FoldableModewere removed. New enumSectionImportance { Inner, Discrete, ComponentLevel }onSectionAttribute.Importance(defaultInner) controls emphasis only — within the neutral grey family, no accent: ComponentLevel = standard grey bar, bold header, hairline separator (the strongest neutral read); Inner = same shape with a lighter grey bar (lighter than the list/TSF header) so nested sections recede a step; Discrete = no bar, muted normal-weight header, no separator. The category follows render context automatically: a section on a component inspector is promoted to ComponentLevel, while one nested inside a serialized sub-object stays Inner — setImportanceexplicitly only to override that (e.g. force a nested section to ComponentLevel, or Discrete anywhere). Edge-to-edge bleed still applies to every section (and still spans the container, not the window, inside the GraphWindow). Migration: dropFoldableMode = …from any[Section]/[Subsection](all sections are foldable now); replace anyStyle = FoldoutStyle.XwithImportance = SectionImportance.X(Discrete→Discrete, everything else→leave default and let context promote, or use ComponentLevel to force emphasis on a nested section). - Unified copy/paste context menu: right-clicking a type-selectable field or a Jungle list row now shows a single Copy / Paste (and Duplicate on list rows) instead of the previous mix of "Copy Value/Paste Value" and "Copy (Deep)/ Paste (Deep)/Duplicate (Deep)" that appeared in separate menus depending on where you clicked. The field's old immediate right-click menu (which preempted the list row's menu) was removed in favour of one UI Toolkit contextual menu; the list row contributes only Duplicate when an inner field already added Copy/Paste, so the menu never shows the same action twice. Dead "Copy Parent Value/Paste Parent Value" code (never wired) and the no-op mixed-selection copy were removed. Copy/Paste were always deep (independent instances) — only the labels changed.
- Inline Jungle list add button: the inline
[JungleList]layout no longer migrates the+onto the last row (which moved as rows expanded/collapsed). It now shows a single full-width "add new entry" bar that always sits under every row, including when the list is empty (the old "None" + tiny-+empty row is gone). The bar text is contextual by default — "Add <ElementLabel>", falling back to "Add <singularized field name>" (so a "Bindings" field reads "Add Binding"). NewJungleListAttribute.AddLabeloverrides it per-site; inline-only — other layouts keep the header+. The bar is styled discreetly (small, muted) and brightens on hover. - Reactor "entries" renamed to "reactions": the per-source list on every reactor
target is now
reactions(wasentries), and the reaction types areFloatReaction,IntReaction,BoolReaction,StringReaction,DoubleReaction,Vector3Reaction,GameObjectReaction,EventReaction,ExclusiveReaction,EventCycleReaction,GameObjectCycleReaction,BoolCycleReaction(were*TriggerEntry/*CycleEntry). The marker interfaceIReactorEntryis nowIReactionandICycleEntryis nowICycleReaction. Each reaction's inner body list is nowprocesses(wasreactions). Existing scenes/prefabs/assets migrate automatically via[FormerlySerializedAs](fields) and[MovedFrom](SerializeReference cycle reaction types) — no manual rewiring required.
[1.0.0] - 2024-01-01¶
- Initial package structure extracted from the Jungle Core repository.
- Added Unity Package Manager metadata and samples manifest.