-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.* | ||
package.json | ||
package-lock.json | ||
yarn-lock.json | ||
build.json | ||
export | ||
tsconfig.json | ||
tslint.json | ||
node_modules | ||
*.ts | ||
*.tsx | ||
Dockerfile | ||
dist | ||
screenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "@dcl/eslint-config/sdk", | ||
"parserOptions": { | ||
"project": ["tsconfig.json"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package-lock.json | ||
node_modules | ||
bin | ||
*.swp | ||
*.*~ | ||
export | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Avatar Swap | ||
A scene that uses `AvatarModifier` component to swap out the default avatar for another character model. This way the player's character style can match that of the enviroment's. | ||
|
||
![](screenshots/avatar-swap.gif) | ||
|
||
This scene shows: | ||
- How to add a 3D model | ||
- How to play animations from a 3D model | ||
- How to hide an avatar using `AvatarModifier` component | ||
- How to attach an entity to the Player | ||
- How to get the Player's entity `Transform` and its position | ||
|
||
## Instructions | ||
Run over to the area covered in grass to automatically switch avatars. Use your mouse to look around and <kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd> keys on your keyboard to move forward, left, backward and right respectively. | ||
|
||
## Try it out | ||
|
||
**Install the CLI** | ||
|
||
Download and install the Decentraland CLI by running the following command inside this scene root directory: | ||
|
||
```bash | ||
npm install @dcl/sdk@next | ||
``` | ||
|
||
**Previewing the scene** | ||
|
||
Inside this scene root directory run: | ||
|
||
``` | ||
dcl start | ||
``` | ||
|
||
## Copyright info | ||
|
||
This scene is protected with a standard Apache 2 licence. See the terms and conditions in the [LICENSE](/LICENSE) file. | ||
|
||
## Acknowledgements | ||
|
||
Model and animations from https://www.mixamo.com/ |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "avatar-swap", | ||
"version": "1.0.0", | ||
"description": "Avatar Swap", | ||
"scripts": { | ||
"start": "dcl start", | ||
"build": "build-ecs", | ||
"watch": "build-ecs --watch", | ||
"lint": "eslint . --ext .ts", | ||
"lint:fix": "eslint . --ext .ts --fix" | ||
}, | ||
"devDependencies": { | ||
"@dcl/eslint-config": "^1.0.1", | ||
"@dcl/sdk": "next" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"ecs7": true, | ||
"display": { | ||
"title": "avatar-swap", | ||
"favicon": "favicon_asset" | ||
}, | ||
"contact": { | ||
"name": "decentraland", | ||
"email": "" | ||
}, | ||
"owner": "", | ||
"scene": { | ||
"parcels": [ | ||
"23,23" | ||
], | ||
"base": "23,23" | ||
}, | ||
"requiredPermissions": [], | ||
"main": "bin/game.js", | ||
"tags": [], | ||
"spawnPoints": [ | ||
{ | ||
"name": "spawn1", | ||
"default": true, | ||
"position": { | ||
"x": 0, | ||
"y": 0, | ||
"z": 0 | ||
}, | ||
"cameraTarget": { | ||
"x": 8, | ||
"y": 1, | ||
"z": 8 | ||
} | ||
} | ||
] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
export * from '@dcl/sdk' | ||
import { engine, GltfContainer, Transform } from '@dcl/sdk/ecs' | ||
import { Vector3 } from '@dcl/sdk/math' | ||
import { attachEntityToPlayer } from "./modules/utils"; | ||
import { createArissaCharacter } from "./modules/arissa"; | ||
import { createAvatarSwappingArea, avatarSwappingSystem } from "./modules/avatarSwappingArea"; | ||
|
||
function setup() { | ||
// Instantiate ground model | ||
const groundEntity = engine.addEntity() | ||
GltfContainer.create(groundEntity, { | ||
src: "models/baseGrass.glb" | ||
}) | ||
|
||
// Instantiate 'Arissa' character animated model | ||
const arissaCharaEntity = createArissaCharacter() | ||
attachEntityToPlayer(Transform.get(arissaCharaEntity).parent) | ||
|
||
// Set avatar modifier area to swap player avatar | ||
createAvatarSwappingArea(Vector3.create(8, 2, 10.5), Vector3.create(16, 4, 11), arissaCharaEntity) | ||
|
||
// Register avatar swapping system | ||
engine.addSystem(avatarSwappingSystem) | ||
} | ||
|
||
setup() | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { | ||
engine, | ||
Entity, | ||
GltfContainer, | ||
Transform, | ||
Animator | ||
} from '@dcl/sdk/ecs' | ||
import { Vector3 } from "@dcl/sdk/math"; | ||
|
||
export function createArissaCharacter() : Entity { | ||
const parentEntity = engine.addEntity() | ||
const entity = engine.addEntity() | ||
|
||
GltfContainer.create(entity, { | ||
src: "models/arissa.glb" | ||
}) | ||
Transform.create(entity, { | ||
position: Vector3.create(0, 1.75, 0), | ||
scale: Vector3.create(0, 0, 0), | ||
parent: parentEntity | ||
}) | ||
Animator.create(entity, { | ||
states: [ | ||
{ | ||
name: "Running", | ||
clip: "Running", | ||
loop: true | ||
}, | ||
{ | ||
name: "Idle", | ||
clip: "Idle", | ||
loop: true | ||
} | ||
] | ||
}) | ||
|
||
return entity | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { | ||
engine, | ||
Entity, | ||
Transform, | ||
Animator, | ||
AvatarModifierArea, | ||
AvatarModifierType | ||
} from '@dcl/sdk/ecs' | ||
import { Vector3 } from '@dcl/sdk/math' | ||
|
||
let areaCenter: Vector3 | ||
let areaSize: Vector3 | ||
let areaMinPosition: Vector3 | ||
let areaMaxPosition: Vector3 | ||
|
||
function setupAreaData(center: Vector3, size: Vector3) { | ||
areaCenter = center | ||
areaSize = size | ||
|
||
const halfSize = Vector3.scale(size, 0.5) | ||
areaMinPosition = Vector3.create( | ||
areaCenter.x - halfSize.x, | ||
areaCenter.y - halfSize.y, | ||
areaCenter.z - halfSize.z | ||
) | ||
areaMaxPosition = Vector3.create( | ||
areaCenter.x + halfSize.x, | ||
areaCenter.y + halfSize.y, | ||
areaCenter.z + halfSize.z | ||
) | ||
} | ||
|
||
function isPositionInsideArea(targetPosition: Vector3): boolean { | ||
return targetPosition.x > areaMinPosition.x | ||
&& targetPosition.y > areaMinPosition.y | ||
&& targetPosition.z > areaMinPosition.z | ||
&& targetPosition.x < areaMaxPosition.x | ||
&& targetPosition.y < areaMaxPosition.y | ||
&& targetPosition.z < areaMaxPosition.z | ||
} | ||
|
||
let otherAvatarEntity: Entity | ||
export function createAvatarSwappingArea(center: Vector3, size: Vector3, avatarEntity: Entity) { | ||
setupAreaData(center, size) | ||
otherAvatarEntity = avatarEntity | ||
const avatarHiderAreaEntity = engine.addEntity() | ||
AvatarModifierArea.create(avatarHiderAreaEntity, { | ||
area: areaSize, | ||
modifiers: [AvatarModifierType.AMT_HIDE_AVATARS], | ||
excludeIds: [] | ||
}) | ||
Transform.create(avatarHiderAreaEntity, { | ||
position: areaCenter | ||
}) | ||
} | ||
|
||
let lastPlayerPos: Vector3 | undefined = undefined | ||
export function avatarSwappingSystem (dt: number) { | ||
if (!Transform.has(engine.PlayerEntity)) return | ||
|
||
const playerPos = Transform.get(engine.PlayerEntity).position | ||
const moved = playerPos != lastPlayerPos | ||
|
||
Animator.getClip(otherAvatarEntity, "Idle").playing = !moved | ||
Animator.getClip(otherAvatarEntity, "Running").playing = moved | ||
|
||
if (!moved) return | ||
|
||
const playerIsInsideHidingArea = isPositionInsideArea(playerPos) | ||
const otherAvatarTransform = Transform.getMutable(otherAvatarEntity) | ||
otherAvatarTransform.scale.x = playerIsInsideHidingArea ? 1.1 : 0 | ||
otherAvatarTransform.scale.y = playerIsInsideHidingArea ? 1.1 : 0 | ||
otherAvatarTransform.scale.z = playerIsInsideHidingArea ? 1.1 : 0 | ||
|
||
lastPlayerPos = playerPos | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { AvatarAnchorPointType, AvatarAttach, Entity } from "@dcl/sdk/ecs"; | ||
import { getUserData } from "~system/UserIdentity" | ||
|
||
export async function attachEntityToPlayer (entity: Entity){ | ||
let userData = await getUserData({}) | ||
if(!userData.data) return | ||
console.log(`userId: ${userData.data.userId}`) | ||
|
||
AvatarAttach.create(entity, { | ||
anchorPointId: AvatarAnchorPointType.AAPT_POSITION, | ||
avatarId: userData.data.userId | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"compilerOptions": {}, | ||
"include": ["src/**/*.ts", "@dcl/ecs"], | ||
"extends": "@dcl/sdk/types/tsconfig.ecs7.strict.json" | ||
} |