@dcl-regenesislabs/opendcl 0.2.1-26502482653.commit-5089b10 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -5
- package/context/sdk7-cheat-sheet.md +0 -4
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/extensions/dcl-init.ts +6 -58
- package/extensions/dcl-setup-ollama.ts +312 -0
- package/package.json +4 -3
- package/prompts/system.md +41 -71
- package/skills/add-3d-models/SKILL.md +70 -120
- package/skills/add-interactivity/SKILL.md +2 -74
- package/skills/advanced-input/SKILL.md +1 -34
- package/skills/advanced-rendering/SKILL.md +9 -82
- package/skills/animations-tweens/SKILL.md +98 -203
- package/skills/audio-video/SKILL.md +83 -184
- package/skills/build-ui/SKILL.md +2 -25
- package/skills/camera-control/SKILL.md +7 -78
- package/skills/create-scene/SKILL.md +13 -56
- package/skills/deploy-scene/SKILL.md +0 -12
- package/skills/deploy-worlds/SKILL.md +0 -35
- package/skills/game-design/SKILL.md +2 -1
- package/skills/lighting-environment/SKILL.md +56 -103
- package/skills/multiplayer-sync/SKILL.md +2 -31
- package/skills/nft-blockchain/SKILL.md +40 -45
- package/skills/optimize-scene/SKILL.md +2 -7
- package/skills/player-avatar/SKILL.md +7 -133
- package/skills/scene-runtime/SKILL.md +5 -9
- package/skills/visual-feedback/SKILL.md +0 -1
- package/skills/audio-analysis/SKILL.md +0 -164
- package/skills/editor-gizmo/.gitignore +0 -11
- package/skills/editor-gizmo/SKILL.md +0 -222
- package/skills/editor-gizmo/src/__editor/camera.ts +0 -277
- package/skills/editor-gizmo/src/__editor/discovery.ts +0 -210
- package/skills/editor-gizmo/src/__editor/drag.ts +0 -265
- package/skills/editor-gizmo/src/__editor/gizmo.ts +0 -496
- package/skills/editor-gizmo/src/__editor/history.ts +0 -72
- package/skills/editor-gizmo/src/__editor/index.ts +0 -138
- package/skills/editor-gizmo/src/__editor/input.ts +0 -55
- package/skills/editor-gizmo/src/__editor/math-utils.ts +0 -114
- package/skills/editor-gizmo/src/__editor/persistence.ts +0 -113
- package/skills/editor-gizmo/src/__editor/selection.ts +0 -157
- package/skills/editor-gizmo/src/__editor/state.ts +0 -117
- package/skills/editor-gizmo/src/__editor/ui.tsx +0 -699
- package/skills/npcs/SKILL.md +0 -180
- package/skills/particle-system/SKILL.md +0 -222
- package/skills/player-physics/SKILL.md +0 -93
|
@@ -5,22 +5,6 @@ description: Advanced rendering in Decentraland scenes. Billboard (face camera),
|
|
|
5
5
|
|
|
6
6
|
# Advanced Rendering in Decentraland
|
|
7
7
|
|
|
8
|
-
## Authoring split
|
|
9
|
-
|
|
10
|
-
`Billboard`, `TextShape`, `Material`, `MeshRenderer`, `GltfContainer`, `VisibilityComponent`, and `GltfNodeModifiers` are **all supported in `main-entities.ts`** — declare the visual entity (sign, label, billboard, glowing prop, model with per-node overrides) fully there with its visual components. Examples below that show `engine.addEntity()` followed by `Transform.create` + `MeshRenderer` / `Billboard` / `TextShape` are pre-`main-entities.ts` patterns — translate them by moving the entity declaration into `main-entities.ts` and keeping only runtime modifications (e.g., `VisibilityComponent.getMutable(entity).visible = false`) in `src/index.ts`.
|
|
11
|
-
|
|
12
|
-
```typescript
|
|
13
|
-
// Example: floating label
|
|
14
|
-
// main-entities.ts
|
|
15
|
-
shop_label: {
|
|
16
|
-
components: {
|
|
17
|
-
Transform: { position: { x: 8, y: 3, z: 8 } },
|
|
18
|
-
TextShape: { text: 'OPEN', fontSize: 4, textColor: { r: 1, g: 1, b: 1, a: 1 } },
|
|
19
|
-
Billboard: { billboardMode: 7 } // BM_ALL
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
8
|
## When to Use Which Rendering Feature
|
|
25
9
|
|
|
26
10
|
| Need | Component | When |
|
|
@@ -246,78 +230,21 @@ engine.addSystem(lodSystem)
|
|
|
246
230
|
|
|
247
231
|
### Per-Node Modifiers (GltfNodeModifiers)
|
|
248
232
|
|
|
249
|
-
Override material or shadow casting on specific nodes within a GLTF model
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
// main-entities.ts
|
|
253
|
-
armored_knight: {
|
|
254
|
-
components: {
|
|
255
|
-
Transform: { position: { x: 8, y: 0, z: 8 } },
|
|
256
|
-
GltfContainer: { src: 'models/knight.glb' },
|
|
257
|
-
GltfNodeModifiers: {
|
|
258
|
-
modifiers: [
|
|
259
|
-
{
|
|
260
|
-
path: 'RootNode/Armor', // GLTF hierarchy path
|
|
261
|
-
castShadows: false // disable shadows for this node
|
|
262
|
-
}
|
|
263
|
-
]
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**Whole-model override**: pass `path: ''` (empty string) to apply the modifier to every node in the model. Useful for re-skinning an entire model with a single material swap:
|
|
233
|
+
Override material or shadow casting on specific nodes within a GLTF model:
|
|
270
234
|
|
|
271
235
|
```typescript
|
|
272
|
-
|
|
273
|
-
components: {
|
|
274
|
-
Transform: { position: { x: 4, y: 0, z: 8 } },
|
|
275
|
-
GltfContainer: { src: 'models/unit.glb' },
|
|
276
|
-
GltfNodeModifiers: {
|
|
277
|
-
modifiers: [
|
|
278
|
-
{
|
|
279
|
-
path: '',
|
|
280
|
-
material: {
|
|
281
|
-
material: {
|
|
282
|
-
$case: 'pbr',
|
|
283
|
-
pbr: { albedoColor: { r: 1, g: 0, b: 0, a: 1 } }
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
]
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### Texture Tweens (Animate Material Textures)
|
|
294
|
-
|
|
295
|
-
Animate a material's texture offset/tiling over time — useful for water, lava, conveyor belts, scrolling backgrounds. Tween component is supported in `main-entities.ts`:
|
|
236
|
+
import { GltfNodeModifiers } from '@dcl/sdk/ecs'
|
|
296
237
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
MeshRenderer: { mesh: { $case: 'plane', plane: { uvs: [] } } },
|
|
303
|
-
Material: { material: { $case: 'pbr', pbr: { texture: { tex: { $case: 'texture', texture: { src: 'images/belt.png' } } } } } },
|
|
304
|
-
Tween: {
|
|
305
|
-
duration: 2000,
|
|
306
|
-
easingFunction: 0, // EF_LINEAR
|
|
307
|
-
mode: {
|
|
308
|
-
$case: 'textureMoveContinuous',
|
|
309
|
-
textureMoveContinuous: { direction: { x: 1, y: 0 }, speed: 0.5 }
|
|
310
|
-
// movementType defaults to 0 = TMT_OFFSET; use 1 = TMT_TILING to scale instead
|
|
311
|
-
}
|
|
238
|
+
GltfNodeModifiers.create(entity, {
|
|
239
|
+
modifiers: [
|
|
240
|
+
{
|
|
241
|
+
path: 'RootNode/Armor', // GLTF hierarchy path
|
|
242
|
+
castShadows: false // Disable shadow casting for this node
|
|
312
243
|
}
|
|
313
|
-
|
|
314
|
-
}
|
|
244
|
+
]
|
|
245
|
+
})
|
|
315
246
|
```
|
|
316
247
|
|
|
317
|
-
For a finite from-to texture move, use `{ $case: 'textureMove', textureMove: { start: { x: 0, y: 0 }, end: { x: 1, y: 0 }, movementType: 0 } }` with a `duration`.
|
|
318
|
-
|
|
319
|
-
Runtime helpers (in `src/index.ts`): `Tween.setTextureMove(entity, from, to, durationMs)` and `Tween.setTextureMoveContinuous(entity, direction, speed)`.
|
|
320
|
-
|
|
321
248
|
### Avatar Texture
|
|
322
249
|
|
|
323
250
|
Generate a texture from a player's avatar:
|
|
@@ -5,10 +5,6 @@ description: Animate objects in Decentraland scenes. Play GLTF model animations
|
|
|
5
5
|
|
|
6
6
|
# Animations and Tweens in Decentraland
|
|
7
7
|
|
|
8
|
-
## Authoring split
|
|
9
|
-
|
|
10
|
-
`Animator`, `Tween`, and `TweenSequence` are all supported in `main-entities.ts` — declare the entity, its visual components, and its initial animation state in the literal. Switch clips or replace tweens at runtime in `src/index.ts` via `getMutable`.
|
|
11
|
-
|
|
12
8
|
## When to Use Which Animation Approach
|
|
13
9
|
|
|
14
10
|
| Need | Approach | When |
|
|
@@ -25,214 +21,142 @@ description: Animate objects in Decentraland scenes. Play GLTF model animations
|
|
|
25
21
|
|
|
26
22
|
## GLTF Animations (Animator)
|
|
27
23
|
|
|
28
|
-
|
|
24
|
+
Play animations embedded in .glb models:
|
|
29
25
|
|
|
30
26
|
```typescript
|
|
31
|
-
|
|
32
|
-
import
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
} satisfies Scene
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Trigger and switch animations at runtime in `src/index.ts`:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { engine, Animator } from '@dcl/sdk/ecs'
|
|
55
|
-
|
|
56
|
-
export function main() {
|
|
57
|
-
const character = engine.getEntityOrNullByName('character')
|
|
58
|
-
if (!character) return
|
|
27
|
+
import { engine, Transform, GltfContainer, Animator } from '@dcl/sdk/ecs'
|
|
28
|
+
import { Vector3 } from '@dcl/sdk/math'
|
|
29
|
+
|
|
30
|
+
const character = engine.addEntity()
|
|
31
|
+
Transform.create(character, { position: Vector3.create(8, 0, 8) })
|
|
32
|
+
GltfContainer.create(character, { src: 'models/character.glb' })
|
|
33
|
+
|
|
34
|
+
// Set up animation states
|
|
35
|
+
Animator.create(character, {
|
|
36
|
+
states: [
|
|
37
|
+
{ clip: 'idle', playing: true, loop: true, speed: 1 },
|
|
38
|
+
{ clip: 'walk', playing: false, loop: true, speed: 1 },
|
|
39
|
+
{ clip: 'attack', playing: false, loop: false, speed: 1.5 }
|
|
40
|
+
]
|
|
41
|
+
})
|
|
59
42
|
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
// Play a specific animation
|
|
44
|
+
Animator.playSingleAnimation(character, 'walk')
|
|
62
45
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
46
|
+
// Stop all animations
|
|
47
|
+
Animator.stopAllAnimations(character)
|
|
66
48
|
```
|
|
67
49
|
|
|
68
50
|
### Switching Animations
|
|
69
51
|
```typescript
|
|
70
|
-
import { Entity, Animator } from '@dcl/sdk/ecs'
|
|
71
|
-
|
|
72
52
|
function playAnimation(entity: Entity, clipName: string) {
|
|
73
53
|
const animator = Animator.getMutable(entity)
|
|
74
|
-
|
|
54
|
+
// Stop all
|
|
55
|
+
for (const state of animator.states) {
|
|
56
|
+
state.playing = false
|
|
57
|
+
}
|
|
58
|
+
// Play the desired one
|
|
75
59
|
const state = animator.states.find(s => s.clip === clipName)
|
|
76
|
-
if (state)
|
|
60
|
+
if (state) {
|
|
61
|
+
state.playing = true
|
|
62
|
+
}
|
|
77
63
|
}
|
|
78
64
|
```
|
|
79
65
|
|
|
80
|
-
## Tweens
|
|
66
|
+
## Tweens (Code-Based Animation)
|
|
81
67
|
|
|
82
|
-
|
|
68
|
+
Animate entity properties smoothly over time:
|
|
83
69
|
|
|
84
70
|
### Move
|
|
85
71
|
```typescript
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
72
|
+
import { engine, Transform, Tween, EasingFunction } from '@dcl/sdk/ecs'
|
|
73
|
+
import { Vector3 } from '@dcl/sdk/math'
|
|
74
|
+
|
|
75
|
+
const box = engine.addEntity()
|
|
76
|
+
Transform.create(box, { position: Vector3.create(2, 1, 8) })
|
|
77
|
+
|
|
78
|
+
Tween.create(box, {
|
|
79
|
+
mode: Tween.Mode.Move({
|
|
80
|
+
start: Vector3.create(2, 1, 8),
|
|
81
|
+
end: Vector3.create(14, 1, 8)
|
|
82
|
+
}),
|
|
83
|
+
duration: 2000, // milliseconds
|
|
84
|
+
easingFunction: EasingFunction.EF_EASESINE
|
|
85
|
+
})
|
|
101
86
|
```
|
|
102
87
|
|
|
103
|
-
Common easing values: `0 = EF_LINEAR`, `1 = EF_EASEINQUAD`, `2 = EF_EASEOUTQUAD`, `3 = EF_EASEQUAD`, `6 = EF_EASESINE`. To replace or stop a tween at runtime, use `Tween.createOrReplace` / `Tween.deleteFrom` on the named entity in `src/index.ts`.
|
|
104
|
-
|
|
105
88
|
### Rotate
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// main-entities.ts — quaternions are { x, y, z, w } literals.
|
|
109
|
-
// 360° around Y end-state is { x: 0, y: 1, z: 0, w: 0 }
|
|
110
|
-
spinning_obj: {
|
|
111
|
-
components: {
|
|
112
|
-
Transform: { position: { x: 8, y: 1, z: 8 } },
|
|
113
|
-
MeshRenderer: { mesh: { $case: 'box', box: { uvs: [] } } },
|
|
114
|
-
Tween: {
|
|
115
|
-
duration: 3000,
|
|
116
|
-
easingFunction: 0, // EF_LINEAR
|
|
117
|
-
mode: {
|
|
118
|
-
$case: 'rotate',
|
|
119
|
-
rotate: {
|
|
120
|
-
start: { x: 0, y: 0, z: 0, w: 1 },
|
|
121
|
-
end: { x: 0, y: 1, z: 0, w: 0 }
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
For exact-degree rotations without hand-computing quaternions, leave the tween out of `main-entities.ts` and create it at runtime in `src/index.ts` where `Quaternion.fromEulerDegrees()` is available:
|
|
130
|
-
|
|
131
89
|
```typescript
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
mode: Tween.Mode.Rotate({
|
|
141
|
-
start: Quaternion.fromEulerDegrees(0, 0, 0),
|
|
142
|
-
end: Quaternion.fromEulerDegrees(0, 360, 0)
|
|
143
|
-
}),
|
|
144
|
-
duration: 3000,
|
|
145
|
-
easingFunction: EasingFunction.EF_LINEAR
|
|
146
|
-
})
|
|
147
|
-
}
|
|
90
|
+
Tween.create(box, {
|
|
91
|
+
mode: Tween.Mode.Rotate({
|
|
92
|
+
start: Quaternion.fromEulerDegrees(0, 0, 0),
|
|
93
|
+
end: Quaternion.fromEulerDegrees(0, 360, 0)
|
|
94
|
+
}),
|
|
95
|
+
duration: 3000,
|
|
96
|
+
easingFunction: EasingFunction.EF_LINEAR
|
|
97
|
+
})
|
|
148
98
|
```
|
|
149
99
|
|
|
150
100
|
### Scale
|
|
151
|
-
|
|
152
101
|
```typescript
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
mode: {
|
|
162
|
-
$case: 'scale',
|
|
163
|
-
scale: { start: { x: 1, y: 1, z: 1 }, end: { x: 2, y: 2, z: 2 } }
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
102
|
+
Tween.create(box, {
|
|
103
|
+
mode: Tween.Mode.Scale({
|
|
104
|
+
start: Vector3.create(1, 1, 1),
|
|
105
|
+
end: Vector3.create(2, 2, 2)
|
|
106
|
+
}),
|
|
107
|
+
duration: 1000,
|
|
108
|
+
easingFunction: EasingFunction.EF_EASEOUTBOUNCE
|
|
109
|
+
})
|
|
168
110
|
```
|
|
169
111
|
|
|
170
112
|
## Tween Sequences (Chained Animations)
|
|
171
113
|
|
|
172
|
-
Chain multiple tweens to play one after another
|
|
114
|
+
Chain multiple tweens to play one after another:
|
|
173
115
|
|
|
174
116
|
```typescript
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
117
|
+
import { TweenSequence, TweenLoop } from '@dcl/sdk/ecs'
|
|
118
|
+
|
|
119
|
+
// First tween
|
|
120
|
+
Tween.create(box, {
|
|
121
|
+
mode: Tween.Mode.Move({
|
|
122
|
+
start: Vector3.create(2, 1, 8),
|
|
123
|
+
end: Vector3.create(14, 1, 8)
|
|
124
|
+
}),
|
|
125
|
+
duration: 2000,
|
|
126
|
+
easingFunction: EasingFunction.EF_EASESINE
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Chain sequence
|
|
130
|
+
TweenSequence.create(box, {
|
|
131
|
+
sequence: [
|
|
132
|
+
// Second: move back
|
|
133
|
+
{
|
|
134
|
+
mode: Tween.Mode.Move({
|
|
135
|
+
start: Vector3.create(14, 1, 8),
|
|
136
|
+
end: Vector3.create(2, 1, 8)
|
|
137
|
+
}),
|
|
181
138
|
duration: 2000,
|
|
182
|
-
easingFunction:
|
|
183
|
-
mode: { $case: 'move', move: { start: { x: 2, y: 1, z: 8 }, end: { x: 14, y: 1, z: 8 } } }
|
|
184
|
-
},
|
|
185
|
-
TweenSequence: {
|
|
186
|
-
loop: 0, // TweenLoop.TL_RESTART (1 = TL_YOYO)
|
|
187
|
-
sequence: [
|
|
188
|
-
{
|
|
189
|
-
duration: 2000,
|
|
190
|
-
easingFunction: 6,
|
|
191
|
-
mode: { $case: 'move', move: { start: { x: 14, y: 1, z: 8 }, end: { x: 2, y: 1, z: 8 } } }
|
|
192
|
-
}
|
|
193
|
-
]
|
|
139
|
+
easingFunction: EasingFunction.EF_EASESINE
|
|
194
140
|
}
|
|
195
|
-
|
|
196
|
-
|
|
141
|
+
],
|
|
142
|
+
loop: TweenLoop.TL_RESTART // Loop the entire sequence
|
|
143
|
+
})
|
|
197
144
|
```
|
|
198
145
|
|
|
199
146
|
## Easing Functions
|
|
200
147
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
| 8 | EF_EASEOUTEXPO | Exponential out |
|
|
214
|
-
| 9 | EF_EASEEXPO | Exponential in-out |
|
|
215
|
-
| 10 | EF_EASEINELASTIC | Elastic in |
|
|
216
|
-
| 11 | EF_EASEOUTELASTIC | Elastic out |
|
|
217
|
-
| 12 | EF_EASEELASTIC | Elastic in-out |
|
|
218
|
-
| 13 | EF_EASEINBOUNCE | Bounce in |
|
|
219
|
-
| 14 | EF_EASEOUTBOUNCE | Bounce out |
|
|
220
|
-
| 15 | EF_EASEBOUNCE | Bounce in-out |
|
|
221
|
-
| 16 | EF_EASEINCUBIC | Cubic in |
|
|
222
|
-
| 17 | EF_EASEOUTCUBIC | Cubic out |
|
|
223
|
-
| 18 | EF_EASECUBIC | Cubic in-out |
|
|
224
|
-
| 19 | EF_EASEINQUART | Quartic in |
|
|
225
|
-
| 20 | EF_EASEOUTQUART | Quartic out |
|
|
226
|
-
| 21 | EF_EASEQUART | Quartic in-out |
|
|
227
|
-
| 22 | EF_EASEINQUINT | Quintic in |
|
|
228
|
-
| 23 | EF_EASEOUTQUINT | Quintic out |
|
|
229
|
-
| 24 | EF_EASEQUINT | Quintic in-out |
|
|
230
|
-
| 25 | EF_EASEINCIRC | Circular in |
|
|
231
|
-
| 26 | EF_EASEOUTCIRC | Circular out |
|
|
232
|
-
| 27 | EF_EASECIRC | Circular in-out |
|
|
233
|
-
| 28 | EF_EASEINBACK | Overshoot in |
|
|
234
|
-
| 29 | EF_EASEOUTBACK | Overshoot out |
|
|
235
|
-
| 30 | EF_EASEBACK | Overshoot in-out |
|
|
148
|
+
Available easing functions from `EasingFunction`:
|
|
149
|
+
- `EF_LINEAR` — Constant speed
|
|
150
|
+
- `EF_EASEINQUAD` / `EF_EASEOUTQUAD` / `EF_EASEQUAD` — Quadratic
|
|
151
|
+
- `EF_EASEINSINE` / `EF_EASEOUTSINE` / `EF_EASESINE` — Sinusoidal (smooth)
|
|
152
|
+
- `EF_EASEINEXPO` / `EF_EASEOUTEXPO` / `EF_EASEEXPO` — Exponential
|
|
153
|
+
- `EF_EASEINELASTIC` / `EF_EASEOUTELASTIC` / `EF_EASEELASTIC` — Elastic bounce
|
|
154
|
+
- `EF_EASEOUTBOUNCE` / `EF_EASEINBOUNCE` / `EF_EASEBOUNCE` — Bounce effect
|
|
155
|
+
- `EF_EASEINBACK` / `EF_EASEOUTBACK` / `EF_EASEBACK` — Overshoot
|
|
156
|
+
- `EF_EASEINCUBIC` / `EF_EASEOUTCUBIC` / `EF_EASECUBIC` — Cubic
|
|
157
|
+
- `EF_EASEINQUART` / `EF_EASEOUTQUART` / `EF_EASEQUART` — Quartic
|
|
158
|
+
- `EF_EASEINQUINT` / `EF_EASEOUTQUINT` / `EF_EASEQUINT` — Quintic
|
|
159
|
+
- `EF_EASEINCIRC` / `EF_EASEOUTCIRC` / `EF_EASECIRC` — Circular
|
|
236
160
|
|
|
237
161
|
## Custom Animation Systems
|
|
238
162
|
|
|
@@ -281,23 +205,8 @@ Tween.setScale(entity,
|
|
|
281
205
|
Vector3.One(), Vector3.create(2, 2, 2),
|
|
282
206
|
1000, EasingFunction.EF_LINEAR
|
|
283
207
|
)
|
|
284
|
-
|
|
285
|
-
// Combined Move + Rotate + Scale in one Tween
|
|
286
|
-
Tween.setMoveRotateScale(entity, {
|
|
287
|
-
positionStart: Vector3.create(0, 0, 0), positionEnd: Vector3.create(0, 5, 0),
|
|
288
|
-
rotationStart: Quaternion.fromEulerDegrees(0, 0, 0), rotationEnd: Quaternion.fromEulerDegrees(0, 360, 0),
|
|
289
|
-
scaleStart: Vector3.One(), scaleEnd: Vector3.create(0.5, 0.5, 0.5)
|
|
290
|
-
}, 2000, EasingFunction.EF_EASEINOUTCUBIC)
|
|
291
|
-
|
|
292
|
-
// Continuous spin — applies a per-frame Quaternion delta. No end state.
|
|
293
|
-
Tween.setRotateContinuous(entity, Quaternion.fromEulerDegrees(0, -1, 0), 700)
|
|
294
|
-
|
|
295
|
-
// Continuous move — applies a per-frame Vector3 delta scaled by speed.
|
|
296
|
-
Tween.setMoveContinuous(entity, Vector3.create(0, 0, 1), 0.5)
|
|
297
208
|
```
|
|
298
209
|
|
|
299
|
-
`*Continuous` variants don't end — they apply a constant delta until the Tween is removed (`Tween.deleteFrom(entity)`).
|
|
300
|
-
|
|
301
210
|
### Yoyo Loop Mode
|
|
302
211
|
|
|
303
212
|
`TL_YOYO` reverses the tween at each end instead of restarting:
|
|
@@ -338,20 +247,6 @@ anim.states[0].weight = 0.5 // blend walk at 50%
|
|
|
338
247
|
anim.states[1].weight = 0.5 // blend idle at 50%
|
|
339
248
|
```
|
|
340
249
|
|
|
341
|
-
### Morph Targets (Blend Shapes)
|
|
342
|
-
|
|
343
|
-
If a GLTF model exports morph targets (e.g., facial expressions, shape blends), drive them via the `weights` array on each `Animator.state`. Indices match the order morph targets were exported. Values range `0`–`1`.
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
const anim = Animator.getMutable(entity)
|
|
347
|
-
const state = anim.states.find(s => s.clip === 'Idle')
|
|
348
|
-
if (state) {
|
|
349
|
-
state.weights = state.weights ?? []
|
|
350
|
-
state.weights[0] = 0.8 // morph target 0 at 80%
|
|
351
|
-
state.weights[1] = 0.3 // morph target 1 at 30%
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
250
|
## Troubleshooting
|
|
356
251
|
|
|
357
252
|
| Problem | Cause | Solution |
|