-
-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Entity support add other Transform
#2456
Changes from 7 commits
e95b86d
d8df9e0
0d57088
0d004aa
b882eab
01e0823
375e4b7
6e635e7
406391f
4991156
08a1b5c
a0339f2
e83000d
90589b0
cb29b43
68fa63a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,8 @@ import { Engine } from "./Engine"; | |
import { Layer } from "./Layer"; | ||
import { Scene } from "./Scene"; | ||
import { Script } from "./Script"; | ||
import { Transform } from "./Transform"; | ||
import { Transform, TransformTransitionState } from "./Transform"; | ||
import { UpdateFlagManager } from "./UpdateFlagManager"; | ||
import { ReferResource } from "./asset/ReferResource"; | ||
import { EngineObject } from "./base"; | ||
import { ComponentCloner } from "./clone/ComponentCloner"; | ||
|
@@ -73,8 +74,6 @@ export class Entity extends EngineObject { | |
name: string; | ||
/** The layer the entity belongs to. */ | ||
layer: Layer = Layer.Layer0; | ||
/** Transform component. */ | ||
readonly transform: Transform; | ||
|
||
/** @internal */ | ||
_isActiveInHierarchy: boolean = false; | ||
|
@@ -94,14 +93,39 @@ export class Entity extends EngineObject { | |
_isActive: boolean = true; | ||
/** @internal */ | ||
_siblingIndex: number = -1; | ||
|
||
/** @internal */ | ||
_isTemplate: boolean = false; | ||
/** @internal */ | ||
_updateFlagManager: UpdateFlagManager = new UpdateFlagManager(); | ||
|
||
private _transform: Transform; | ||
private _transformTransitionState: TransformTransitionState; | ||
private _templateResource: ReferResource; | ||
private _parent: Entity = null; | ||
private _activeChangedComponents: Component[]; | ||
|
||
/** | ||
* The transform of the entity. | ||
*/ | ||
get transform(): Transform { | ||
return this._transform; | ||
} | ||
|
||
set transform(value: Transform) { | ||
const pre = this._transform; | ||
if (value !== pre) { | ||
let state = this._transformTransitionState; | ||
if (pre) { | ||
state ||= this._transformTransitionState = {}; | ||
pre._generateTransitionState(state); | ||
} | ||
if (value) { | ||
state && value._applyTransitionState(state); | ||
} | ||
this._transform = value; | ||
} | ||
} | ||
|
||
/** | ||
* Whether to activate locally. | ||
*/ | ||
|
@@ -193,11 +217,17 @@ export class Entity extends EngineObject { | |
* Create a entity. | ||
* @param engine - The engine the entity belongs to | ||
*/ | ||
constructor(engine: Engine, name?: string) { | ||
constructor(engine: Engine, name?: string, ...components: ComponentConstructor[]) { | ||
super(engine); | ||
this.name = name; | ||
this.transform = this.addComponent(Transform); | ||
this._inverseWorldMatFlag = this.transform.registerWorldChangeFlag(); | ||
for (let i = 0, n = components.length; i < n; i++) { | ||
const type = components[i]; | ||
if (!(type.prototype instanceof Transform) || !this.transform) { | ||
this.addComponent(type); | ||
} | ||
} | ||
singlecoder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.transform || this.addComponent(Transform); | ||
this._inverseWorldMatFlag = this.registerWorldChangeFlag(); | ||
} | ||
|
||
/** | ||
|
@@ -210,6 +240,7 @@ export class Entity extends EngineObject { | |
type: T, | ||
...args: ComponentArguments<T> | ||
): InstanceType<T> { | ||
type.prototype instanceof Transform && this.transform?.destroy(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid destroying existing In the Consider removing or modifying this line to prevent destroying existing Apply this diff: -type.prototype instanceof Transform && this.transform?.destroy();
+if (type.prototype instanceof Transform && !this.transform) {
+ // If the entity does not already have a Transform, proceed to add one.
+}
|
||
ComponentsDependencies._addCheck(this, type); | ||
const component = new type(this, ...args) as InstanceType<T>; | ||
this._components.push(component); | ||
|
@@ -394,7 +425,10 @@ export class Entity extends EngineObject { | |
* @returns The child entity | ||
*/ | ||
createChild(name?: string): Entity { | ||
const child = new Entity(this.engine, name); | ||
const transform = this._transform; | ||
const child = transform | ||
? new Entity(this.engine, name, transform.constructor as ComponentConstructor) | ||
: new Entity(this.engine, name); | ||
child.layer = this.layer; | ||
child.parent = this; | ||
return child; | ||
|
@@ -429,6 +463,14 @@ export class Entity extends EngineObject { | |
return cloneEntity; | ||
} | ||
|
||
/** | ||
* Listen for changes in the world pose of this `Entity`. | ||
* @returns Change flag | ||
*/ | ||
registerWorldChangeFlag(): BoolUpdateFlag { | ||
return this._updateFlagManager.createFlag(BoolUpdateFlag); | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
|
@@ -438,8 +480,10 @@ export class Entity extends EngineObject { | |
} | ||
|
||
private _createCloneEntity(): Entity { | ||
const cloneEntity = new Entity(this._engine, this.name); | ||
|
||
const transform = this._transform; | ||
const cloneEntity = transform | ||
? new Entity(this.engine, this.name, transform.constructor as ComponentConstructor) | ||
: new Entity(this.engine, this.name); | ||
const templateResource = this._templateResource; | ||
if (templateResource) { | ||
cloneEntity._templateResource = templateResource; | ||
|
@@ -450,10 +494,9 @@ export class Entity extends EngineObject { | |
cloneEntity._isActive = this._isActive; | ||
const { transform: cloneTransform } = cloneEntity; | ||
const { transform: srcTransform } = this; | ||
cloneTransform.position = srcTransform.position; | ||
cloneTransform.rotation = srcTransform.rotation; | ||
cloneTransform.scale = srcTransform.scale; | ||
|
||
const transitionState = (this._transformTransitionState ||= {}); | ||
srcTransform._generateTransitionState(transitionState); | ||
cloneTransform._applyTransitionState(transitionState); | ||
const srcChildren = this._children; | ||
for (let i = 0, n = srcChildren.length; i < n; i++) { | ||
cloneEntity.addChild(srcChildren[i]._createCloneEntity()); | ||
|
@@ -478,7 +521,7 @@ export class Entity extends EngineObject { | |
for (let i = 0, n = components.length; i < n; i++) { | ||
const sourceComp = components[i]; | ||
if (!(sourceComp instanceof Transform)) { | ||
const targetComp = target.addComponent(<new (entity: Entity) => Component>sourceComp.constructor); | ||
const targetComp = target.addComponent(<ComponentConstructor>sourceComp.constructor); | ||
ComponentCloner.cloneComponent(sourceComp, targetComp, srcRoot, targetRoot, deepInstanceMap); | ||
} | ||
} | ||
|
@@ -765,3 +808,5 @@ type ComponentArguments<T extends new (entity: Entity, ...args: any[]) => Compon | |
) => Component | ||
? P | ||
: never; | ||
|
||
type ComponentConstructor = new (entity: Entity) => Component; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling to transform setter
The transform state transition logic needs validation and error handling.
Apply this diff to improve robustness:
📝 Committable suggestion