add: focus repair case view
This commit is contained in:
@@ -92,6 +92,7 @@ export function RepairGame({
|
||||
<RepairMissionCase
|
||||
config={config}
|
||||
open={step === "repairing"}
|
||||
zoomed={step === "repairing"}
|
||||
showFragmentationPrompt={readyForFragmentation}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { RepairCaseModel } from "@/components/three/gameplay/RepairCaseModel";
|
||||
import { RepairPromptVideo } from "@/components/three/gameplay/RepairPromptVideo";
|
||||
import { REPAIR_CASE_MODEL_PATH } from "@/data/gameplay/repairCaseConfig";
|
||||
import {
|
||||
REPAIR_CASE_FOCUS_POSITION,
|
||||
REPAIR_CASE_FOCUS_SCALE,
|
||||
REPAIR_CASE_MODEL_PATH,
|
||||
} from "@/data/gameplay/repairCaseConfig";
|
||||
import type { RepairMissionConfig } from "@/data/gameplay/repairMissions";
|
||||
|
||||
interface RepairMissionCaseProps {
|
||||
@@ -8,6 +12,7 @@ interface RepairMissionCaseProps {
|
||||
exiting?: boolean;
|
||||
onExitComplete?: (() => void) | undefined;
|
||||
open?: boolean;
|
||||
zoomed?: boolean;
|
||||
showFragmentationPrompt?: boolean;
|
||||
}
|
||||
|
||||
@@ -16,8 +21,14 @@ export function RepairMissionCase({
|
||||
exiting = false,
|
||||
onExitComplete,
|
||||
open = false,
|
||||
zoomed = false,
|
||||
showFragmentationPrompt = false,
|
||||
}: RepairMissionCaseProps): React.JSX.Element {
|
||||
const casePosition = zoomed
|
||||
? REPAIR_CASE_FOCUS_POSITION
|
||||
: config.case.position;
|
||||
const caseScale = zoomed ? REPAIR_CASE_FOCUS_SCALE : config.case.scale;
|
||||
|
||||
return (
|
||||
<group>
|
||||
<RepairCaseModel
|
||||
@@ -25,14 +36,14 @@ export function RepairMissionCase({
|
||||
exiting={exiting}
|
||||
onExitComplete={onExitComplete}
|
||||
open={open}
|
||||
position={config.case.position}
|
||||
position={casePosition}
|
||||
rotation={config.case.rotation}
|
||||
scale={config.case.scale}
|
||||
scale={caseScale}
|
||||
/>
|
||||
{showFragmentationPrompt && !exiting ? (
|
||||
<RepairPromptVideo
|
||||
src={config.interactUiPath}
|
||||
position={[config.case.position[0], 2.4, config.case.position[2]]}
|
||||
position={[casePosition[0], 2.4, casePosition[2]]}
|
||||
size={80}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { RepairObjectModel } from "@/components/three/gameplay/RepairObjectModel
|
||||
import { RepairPromptVideo } from "@/components/three/gameplay/RepairPromptVideo";
|
||||
import { GrabbableObject } from "@/components/three/interaction/GrabbableObject";
|
||||
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
|
||||
import { REPAIR_CASE_FOCUS_POSITION } from "@/data/gameplay/repairCaseConfig";
|
||||
import type {
|
||||
RepairMissionConfig,
|
||||
RepairMissionPartConfig,
|
||||
@@ -13,9 +14,9 @@ import type { Vector3Tuple } from "@/types/three/three";
|
||||
const INSTALL_TARGET_POSITION: Vector3Tuple = [0, 0.8, 0];
|
||||
const INSTALL_TARGET_VECTOR = new THREE.Vector3(...INSTALL_TARGET_POSITION);
|
||||
const REPLACEMENT_START_OFFSETS: Vector3Tuple[] = [
|
||||
[-0.9, 1.35, 1.8],
|
||||
[0, 1.35, 2.15],
|
||||
[0.9, 1.35, 1.8],
|
||||
[-1.15, 1, 0.25],
|
||||
[0, 1.05, 0.45],
|
||||
[1.15, 1, 0.25],
|
||||
];
|
||||
const REPAIR_INSTALL_RADIUS = 1.1;
|
||||
|
||||
@@ -109,9 +110,9 @@ export function RepairRepairingStep({
|
||||
<GrabbableObject
|
||||
key={part.id}
|
||||
position={[
|
||||
config.case.position[0] + offset[0],
|
||||
config.case.position[1] + offset[1],
|
||||
config.case.position[2] + offset[2],
|
||||
REPAIR_CASE_FOCUS_POSITION[0] + offset[0],
|
||||
REPAIR_CASE_FOCUS_POSITION[1] + offset[1],
|
||||
REPAIR_CASE_FOCUS_POSITION[2] + offset[2],
|
||||
]}
|
||||
colliders="ball"
|
||||
handControlled
|
||||
@@ -123,7 +124,7 @@ export function RepairRepairingStep({
|
||||
<RepairObjectModel
|
||||
label={part.label}
|
||||
modelPath={part.modelPath ?? config.modelPath}
|
||||
scale={0.28}
|
||||
scale={0.36}
|
||||
/>
|
||||
</GrabbableObject>
|
||||
);
|
||||
|
||||
@@ -442,7 +442,7 @@ Ce document liste les fonctionnalités présentes dans le code actuel.
|
||||
|
||||
- \`RepairGame\` de production réutilisable monté pour les états de mission \`bike\`, \`pylone\` et \`ferme\`
|
||||
- Configuration de mission partagée via \`src/data/gameplay/repairMissions.ts\`
|
||||
- Flow repair-game avec \`waiting -> inspected -> fragmented -> scanning -> repairing -> done -> next mission\`, prompts \`.webm\`, apparition/ouverture/sortie de la mallette, touche \`E\`, hold deux poings, transition de modèle explosé, scan visuel par pièce, marqueur rouge persistant et vidéo UI centrée sur les pièces cassées, plusieurs choix de pièces grabbables, validation de la bonne pièce et complétion de mission
|
||||
- Flow repair-game avec \`waiting -> inspected -> fragmented -> scanning -> repairing -> done -> next mission\`, prompts \`.webm\`, apparition/ouverture/sortie de la mallette, vue focalisée de la mallette, touche \`E\`, hold deux poings, transition de modèle explosé, scan visuel par pièce, marqueur rouge persistant et vidéo UI centrée sur les pièces cassées, plusieurs choix de pièces grabbables, validation de la bonne pièce et complétion de mission
|
||||
|
||||
## Audio
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
|
||||
export const REPAIR_CASE_MODEL_PATH = "/models/packderelance/model.gltf";
|
||||
export const REPAIR_CASE_OPEN_SOUND_PATH = "/sounds/effect/open-malette.mp3";
|
||||
export const REPAIR_CASE_CLOSE_SOUND_PATH = "/sounds/effect/close-malette.mp3";
|
||||
@@ -17,3 +19,8 @@ export const REPAIR_CASE_FLOAT_UP_SPEED = 2.4;
|
||||
export const REPAIR_CASE_FLOAT_DOWN_SPEED = 1.8;
|
||||
export const REPAIR_CASE_ROTATION_RESET_SPEED = 3;
|
||||
export const REPAIR_CASE_ROTATION_AMPLITUDE_DEGREES = 5;
|
||||
|
||||
export const REPAIR_CASE_FOCUS_POSITION = [
|
||||
0, 1.05, 2.05,
|
||||
] satisfies Vector3Tuple;
|
||||
export const REPAIR_CASE_FOCUS_SCALE = 2.25;
|
||||
|
||||
Reference in New Issue
Block a user