5
5
defineState ,
6
6
dispatchAction ,
7
7
getMutableState ,
8
+ getState ,
8
9
none ,
9
10
useHookstate
10
11
} from '@etherealengine/hyperflux'
@@ -14,35 +15,43 @@ import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID'
14
15
import { NetworkTopics } from '@etherealengine/spatial/src/networking/classes/Network'
15
16
import { WorldNetworkAction } from '@etherealengine/spatial/src/networking/functions/WorldNetworkAction'
16
17
17
- import { PhysicsSystem } from '@etherealengine/spatial/src/physics/PhysicsModule'
18
-
19
18
import { isClient } from '@etherealengine/common/src/utils/getEnvironment'
20
- import { defineSystem , getComponent , setComponent } from '@etherealengine/ecs'
19
+ import { PresentationSystemGroup , defineSystem , getComponent , setComponent } from '@etherealengine/ecs'
20
+ import { ECSState } from '@etherealengine/ecs/src/ECSState'
21
21
import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent'
22
- import { TransformComponent } from '@etherealengine/spatial /src/transform/components/TransformComponent '
22
+ import { GeometryTypeEnum } from '@etherealengine/engine /src/scene/constants/GeometryTypeEnum '
23
23
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
24
24
import { UUIDComponent } from '@etherealengine/spatial/src/common/UUIDComponent'
25
+ import { NetworkState } from '@etherealengine/spatial/src/networking/NetworkState'
26
+ import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent'
27
+ import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent'
25
28
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
26
-
27
- //
28
- // Description of the format of a spawn action to create a artifact
29
- //
30
-
31
- class BasicActions {
32
- static spawnAction = defineAction ( {
33
- ...WorldNetworkAction . spawnObject . actionShape ,
34
- prefab : 'ee.basic.ball' ,
35
- $topic : NetworkTopics . world
36
- } )
29
+ import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
30
+ import { Vector3 } from 'three'
31
+
32
+ /**
33
+ * Basic actions to spawn and destroy objects
34
+ * This extends and naturally utilizes the functionality in EntityNetworkState
35
+ */
36
+
37
+ const BasicActions = {
38
+ spawnAction : defineAction (
39
+ WorldNetworkAction . spawnObject . extend ( {
40
+ type : 'ee.basic.SPAWN_BALL' ,
41
+ $topic : NetworkTopics . world
42
+ } )
43
+ )
37
44
}
38
45
39
- //
40
- // Global state that tracks locally spawned or destroyed artifacts by using action receptors
41
- / /
46
+ /**
47
+ * Global state that tracks locally spawned or destroyed artifacts by using action receptors
48
+ * /
42
49
43
- export const BasicState = defineState ( {
50
+ const BasicState = defineState ( {
44
51
name : 'ee.basic.BasicState' ,
52
+
45
53
initial : { } as Record < EntityUUID , { } > ,
54
+
46
55
receptors : {
47
56
onSpawnAction : BasicActions . spawnAction . receive ( ( action ) => {
48
57
const state = getMutableState ( BasicState )
@@ -55,101 +64,80 @@ export const BasicState = defineState({
55
64
}
56
65
} )
57
66
58
- //
59
- // A reactor such that each basic state record has an associated a visual artifact
60
- / /
67
+ /**
68
+ * A reactor such that each basic state record has an associated a visual artifact
69
+ * /
61
70
62
71
const ArtifactReactor = ( { entityUUID } : { entityUUID : EntityUUID } ) => {
63
- const basicState = useHookstate ( getMutableState ( BasicState ) [ entityUUID ] )
64
- useEffect ( ( ) => {
65
- const entity = UUIDComponent . getEntityByUUID ( entityUUID )
66
- setComponent ( entity , TransformComponent )
67
- setComponent ( entity , VisibleComponent )
68
- setComponent ( entity , NameComponent , 'hello' )
69
- setComponent ( entity , PrimitiveGeometryComponent , { geometryType : 1 } )
70
-
71
- /*
72
+ /** Entity creation and destruction is handled by EntityNetworkState */
73
+ const entity = UUIDComponent . useEntityByUUID ( entityUUID )
72
74
73
- setComponent(entity, ColliderComponent, {
74
- bodyType: 0, // dynamic
75
- shapeType: 1, // sphere
76
- collisionMask: 1,
77
- restitution: 0.5
78
- })
75
+ useEffect ( ( ) => {
76
+ if ( ! entity ) return
79
77
80
- const rigidBodyDesc = RigidBodyDesc.dynamic()
81
- Physics.createRigidBody(entity, getState(PhysicsState).physicsWorld, rigidBodyDesc, [])
82
-
83
- const rigidBody = getComponent(entity, RigidBodyComponent)
84
-
85
- const interactionGroups = getInteractionGroups(CollisionGroups.Default, DefaultCollisionMask)
86
- const colliderDesc = ColliderDesc.ball(0.1).setCollisionGroups(interactionGroups)
87
- colliderDesc.setRestitution(1)
88
-
89
- Physics.createColliderAndAttachToRigidBody(getState(PhysicsState).physicsWorld, colliderDesc, rigidBody.body)
90
-
91
- */
78
+ setComponent ( entity , TransformComponent , { scale : new Vector3 ( 0.1 , 0.1 , 0.1 ) } )
79
+ setComponent ( entity , VisibleComponent )
80
+ setComponent ( entity , NameComponent , entityUUID )
81
+ setComponent ( entity , PrimitiveGeometryComponent , { geometryType : GeometryTypeEnum . SphereGeometry } )
82
+ setComponent ( entity , RigidBodyComponent , { type : 'dynamic' } )
83
+ setComponent ( entity , ColliderComponent , { shape : 'sphere' } )
92
84
93
85
if ( isClient ) return
94
86
95
- // positions are networked intrinsically
87
+ const angle = Math . random ( ) * Math . PI * 2
88
+ const direction = new Vector3 ( Math . sin ( angle ) , 0 , Math . cos ( angle ) )
89
+ const velocity = 0.025 + Math . random ( ) * 0.01
90
+ getComponent ( entity , RigidBodyComponent ) . body . applyImpulse ( direction . multiplyScalar ( velocity ) , true )
91
+ } , [ entity ] )
96
92
97
- const x = Math . random ( ) * 10
98
- const y = 0
99
- const z = Math . random ( ) * 10
100
- const transform = getComponent ( entity , TransformComponent )
101
- transform . position . set ( x , y , z )
102
-
103
- // forces are networked intrinsically
104
-
105
- //const angle = Math.random()*Math.PI*2
106
- //const direction = new Vector3( Math.sin(angle),0,Math.cos(angle))
107
- //const velocity = 0.025 + Math.random()*0.01
108
- //rigidBody.body.applyImpulse(direction.multiplyScalar(velocity), true)
109
- } , [ ] )
110
93
return null
111
94
}
112
95
113
- //
114
- // Observe spawn events and make sure there are sub reactors that reflect them
115
- // Make sub-reactors for each entry
116
- //
96
+ /**
97
+ * Observe spawn events and create a sub-reactor for each entry in the basic state
98
+ */
117
99
118
100
const reactor = ( ) => {
119
101
const basicState = useHookstate ( getMutableState ( BasicState ) )
120
102
return (
121
103
< >
122
104
{ basicState . keys . map ( ( entityUUID : EntityUUID ) => (
123
- < ArtifactReactor entityUUID = { entityUUID } />
105
+ < ArtifactReactor key = { entityUUID } entityUUID = { entityUUID } />
124
106
) ) }
125
107
</ >
126
108
)
127
109
}
128
110
129
111
let counter = 0
112
+ const spawnRate = 3
130
113
131
- //
132
- // Periodically change the basic state
133
- / /
114
+ /**
115
+ * Spawn a new basic entity every 3 seconds
116
+ * /
134
117
135
118
const execute = ( ) => {
136
- if ( isClient ) return
137
- counter ++
138
- if ( counter & 255 ) return
119
+ /** Only run this on the server */
120
+ if ( isClient || ! NetworkState . worldNetwork ) return
121
+
122
+ const { deltaSeconds, elapsedSeconds } = getState ( ECSState )
123
+
124
+ counter += deltaSeconds
125
+
126
+ if ( counter < spawnRate ) return
127
+ counter = 0
139
128
140
- const entityUUID = `basic-${ counter } ` as EntityUUID
141
- const prefab = 'ee.basic.ball'
142
- const action = BasicActions . spawnAction ( { entityUUID, prefab } )
129
+ const entityUUID = `basic-${ elapsedSeconds } ` as EntityUUID
130
+ const action = BasicActions . spawnAction ( { entityUUID, position : new Vector3 ( Math . random ( ) , 1 , Math . random ( ) ) } )
143
131
dispatchAction ( action )
144
132
}
145
133
146
- //
147
- // System
148
- / /
134
+ /**
135
+ * System to register the execute function and reactor
136
+ * /
149
137
150
138
export const BasicSystem = defineSystem ( {
151
139
uuid : 'basic.system' ,
152
140
reactor,
153
141
execute,
154
- insert : { after : PhysicsSystem }
142
+ insert : { after : PresentationSystemGroup }
155
143
} )
0 commit comments