From 45437a1d2f2c4950cd9371b4e4934392a42cd6a6 Mon Sep 17 00:00:00 2001 From: Rezmason Date: Fri, 8 Dec 2023 10:43:35 -0800 Subject: [PATCH 1/4] Exercise 1: spawn multiple bubbles --- src/components/BubbleEmitterComponent.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/BubbleEmitterComponent.ts b/src/components/BubbleEmitterComponent.ts index 51f327c..7f6f69d 100644 --- a/src/components/BubbleEmitterComponent.ts +++ b/src/components/BubbleEmitterComponent.ts @@ -13,6 +13,7 @@ import { NO_PROXY, getState } from "@etherealengine/hyperflux" import { useExecute } from "@etherealengine/engine/src/ecs/functions/SystemFunctions" import { SimulationSystemGroup } from "@etherealengine/engine/src/ecs/functions/EngineFunctions" import { EngineState } from "@etherealengine/engine/src/ecs/classes/EngineState" +import { LocalTransformComponent } from "@etherealengine/engine/src/transform/components/TransformComponent" export const BubbleEmitterComponent = defineComponent({ //name: The human-readable label for the component. This will be displayed in the editor and debugging tools. @@ -92,15 +93,22 @@ export const BubbleEmitterComponent = defineComponent({ // Spawning a single bubble as an example // [Exercise 1]: Using this system. Spawn multiple bubbles with varying x,z Localtransform positons // [Exercise 3]: Remove them if they are too old(bubble.age > N seconds)[This can be done in a couple ways(reactively and within this sytem synchronosly)] - if(emitterComponent.bubbleEntities.value!.length < 1) { //For example ensuring there is only one bubble being added + const bubbles: Array = [] + const numExistingBubbles = emitterComponent.bubbleEntities.value!.length + const numBubbles = 10 + for (let i = numExistingBubbles; i < numBubbles; i++) { const bubbleEntity = createEntity() setComponent(bubbleEntity, BubbleComponent) + setComponent(bubbleEntity, LocalTransformComponent, { + position: new Vector3((Math.random() - 0.5) * 100, 0, (Math.random() - 0.5) * 100) + }) setComponent(bubbleEntity, EntityTreeComponent, { parentEntity: entity, uuid: MathUtils.generateUUID() as EntityUUID }) - emitterComponent.bubbleEntities.merge([bubbleEntity]) + bubbles.push(bubbleEntity) } + emitterComponent.bubbleEntities.merge(bubbles) const bubble = getComponent(emitterComponent.bubbleEntities.value![0], BubbleComponent) From a219809b2e9034bf03c2b3bca071cc58430aa37e Mon Sep 17 00:00:00 2001 From: Rezmason Date: Fri, 8 Dec 2023 10:44:39 -0800 Subject: [PATCH 2/4] Exercise 2: move every bubble, not just the first one. --- src/systems/BubbleSystem.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/systems/BubbleSystem.ts b/src/systems/BubbleSystem.ts index 21e6557..087314d 100644 --- a/src/systems/BubbleSystem.ts +++ b/src/systems/BubbleSystem.ts @@ -18,12 +18,13 @@ export const BubbleSystem = defineSystem({ // [Exercise 2]: Using the below basic setup. Move every bubble not just the first one const tempvector = new Vector3(0,0,0) const emitterComponent = getComponent(entity, BubbleEmitterComponent) - const localTransform = getComponent(emitterComponent.bubbleEntities![0], LocalTransformComponent) - if(!localTransform) continue; - velocity.copy(emitterComponent.direction).multiplyScalar(emitterComponent.speed) - tempvector.addVectors(localTransform.position, velocity) - localTransform.position.copy(tempvector) - + for (const bubbleEntity of emitterComponent.bubbleEntities!) { + const localTransform = getComponent(bubbleEntity, LocalTransformComponent) + if(!localTransform) continue; + velocity.copy(emitterComponent.direction).multiplyScalar(emitterComponent.speed) + tempvector.addVectors(localTransform.position, velocity) + localTransform.position.copy(tempvector) + } // [Exercise 4]: Utilizing an AvatarComponent Query, TransformComponent positions of bubble entities, and Vector3.distanceTo // Detect if the player is near a bubble and remove it } From 36be1d05d20d6d23c311a31c13b82d69fc24f085 Mon Sep 17 00:00:00 2001 From: Rezmason Date: Fri, 8 Dec 2023 10:45:00 -0800 Subject: [PATCH 3/4] Exercise 3: remove bubbles if they reach the age threshold --- src/components/BubbleEmitterComponent.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/BubbleEmitterComponent.ts b/src/components/BubbleEmitterComponent.ts index 7f6f69d..5c7c208 100644 --- a/src/components/BubbleEmitterComponent.ts +++ b/src/components/BubbleEmitterComponent.ts @@ -110,11 +110,14 @@ export const BubbleEmitterComponent = defineComponent({ } emitterComponent.bubbleEntities.merge(bubbles) - const bubble = getComponent(emitterComponent.bubbleEntities.value![0], BubbleComponent) - - if(bubble.age >= 5) { // Delete one bubble after its age is greater than 5 seconds - removeBubble(entity,emitterComponent.bubbleEntities.value![0]) + const bubbleEntities = emitterComponent.bubbleEntities.value!.slice() + for (const bubbleEntity of bubbleEntities) { + const bubble = getComponent(bubbleEntity, BubbleComponent) + if (bubble.age >= 5) { + removeBubble(entity, bubbleEntity) + } } + }, { after: SimulationSystemGroup }) return null From 51ce7f76f94454a7fdf35a8da3d2b3dc6ba975de Mon Sep 17 00:00:00 2001 From: Rezmason Date: Fri, 8 Dec 2023 10:46:25 -0800 Subject: [PATCH 4/4] Exercise 4: detect if the player is near a bubble and remove it --- src/systems/BubbleSystem.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/systems/BubbleSystem.ts b/src/systems/BubbleSystem.ts index 087314d..9810598 100644 --- a/src/systems/BubbleSystem.ts +++ b/src/systems/BubbleSystem.ts @@ -1,13 +1,18 @@ import { defineQuery, getComponent, getMutableComponent } from "@etherealengine/engine/src/ecs/functions/ComponentFunctions"; import { defineSystem } from "@etherealengine/engine/src/ecs/functions/SystemFunctions"; import { BubbleEmitterComponent, removeBubble } from "../components/BubbleEmitterComponent"; -import { LocalTransformComponent } from "@etherealengine/engine/src/transform/components/TransformComponent"; +import { BubbleComponent } from "../components/BubbleComponent"; +import { LocalTransformComponent, TransformComponent } from "@etherealengine/engine/src/transform/components/TransformComponent"; import { NO_PROXY, getState } from "@etherealengine/hyperflux"; import { EngineState } from "@etherealengine/engine/src/ecs/classes/EngineState"; import { Vector3 } from "three"; import { SimulationSystemGroup } from "@etherealengine/engine/src/ecs/functions/EngineFunctions"; +import { AvatarComponent } from "@etherealengine/engine/src/avatar/components/AvatarComponent"; +import { EntityTreeComponent } from "@etherealengine/engine/src/ecs/functions/EntityTree"; const bubbleEmitterQuery = defineQuery([BubbleEmitterComponent]) +const bubbleQuery = defineQuery([BubbleComponent]) +const avatarQuery = defineQuery([AvatarComponent, TransformComponent]) const velocity = new Vector3(0,0,0) export const BubbleSystem = defineSystem({ @@ -28,5 +33,16 @@ export const BubbleSystem = defineSystem({ // [Exercise 4]: Utilizing an AvatarComponent Query, TransformComponent positions of bubble entities, and Vector3.distanceTo // Detect if the player is near a bubble and remove it } + + for (const bubbleEntity of bubbleQuery()) { + const bubbleWorldPosition = getComponent(bubbleEntity, TransformComponent).position + for (const avatarEntity of avatarQuery()) { + if (getComponent(avatarEntity, TransformComponent).position.distanceTo(bubbleWorldPosition) < 1) { + const emitter = getComponent(bubbleEntity, EntityTreeComponent).parentEntity! + removeBubble(emitter, bubbleEntity) + break + } + } + } } }) \ No newline at end of file