INTERFAZ DE USUARIO
Introducción
8th Wall Studio ofrece un sistema de interfaz de usuario integrado para crear interfaces interactivas y fáciles de usar dentro de su experiencia.Diseño de interfaz y componentes
Studio ofrece una gran variedad de elementos de interfaz de usuario, desde texto e imágenes hasta botones y marcos. Nuestra intuitiva opción (+) en el panel Jerarquía facilita la adición y personalización de elementos de interfaz de usuario. El componente de elementos de interfaz de usuario incluye opciones de configuración detalladas inspiradas en CSS y Flexbox, que permiten ajustar desde los bordes hasta los colores de fondo. Más información sobre el estilo Flexbox aquí.
Añadir elementos de interfaz de usuario
Puede introducir elementos de interfaz de usuario a través de varios métodos:
- Editor Visual: Utilice la opción (+) en la Jerarquía para añadir preselecciones.
- Método de componentes: Adjuntar elementos de interfaz de usuario como componentes en una entidad.
- Scripting: Añadir elementos mediante programación utilizando la API.
IU 3D
Los elementos de interfaz de usuario 3D se integran a la perfección en la escena 3D, lo que permite una visualización espacial interactiva. Puede ajustarlos a través del inspector o del artilugio de transformación.
Interacción
Puede añadir interacción a los elementos de la interfaz de usuario 3D mediante un componente personalizado con un receptor de eventos.
Ejemplo
import * as ecs from '@8thwall/ecs'
ecs.registerComponent({
name: 'Botón 3D',
schema: {
},
schemaDefaults: {
},
data: {
},
stateMachine: ({world, eid}) => {
ecs.defineState('default')
.initial()
.listen(eid, ecs.input.SCREEN_TOUCH_START, (e) => {
console.log('¡Interactuado!')
})
},
})
Interfaz de usuario superpuesta
Para la interfaz de usuario anclada a la pantalla, los elementos superpuestos ofrecen un posicionamiento absoluto. Previsualice estos elementos en el simulador y utilice un tamaño basado en porcentajes para el diseño adaptable, por ejemplo, width: 100%
.
Interacción
Puede añadir interacción a los elementos superpuestos de la interfaz de usuario mediante un componente personalizado con un receptor de eventos.
Ejemplo
import * as ecs from '@8thwall/ecs'
ecs.registerComponent({
name: 'Botón de superposición',
schema: {
},
schemaDefaults: {
},
data: {
},
stateMachine: ({world, eid}) => {
ecs.defineState('default')
.initial()
.listen(eid, 'click', (e) => {
console.log('¡Interactuado!')
})
},
})
Integración con máquinas de estado
Como se ha visto en ejemplos anteriores en esta página, la interfaz de usuario se puede integrar con [máquinas de estado] (../essentials/state-machines.mdx) para implementar características tales como la navegación por menús básicos como se muestra a continuación.
Estos botones construidos con componentes de interfaz de usuario se pueden configurar para enviar un evento cuando se interactúa con ellos.
ecs.registerComponent({
name: 'start-button',
stateMachine: ({world, eid}) => {
ecs.defineState('default')
.initial()
.listen(eid, ecs.input.UI_CLICK, () => {
world.events.dispatch(eid, 'onStartButtonClick')
})
},
})
Los menús de interfaz de usuario creados en Studio pueden seguirse y organizarse por estados.
enum GAME_STATES {
GAME_START = 'gameStateStart',
GAME_ACTIVE = 'gameStateActive',
GAME_OVER = 'gameStateOver',
}
enum GAME_MENUS {
START_MENU = 'startMenu',
GAME_OVER_MENU = 'gameOverMenu',
}
Para facilitar el cambio entre menús ocultando todos los demás menús y mostrando el menú que queremos que esté activo, podemos utilizar una función para ocultar mediante programación todos los menús no activos.
const updateUI = (world, schema, activeMenu = null) => {
Object.values(GAME_MENUS).forEach((menu) => {
if (schema[menu]) {
if (menu === activeMenu) {
ecs.Hidden.remove(world, schema[menu])
} else {
ecs.Hidden.set(world, schema[menu])
}
} else {
console.warn(`El menú ${menu} no está definido en el esquema.`)
}
})
}
Todo lo anterior se puede utilizar para gestionar una máquina de estados para la navegación por el menú que cambia en función de los clics de los botones y los estados del juego. En el siguiente ejemplo, iniciamos un juego al pulsar el botón de inicio, y activamos un menú de fin de juego después de un tiempo determinado. Desde el menú de fin de partida, con otros botones puedes reiniciar el juego o volver al menú de inicio.
ecs.registerComponent({
name: 'game-controller',
schema: {
startMenu: ecs.eid,
gameOverMenu: ecs.eid,
gameActiveMenu: ecs.eid,
},
data: {
isGameActive: ecs.boolean,
},
stateMachine: ({world, eid, dataAttribute, schemaAttribute}) => {
const gameOver = ecs.defineTrigger()
ecs.defineState(GAME_STATES.GAME_START)
.initial()
.onEnter(() => {
console.log('Entered Game Start')
updateUI(world, schemaAttribute.cursor(eid), GAME_MENUS.START_MENU)
})
.onEvent('onStartButtonClick', GAME_STATES.GAME_ACTIVE, {target: world.events.globalId})
ecs.defineState(GAME_STATES.GAME_ACTIVE)
.onEnter(() => {
console.log('State Change: Entered Game Active')
updateUI(world, schemaAttribute.cursor(eid), 'gameActive')
setTimeout(() => {
console.log('Espera terminada. Activando game over.')
gameOver.trigger()
}, 1000)
})
.onTrigger(gameOver, GAME_STATES.GAME_OVER)
ecs.defineState(GAME_STATES.GAME_OVER)
.onEnter(() => {
dataAttribute.cursor(eid).isGameActive = false
updateUI(world, schemaAttribute.cursor(eid), GAME_MENUS.GAME_OVER_MENU)
})
.onEvent('onRestartButtonClick', GAME_STATES.GAME_ACTIVE, {target: world.events.globalId})
.onEvent('onReturnStartClick', GAME_STATES.GAME_START, {target: world.events.globalId})
},
})
Fuentes
Fuentes predeterminadas
Las fuentes predeterminadas están disponibles para su uso en el sistema de interfaz de usuario.
Nunito
Akidenz Grotesk
Baskerville
Futura
Gotham
Helvetica
Nanum Pen Script
Press Start 2P
Times
Inconsolata
Fuentes personalizadas
También puede cargar fuentes personalizadas mediante archivos TTF para utilizarlas en sus elementos de interfaz de usuario. Añada archivos de fuentes personalizadas a sus activos para que estén disponibles.