Let a behavior run while the editor is open
A behavior object carries a "Run in editor" switch next to Enabled. When it is on, the behavior ticks outside of Play and works on the saved model directly - Unity semantics: what it moves is a real change, autosaved and not undoable. Input stays with the editor, so On key never fires while typing. The editor run never bakes placed containers into the model, since that would silently drop their instanceEdits. syncToModel reports whether it wrote anything, and the dirty flag is only raised on change - otherwise a behavior moving something every frame would trigger ~60 saves a second.
This commit is contained in:
1 parent
c74037b6e1
commit
8f31afac37
21 files changed
+718
-35
No files matched your search
@@ -84,8 +84,8 @@ const ASSET_SCHEMAS: Record<AssetType, PropertySchema> = {
|
||||
],
|
||||
},
|
||||
],
|
||||
// Behaviors declare their own properties (variables) per asset – see `schemaForAsset`.
|
||||
behavior: [],
|
||||
// Behaviors declare their own properties (variables) per asset too – see `schemaForAsset`.
|
||||
behavior: [{ key: 'runInEditor', label: 'Run in editor', kind: 'boolean', default: false }],
|
||||
collider: [
|
||||
{
|
||||
key: 'shape',
|
||||
@@ -133,9 +133,11 @@ export function schemaFor(type: AssetType): PropertySchema {
|
||||
return FULL_SCHEMAS[type];
|
||||
}
|
||||
|
||||
/** The type schema, or for behaviors their declared variables. */
|
||||
/** The type schema, for behaviors followed by their declared variables. */
|
||||
export function schemaForAsset(asset: Asset): PropertySchema {
|
||||
return asset.type === 'behavior' ? [...COMMON_PROPS, ...asset.variables] : FULL_SCHEMAS[asset.type];
|
||||
return asset.type === 'behavior'
|
||||
? [...FULL_SCHEMAS.behavior, ...asset.variables]
|
||||
: FULL_SCHEMAS[asset.type];
|
||||
}
|
||||
|
||||
export function propDef(asset: Asset, key: string): PropertyDef | undefined {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ancestorIdsOf, type ObjectTree } from '../model/hierarchy';
|
||||
import { instanceTargetOf, isEmptyEdit, resolveObjects } from '../model/instance';
|
||||
import { findAsset, type Project } from '../model/Project';
|
||||
import type { SceneObject } from '../model/SceneObject';
|
||||
import { COMMON_PROPS, type PropertySchema, schemaForAsset } from './PropertySchema';
|
||||
import { type PropertySchema, schemaFor, schemaForAsset } from './PropertySchema';
|
||||
import { deviatesFromAsset, isModified } from './resolve';
|
||||
|
||||
/**
|
||||
@@ -11,7 +11,7 @@ import { deviatesFromAsset, isModified } from './resolve';
|
||||
* default is declared on the variable itself, so the asset value cannot differ from it.
|
||||
*/
|
||||
export function markedAssetSchema(asset: Asset): PropertySchema {
|
||||
return asset.type === 'behavior' ? COMMON_PROPS : schemaForAsset(asset);
|
||||
return asset.type === 'behavior' ? schemaFor('behavior') : schemaForAsset(asset);
|
||||
}
|
||||
|
||||
/** Whether any asset property the inspector would mark gold differs from its default. */
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The `runInEditor` switch of a behavior (see `ASSET_SCHEMAS.behavior`). A behavior with it on
|
||||
* keeps running while the project is *not* playing, and then it edits the saved model: what it
|
||||
* moves or writes is a real change that is saved and is not on the undo stack. That is what makes
|
||||
* the switch useful (a behavior can build or arrange content) and why it is off by default.
|
||||
*/
|
||||
import type { ObjectTree } from '../model/hierarchy';
|
||||
import type { PropertyBag } from '../model/Properties';
|
||||
import { findAsset, type Project } from '../model/Project';
|
||||
import { resolveSceneObjectProps } from './resolve';
|
||||
|
||||
export function runsInEditor(props: PropertyBag): boolean {
|
||||
return props.runInEditor === true;
|
||||
}
|
||||
|
||||
/** Whether a holder contains any behavior asking to run outside play mode. */
|
||||
export function hasEditorRun(project: Project, holder: ObjectTree): boolean {
|
||||
return holder.objects.some((object) => {
|
||||
const asset = findAsset(project, object.assetId);
|
||||
return asset?.type === 'behavior' && runsInEditor(resolveSceneObjectProps(asset, object));
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user