Feat/polish-mission1 #12
@@ -8,6 +8,10 @@ import { useLoggedGLTF } from "@/hooks/three/useLoggedGLTF";
|
||||
import { useClonedObject } from "@/hooks/three/useClonedObject";
|
||||
import { useDebugFolder } from "@/hooks/debug/useDebugFolder";
|
||||
import { useEbikeSounds } from "@/hooks/ebike/useEbikeSounds";
|
||||
import {
|
||||
getObjectBottomOffset,
|
||||
useTerrainHeightSampler,
|
||||
} from "@/hooks/three/useTerrainHeight";
|
||||
import { animateCameraTransformTransition } from "@/world/GameCinematics";
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import {
|
||||
@@ -32,6 +36,18 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
||||
position: position,
|
||||
});
|
||||
const model = useClonedObject(scene);
|
||||
const terrainHeight = useTerrainHeightSampler();
|
||||
const parkedPosition = useMemo<Vector3Tuple>(() => {
|
||||
const [x, y, z] = position;
|
||||
const height = terrainHeight.getHeight(x, z) ?? y;
|
||||
const bottomOffset = getObjectBottomOffset(model, [
|
||||
EBIKE_WORLD_SCALE,
|
||||
EBIKE_WORLD_SCALE,
|
||||
EBIKE_WORLD_SCALE,
|
||||
]);
|
||||
|
||||
return [x, height + bottomOffset, z];
|
||||
}, [model, position, terrainHeight]);
|
||||
const movementMode = useGameStore((state) => state.player.movementMode);
|
||||
const mainState = useGameStore((state) => state.mainState);
|
||||
const ebikeStep = useGameStore((state) => state.ebike.currentStep);
|
||||
@@ -64,19 +80,19 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
||||
y: number;
|
||||
z: number;
|
||||
}>({
|
||||
x: position[0],
|
||||
y: position[1],
|
||||
z: position[2],
|
||||
x: parkedPosition[0],
|
||||
y: parkedPosition[1],
|
||||
z: parkedPosition[2],
|
||||
});
|
||||
const lastGpsUpdatePos = useRef<THREE.Vector3>(
|
||||
new THREE.Vector3(...position),
|
||||
new THREE.Vector3(...parkedPosition),
|
||||
);
|
||||
|
||||
// Use ref for internal state, and state for debug visualization (to avoid ref access during render)
|
||||
const restingPositionRef = useRef<Vector3Tuple>([
|
||||
position[0],
|
||||
position[1],
|
||||
position[2],
|
||||
parkedPosition[0],
|
||||
parkedPosition[1],
|
||||
parkedPosition[2],
|
||||
]);
|
||||
const restingRotationRef = useRef<number>(EBIKE_WORLD_ROTATION_Y);
|
||||
const forkRef = useRef<THREE.Object3D | null>(null);
|
||||
@@ -84,23 +100,27 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
||||
// State for debug visualization (synced from refs during useFrame)
|
||||
const [showCameraPoints, setShowCameraPoints] = useState(true);
|
||||
const [debugRestingPosition, setDebugRestingPosition] =
|
||||
useState<Vector3Tuple>([position[0], position[1], position[2]]);
|
||||
useState<Vector3Tuple>([
|
||||
parkedPosition[0],
|
||||
parkedPosition[1],
|
||||
parkedPosition[2],
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (movementMode === "ebike") return;
|
||||
|
||||
restingPositionRef.current = position;
|
||||
restingPositionRef.current = parkedPosition;
|
||||
restingRotationRef.current = EBIKE_WORLD_ROTATION_Y;
|
||||
lastGpsUpdatePos.current.set(...position);
|
||||
lastGpsUpdatePos.current.set(...parkedPosition);
|
||||
|
||||
if (groupRef.current) {
|
||||
groupRef.current.position.set(...position);
|
||||
groupRef.current.position.set(...parkedPosition);
|
||||
groupRef.current.rotation.set(0, EBIKE_WORLD_ROTATION_Y, 0);
|
||||
}
|
||||
|
||||
window.ebikeParkedPosition = position;
|
||||
window.ebikeParkedPosition = parkedPosition;
|
||||
window.ebikeParkedRotation = EBIKE_WORLD_ROTATION_Y;
|
||||
}, [movementMode, position]);
|
||||
}, [movementMode, parkedPosition]);
|
||||
|
||||
useEffect(() => {
|
||||
if (model) {
|
||||
@@ -293,7 +313,7 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
||||
{!repairGameOwnsEbikeModel ? (
|
||||
<group
|
||||
ref={groupRef}
|
||||
position={position}
|
||||
position={parkedPosition}
|
||||
rotation={[0, EBIKE_WORLD_ROTATION_Y, 0]}
|
||||
scale={EBIKE_WORLD_SCALE}
|
||||
>
|
||||
@@ -301,7 +321,7 @@ export function Ebike({ position }: EbikeProps): React.JSX.Element {
|
||||
<InteractableObject
|
||||
kind="trigger"
|
||||
label={interactionLabel}
|
||||
position={position}
|
||||
position={parkedPosition}
|
||||
radius={5}
|
||||
onPress={handleInteract}
|
||||
>
|
||||
|
||||
@@ -15,7 +15,7 @@ export const EBIKE_DROP_PLAYER_TRANSFORM: CameraTransform = {
|
||||
rotation: [0, 0, 0],
|
||||
};
|
||||
|
||||
export const EBIKE_WORLD_POSITION: Vector3Tuple = [57.9, 6.3, 58.35];
|
||||
export const EBIKE_WORLD_POSITION: Vector3Tuple = [65, 0.8, 72];
|
||||
export const EBIKE_WORLD_ROTATION_Y = -2.5;
|
||||
export const EBIKE_WORLD_SCALE = 0.35;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ export const PLAYER_EYE_HEIGHT = 1.75;
|
||||
export const PLAYER_CAPSULE_RADIUS = 0.35;
|
||||
|
||||
export const PLAYER_WALK_SPEED = 5;
|
||||
export const PLAYER_EBIKE_SPEED = 20;
|
||||
export const PLAYER_EBIKE_SPEED = 30;
|
||||
export const PLAYER_AIR_CONTROL_FACTOR = 0.35;
|
||||
export const PLAYER_JUMP_SPEED = 9;
|
||||
export const PLAYER_GRAVITY = 30;
|
||||
@@ -16,8 +16,8 @@ export const PLAYER_FALL_RESPAWN_Y = -20;
|
||||
export const PLAYER_FALL_RESPAWN_DELAY = 3;
|
||||
|
||||
export const PLAYER_SPAWN_POSITION_GAME: Vector3Tuple = [
|
||||
LA_FABRIK_PLAYER_SPAWN[0] + 5,
|
||||
LA_FABRIK_PLAYER_SPAWN[0] + 1,
|
||||
LA_FABRIK_PLAYER_SPAWN[1],
|
||||
LA_FABRIK_PLAYER_SPAWN[2] + 5,
|
||||
LA_FABRIK_PLAYER_SPAWN[2] - 1,
|
||||
];
|
||||
export const PLAYER_SPAWN_POSITION_PHYSICS: Vector3Tuple = [0, 3, 0];
|
||||
|
||||
@@ -6,8 +6,8 @@ export const LA_FABRIK_HALF_EXTENTS = {
|
||||
x: 8.5,
|
||||
z: 7.5,
|
||||
} as const;
|
||||
export const LA_FABRIK_PLAYER_SPAWN: Vector3Tuple = [59.5, 7.8, 64.64];
|
||||
export const LA_FABRIK_INITIAL_LOOK_AT: Vector3Tuple = [58, 7.8, 62.5];
|
||||
export const LA_FABRIK_PLAYER_SPAWN: Vector3Tuple = [59.5, 6.3, 64.64];
|
||||
export const LA_FABRIK_INITIAL_LOOK_AT: Vector3Tuple = [58, 7.3, 62.5];
|
||||
export const LA_FABRIK_INTERIOR_LIGHT_POSITION: Vector3Tuple = [59.5, 9, 64.64];
|
||||
|
||||
export function isInsideLaFabrikFootprint(
|
||||
|
||||
Reference in New Issue
Block a user