diff --git a/app/src/components/layout/controls/ControlsPlayer.tsx b/app/src/components/layout/controls/ControlsPlayer.tsx
index 4f897d2..724c3bb 100644
--- a/app/src/components/layout/controls/ControlsPlayer.tsx
+++ b/app/src/components/layout/controls/ControlsPlayer.tsx
@@ -1,23 +1,44 @@
-import React, { useState } from "react";
-import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
+import React, { useEffect, useState } from "react";
+import useCameraModeStore, {
+ usePlayButtonStore,
+} from "../../../store/usePlayButtonStore";
import useModuleStore from "../../../store/useModuleStore";
import { PlayIcon } from "../../icons/ShortcutIcons";
import InputToggle from "../../ui/inputs/InputToggle";
import { EyeCloseIcon, WalkIcon } from "../../icons/ExportCommonIcons";
import { ExitIcon } from "../../icons/SimulationIcons";
+import { useCamMode } from "../../../store/builder/store";
-const ControlsPlayer = () => {
+const ControlsPlayer: React.FC = () => {
const { setIsPlaying } = usePlayButtonStore();
const { activeModule } = useModuleStore();
- const [walkMode, setWalkMode] = useState(false);
+ const { walkMode, toggleWalkMode } = useCameraModeStore();
const [hidePlayer, setHidePlayer] = useState(false);
+ const { camMode } = useCamMode();
const changeCamMode = () => {
- setWalkMode(!walkMode);
- console.log("switch camera mode to first person");
+ toggleWalkMode();
+ echo.log("switch camera mode to first person");
+ // Simulate "/" keypress
+ const slashKeyEvent = new KeyboardEvent("keydown", {
+ key: "/",
+ code: "Slash",
+ keyCode: 191, // for compatibility
+ which: 191,
+ bubbles: true,
+ cancelable: true,
+ });
+ document.dispatchEvent(slashKeyEvent);
};
+ useEffect(() => {
+ if (camMode === "ThirdPerson") {
+ toggleWalkMode();
+ } else return;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [camMode]);
+
return (
-
+
{!hidePlayer && (
@@ -26,7 +47,7 @@ const ControlsPlayer = () => {
)}
- {!hidePlayer && (
+ {!hidePlayer && activeModule === "builder" && (
{
const { camMode, setCamMode } = useCamMode();
@@ -65,26 +66,14 @@ const CamMode: React.FC = () => {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "/" && !isTransitioning && !toggleView) {
- setIsTransitioning(true);
-
- state.controls.mouseButtons.left =
- CONSTANTS.controlsTransition.leftMouse;
- state.controls.mouseButtons.right =
- CONSTANTS.controlsTransition.rightMouse;
- state.controls.mouseButtons.wheel =
- CONSTANTS.controlsTransition.wheelMouse;
- state.controls.mouseButtons.middle =
- CONSTANTS.controlsTransition.middleMouse;
-
- if (camMode === "ThirdPerson") {
- setCamMode("FirstPerson");
- await switchToFirstPerson(state.controls, state.camera);
- } else if (camMode === "FirstPerson") {
- setCamMode("ThirdPerson");
- await switchToThirdPerson(state.controls, state.camera);
- }
-
- setIsTransitioning(false);
+ firstPersonCamera({
+ setIsTransitioning,
+ state,
+ camMode,
+ setCamMode,
+ switchToFirstPerson,
+ switchToThirdPerson,
+ });
}
};
@@ -92,6 +81,7 @@ const CamMode: React.FC = () => {
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [
camMode,
isTransitioning,
@@ -140,6 +130,3 @@ const CamMode: React.FC = () => {
};
export default CamMode;
-
-
-
diff --git a/app/src/modules/scene/camera/firstPersonCamera.ts b/app/src/modules/scene/camera/firstPersonCamera.ts
new file mode 100644
index 0000000..85aacb3
--- /dev/null
+++ b/app/src/modules/scene/camera/firstPersonCamera.ts
@@ -0,0 +1,39 @@
+import * as CONSTANTS from "../../../types/world/worldConstants";
+
+interface FirstPersonCameraProps {
+ setIsTransitioning?: (value: boolean) => void;
+ state: any;
+}
+
+interface FirstPersonCameraParams extends FirstPersonCameraProps {
+ camMode: string;
+ setCamMode: (mode: string) => void;
+ switchToFirstPerson: (controls: any, camera: any) => Promise;
+ switchToThirdPerson: (controls: any, camera: any) => Promise;
+}
+
+export async function firstPersonCamera({
+ setIsTransitioning,
+ state,
+ camMode,
+ setCamMode,
+ switchToFirstPerson,
+ switchToThirdPerson
+}: FirstPersonCameraParams): Promise {
+ setIsTransitioning && setIsTransitioning(true);
+
+ state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
+ state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
+ state.controls.mouseButtons.wheel = CONSTANTS.controlsTransition.wheelMouse;
+ state.controls.mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
+
+ if (camMode === "ThirdPerson") {
+ setCamMode("FirstPerson");
+ await switchToFirstPerson(state.controls, state.camera);
+ } else if (camMode === "FirstPerson") {
+ setCamMode("ThirdPerson");
+ await switchToThirdPerson(state.controls, state.camera);
+ }
+
+ setIsTransitioning && setIsTransitioning(false);
+}
diff --git a/app/src/store/usePlayButtonStore.ts b/app/src/store/usePlayButtonStore.ts
index bed2bd7..fe85d6a 100644
--- a/app/src/store/usePlayButtonStore.ts
+++ b/app/src/store/usePlayButtonStore.ts
@@ -33,3 +33,17 @@ export const useAnimationPlaySpeed = create((set) => ({
speed: 1,
setSpeed: (value) => set({ speed: value }),
}));
+
+interface CameraModeState {
+ walkMode: boolean;
+ setWalkMode: (enabled: boolean) => void;
+ toggleWalkMode: () => void;
+}
+
+const useCameraModeStore = create((set) => ({
+ walkMode: false,
+ setWalkMode: (enabled) => set({ walkMode: enabled }),
+ toggleWalkMode: () => set((state) => ({ walkMode: !state.walkMode })),
+}));
+
+export default useCameraModeStore;
diff --git a/app/src/styles/components/simulation/simulation.scss b/app/src/styles/components/simulation/simulation.scss
index f95518e..28c28f4 100644
--- a/app/src/styles/components/simulation/simulation.scss
+++ b/app/src/styles/components/simulation/simulation.scss
@@ -358,7 +358,8 @@
}
.controls-player-container {
- max-width: 50vw;
+ min-width: 26vw;
+ max-width: 80vw;
border-radius: 15px;
gap: 40px;
background: var(--background-color);
@@ -375,6 +376,12 @@
isolation: isolate;
font-weight: 700;
padding: 8px;
+ transition: all 0.2s;
+
+ &.hide {
+ min-width: none;
+ width: 92px;
+ }
.controls-left,
.controls-right {
@@ -418,7 +425,7 @@
outline: 1px solid var(--border-color);
color: var(--accent-color);
}
- &.hide{
+ &.hide {
width: 32px;
}
.icon {
diff --git a/app/src/utils/shortcutkeys/handleShortcutKeys.ts b/app/src/utils/shortcutkeys/handleShortcutKeys.ts
index 813d2cb..c4d8aa1 100644
--- a/app/src/utils/shortcutkeys/handleShortcutKeys.ts
+++ b/app/src/utils/shortcutkeys/handleShortcutKeys.ts
@@ -11,7 +11,7 @@ import {
useToggleView,
useToolMode,
} from "../../store/builder/store";
-import { usePlayButtonStore } from "../../store/usePlayButtonStore";
+import useCameraModeStore, { usePlayButtonStore } from "../../store/usePlayButtonStore";
import { detectModifierKeys } from "./detectModifierKeys";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
@@ -29,6 +29,7 @@ const KeyPressListener: React.FC = () => {
const { setActiveTool } = useActiveTool();
const { clearSelectedZone } = useSelectedZoneStore();
const { showShortcuts, setShowShortcuts } = useShortcutStore();
+ const { setWalkMode } = useCameraModeStore();
const isTextInput = (element: Element | null): boolean =>
element instanceof HTMLInputElement ||
@@ -168,6 +169,7 @@ const KeyPressListener: React.FC = () => {
}
if (keyCombination === "ESCAPE") {
+ setWalkMode(false);
setActiveTool("cursor");
setActiveSubTool("cursor");
setIsPlaying(false);