From eed6afb58f5a8110ce44d6d0794b6b10d9dcaa6c Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Mon, 27 Apr 2026 17:17:05 +0200 Subject: [PATCH] Feature: Add support for inverted mouse camera horizontal setting to player start --- src/document/migrate-scene-document.ts | 7 +++++++ src/document/scene-document-validation.ts | 11 +++++++++++ src/document/scene-document.ts | 3 ++- src/runtime-three/runtime-scene-build.ts | 4 ++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/document/migrate-scene-document.ts b/src/document/migrate-scene-document.ts index b98a4169..91c5e328 100644 --- a/src/document/migrate-scene-document.ts +++ b/src/document/migrate-scene-document.ts @@ -29,6 +29,7 @@ import { createCameraRigPlayerTargetRef, createCameraRigWorldPointTargetRef, DEFAULT_PLAYER_START_ALLOW_LOOK_INPUT_TARGET_SWITCH, + DEFAULT_PLAYER_START_INVERT_MOUSE_CAMERA_HORIZONTAL, DEFAULT_PLAYER_START_INTERACTION_ANGLE_DEGREES, DEFAULT_PLAYER_START_GAMEPAD_BINDINGS, DEFAULT_PLAYER_START_INTERACTION_REACH_METERS, @@ -3348,6 +3349,11 @@ function readPlayerStartEntity(value: unknown, label: string): EntityInstance { `${label}.targetButtonCyclesActiveTarget`, DEFAULT_PLAYER_START_TARGET_BUTTON_CYCLES_ACTIVE_TARGET ), + invertMouseCameraHorizontal: readOptionalBoolean( + value.invertMouseCameraHorizontal, + `${label}.invertMouseCameraHorizontal`, + DEFAULT_PLAYER_START_INVERT_MOUSE_CAMERA_HORIZONTAL + ), movementTemplate: readPlayerStartMovementTemplate( value.movementTemplate, `${label}.movementTemplate` @@ -5500,6 +5506,7 @@ export function migrateSceneDocument(source: unknown): SceneDocument { source.version !== PLAYER_START_INTERACTION_REACH_SCENE_DOCUMENT_VERSION && source.version !== PLAYER_START_INTERACTION_ANGLE_SCENE_DOCUMENT_VERSION && source.version !== PLAYER_START_TARGETING_SETTINGS_SCENE_DOCUMENT_VERSION && + source.version !== PLAYER_START_MOUSE_INVERT_SCENE_DOCUMENT_VERSION && source.version !== PLAYER_START_INTERACT_BINDINGS_SCENE_DOCUMENT_VERSION && source.version !== PLAYER_START_MOVEMENT_TEMPLATE_SCENE_DOCUMENT_VERSION && source.version !== PROJECT_NAME_SCENE_DOCUMENT_VERSION && diff --git a/src/document/scene-document-validation.ts b/src/document/scene-document-validation.ts index a11e7c60..c976e811 100644 --- a/src/document/scene-document-validation.ts +++ b/src/document/scene-document-validation.ts @@ -2699,6 +2699,17 @@ function validatePlayerStartEntity( ); } + if (typeof entity.invertMouseCameraHorizontal !== "boolean") { + diagnostics.push( + createDiagnostic( + "error", + "invalid-player-start-invert-mouse-camera-horizontal", + "Player Start invertMouseCameraHorizontal must remain a boolean.", + `${path}.invertMouseCameraHorizontal` + ) + ); + } + if (!isPlayerStartMovementTemplateKind(entity.movementTemplate?.kind)) { diagnostics.push( createDiagnostic( diff --git a/src/document/scene-document.ts b/src/document/scene-document.ts index c3b8d9b6..f594a363 100644 --- a/src/document/scene-document.ts +++ b/src/document/scene-document.ts @@ -29,7 +29,8 @@ import { } from "../sequencer/project-sequences"; import type { Terrain } from "./terrains"; -export const SCENE_DOCUMENT_VERSION = 83 as const; +export const SCENE_DOCUMENT_VERSION = 84 as const; +export const PLAYER_START_MOUSE_INVERT_SCENE_DOCUMENT_VERSION = 84 as const; export const PLAYER_START_TARGETING_SETTINGS_SCENE_DOCUMENT_VERSION = 83 as const; export const PLAYER_START_INTERACT_BINDINGS_SCENE_DOCUMENT_VERSION = diff --git a/src/runtime-three/runtime-scene-build.ts b/src/runtime-three/runtime-scene-build.ts index ac127f0e..9b606b60 100644 --- a/src/runtime-three/runtime-scene-build.ts +++ b/src/runtime-three/runtime-scene-build.ts @@ -282,6 +282,7 @@ export interface RuntimePlayerStart { interactionAngleDegrees: number; allowLookInputTargetSwitch: boolean; targetButtonCyclesActiveTarget: boolean; + invertMouseCameraHorizontal: boolean; movement: RuntimePlayerMovement; inputBindings: PlayerStartInputBindings; collider: FirstPersonPlayerShape; @@ -1599,6 +1600,7 @@ function buildRuntimeSceneCollections( interactionAngleDegrees: entity.interactionAngleDegrees, allowLookInputTargetSwitch: entity.allowLookInputTargetSwitch, targetButtonCyclesActiveTarget: entity.targetButtonCyclesActiveTarget, + invertMouseCameraHorizontal: entity.invertMouseCameraHorizontal, movement: buildRuntimePlayerMovement(entity.movementTemplate), inputBindings: clonePlayerStartInputBindings(entity.inputBindings), collider: buildRuntimePlayerShape(entity) @@ -2001,6 +2003,8 @@ export function buildRuntimeSceneFromDocument( playerStartEntity.allowLookInputTargetSwitch, targetButtonCyclesActiveTarget: playerStartEntity.targetButtonCyclesActiveTarget, + invertMouseCameraHorizontal: + playerStartEntity.invertMouseCameraHorizontal, movement: cloneRuntimePlayerMovement(playerMovement), inputBindings: clonePlayerStartInputBindings(playerInputBindings), collider: playerCollider