From bfcf98091247b21bdbd95fbe5265b3644b1d689e Mon Sep 17 00:00:00 2001 From: Pato Date: Wed, 16 Mar 2022 19:06:08 -0300 Subject: [PATCH 1/2] feat: display scene's spawn points in preview mode --- packages/entryPoints/index.ts | 1 + packages/unity-interface/ClientDebug.ts | 89 ++++++++++++++++++++++--- packages/unity-interface/dcl.ts | 23 +++++-- 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/packages/entryPoints/index.ts b/packages/entryPoints/index.ts index 8fde4b2fd..d8e61d74e 100644 --- a/packages/entryPoints/index.ts +++ b/packages/entryPoints/index.ts @@ -317,6 +317,7 @@ export async function startPreview() { } }) clientDebug.ToggleSceneBoundingBoxes(sceneData.sceneId, false).catch((e) => defaultLogger.error(e)) + clientDebug.ToggleSceneSpawnPoints(sceneData.sceneId, false).catch((e) => defaultLogger.error(e)) unityInterface.SendMessageToUnity('Main', 'TogglePreviewMenu', JSON.stringify({ enabled: true })) } }) diff --git a/packages/unity-interface/ClientDebug.ts b/packages/unity-interface/ClientDebug.ts index f96a255c5..d8cde5fa3 100644 --- a/packages/unity-interface/ClientDebug.ts +++ b/packages/unity-interface/ClientDebug.ts @@ -2,6 +2,11 @@ import { defaultLogger } from 'shared/logger' import { ErrorContextTypes, ReportFatalErrorWithUnityPayloadAsync } from 'shared/loading/ReportFatalError' import { getUnityInstance, IUnityInterface } from './IUnityInterface' import { fetchSceneIds } from 'decentraland-loader/lifecycle/utils/fetchSceneIds' +import { fetchSceneJson } from 'decentraland-loader/lifecycle/utils/fetchSceneJson' +import { SceneJsonData } from 'shared/types' +import { SpawnPoint } from '@dcl/schemas' +import { gridToWorld, parseParcelPosition } from 'atomicHelpers/parcelScenePositions' +import { Vector3 } from '@dcl/ecs-math' export class ClientDebug { private unityInterface: IUnityInterface @@ -87,15 +92,8 @@ export class ClientDebug { } public async ToggleSceneBoundingBoxes(scene: string, enabled: boolean) { - const isInputCoords = scene.match(/^-?[0-9]*([,]-?[0-9]*){1}$/) - let sceneId: string | undefined - - if (isInputCoords) { - const ids = await fetchSceneIds([scene]) - sceneId = ids[0] ?? undefined - } else { - sceneId = scene - } + const isInputCoords = isValueACoordinate(scene) + const sceneId: string | undefined = isInputCoords ? await getSceneIdFromCoordinates(scene) : scene if (sceneId) { this.unityInterface.SendMessageToUnity('Main', 'ToggleSceneBoundingBoxes', JSON.stringify({ sceneId, enabled })) @@ -103,6 +101,79 @@ export class ClientDebug { throw new Error(`scene not found ${scene}`) } } + + public async ToggleSceneSpawnPoints(scene: string, enabled?: boolean, sceneJsonData?: SceneJsonData) { + const isInputCoords = isValueACoordinate(scene) + const sceneId: string | undefined = isInputCoords ? await getSceneIdFromCoordinates(scene) : scene + + if (!sceneId) { + throw new Error(`scene not found ${scene}`) + } + + let sceneJson = sceneJsonData + + // if `sceneJsonData` is not in the arguments we fetch the json data + if (!sceneJson) { + const fetchJson = await fetchSceneJson([sceneId]) + const fetchedJson = fetchJson[0] ?? undefined + + if (!fetchedJson) { + throw new Error(`scene json not found ${scene}`) + } + sceneJson = fetchedJson.sceneJsonData + } + + // get base parcel world position to always handle positions in world context + const base = parseParcelPosition(sceneJson.scene.base) + const basePosition = new Vector3() + gridToWorld(base.x, base.y, basePosition) + + const spawnPoints: SpawnPoint[] = [] + + // if no spawnpoint set in scene json, we create the default one (0,0,0) + if (!sceneJson.spawnPoints) { + spawnPoints.push({ + name: 'undefined', + position: { x: [basePosition.x], y: [basePosition.y], z: [basePosition.z] }, + default: true + }) + } else { + const convertPositionComponent = (value: number | number[], sceneWorldPosition: number): number[] => { + if (Array.isArray(value)) { + return value.map((v) => sceneWorldPosition + v) + } + return [sceneWorldPosition + value] + } + + // convert vector3 to world position and always use type `number[]` for spawnpoint position + for (const spawnPoint of sceneJson.spawnPoints) { + spawnPoints.push({ + ...spawnPoint, + position: { + x: convertPositionComponent(spawnPoint.position.x, basePosition.x), + y: convertPositionComponent(spawnPoint.position.y, basePosition.y), + z: convertPositionComponent(spawnPoint.position.z, basePosition.z) + }, + cameraTarget: spawnPoint.cameraTarget ? basePosition.add(spawnPoint.cameraTarget) : undefined + }) + } + } + + this.unityInterface.SendMessageToUnity( + 'Main', + 'ToggleSceneSpawnPoints', + JSON.stringify({ sceneId, enabled, spawnPoints }) + ) + } +} + +function isValueACoordinate(value: string): boolean { + return value.match(/^-?[0-9]*([,]-?[0-9]*){1}$/) ? true : false +} + +async function getSceneIdFromCoordinates(coordinates: string): Promise { + const ids = await fetchSceneIds([coordinates]) + return ids[0] ?? undefined } export const clientDebug: ClientDebug = new ClientDebug(getUnityInstance()) diff --git a/packages/unity-interface/dcl.ts b/packages/unity-interface/dcl.ts index b1874f48e..dca59021f 100644 --- a/packages/unity-interface/dcl.ts +++ b/packages/unity-interface/dcl.ts @@ -170,13 +170,15 @@ export async function startUnitySceneWorkers() { } export async function getPreviewSceneId(): Promise<{ sceneId: string | null; sceneBase: string }> { - const result = await fetch('/scene.json?nocache=' + Math.random()) + const jsonData = await getPreviewSceneJson() + const [sceneId] = await fetchSceneIds([jsonData.scene.base]) + return { sceneId, sceneBase: jsonData.scene.base } +} +async function getPreviewSceneJson() { + const result = await fetch('/scene.json?nocache=' + Math.random()) if (result.ok) { - const scene = (await result.json()) as SceneJsonData - - const [sceneId] = await fetchSceneIds([scene.scene.base]) - return { sceneId, sceneBase: scene.scene.base } + return (await result.json()) as SceneJsonData } else { throw new Error('Could not load scene.json') } @@ -186,13 +188,20 @@ export async function loadPreviewScene(message: sdk.Messages) { async function oldReload() { const { sceneId, sceneBase } = await getPreviewSceneId() if (sceneId) { - await reloadScene(sceneId) + await doReload(sceneId) } else { defaultLogger.log(`Unable to load sceneId of ${sceneBase}`) debugger } } + async function doReload(sceneId: string) { + await reloadScene(sceneId) + getPreviewSceneJson() + .then((sceneJson) => clientDebug.ToggleSceneSpawnPoints(sceneId, undefined, sceneJson)) + .catch((e) => defaultLogger.error(e)) + } + if (message.type === sdk.SCENE_UPDATE && sdk.SceneUpdate.validate(message)) { if (message.payload.sceneType === sdk.ProjectType.PORTABLE_EXPERIENCE) { try { @@ -219,7 +228,7 @@ export async function loadPreviewScene(message: sdk.Messages) { } } else { if (message.payload.sceneId) { - await reloadScene(message.payload.sceneId) + await doReload(message.payload.sceneId) } else { await oldReload() } From c7f9b97bbcd5faf82931a769596e1b2440c3ab0e Mon Sep 17 00:00:00 2001 From: Pato Date: Fri, 1 Apr 2022 14:07:51 -0300 Subject: [PATCH 2/2] add comment --- packages/unity-interface/dcl.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/unity-interface/dcl.ts b/packages/unity-interface/dcl.ts index dca59021f..cd3592808 100644 --- a/packages/unity-interface/dcl.ts +++ b/packages/unity-interface/dcl.ts @@ -197,6 +197,9 @@ export async function loadPreviewScene(message: sdk.Messages) { async function doReload(sceneId: string) { await reloadScene(sceneId) + + // We get scene json here to use hot-reload to update displayed spawnpoints + // since the ILand info is not currently changing on hot-reload getPreviewSceneJson() .then((sceneJson) => clientDebug.ToggleSceneSpawnPoints(sceneId, undefined, sceneJson)) .catch((e) => defaultLogger.error(e))