Add air direction only setting for player movement
This commit is contained in:
@@ -132,7 +132,8 @@ describe("validateSceneDocument", () => {
|
||||
variableHeight: "yes",
|
||||
maxHoldMs: 0,
|
||||
moveWhileJumping: "yes",
|
||||
moveWhileFalling: 1
|
||||
moveWhileFalling: 1,
|
||||
directionOnly: "left"
|
||||
},
|
||||
sprint: {
|
||||
speedMultiplier: 0
|
||||
@@ -217,6 +218,9 @@ describe("validateSceneDocument", () => {
|
||||
expect.objectContaining({
|
||||
code: "invalid-player-start-move-while-falling"
|
||||
}),
|
||||
expect.objectContaining({
|
||||
code: "invalid-player-start-air-direction-only"
|
||||
}),
|
||||
expect.objectContaining({
|
||||
code: "invalid-player-start-sprint-speed-multiplier"
|
||||
}),
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
IMPORTED_MODEL_COLLIDERS_SCENE_DOCUMENT_VERSION,
|
||||
LOCAL_LIGHTS_AND_SKYBOX_SCENE_DOCUMENT_VERSION,
|
||||
MODEL_ASSET_PIPELINE_SCENE_DOCUMENT_VERSION,
|
||||
PLAYER_START_AIR_CONTROL_SCENE_DOCUMENT_VERSION,
|
||||
PLAYER_START_COLLIDER_SETTINGS_SCENE_DOCUMENT_VERSION,
|
||||
PLAYER_START_INPUT_BINDINGS_SCENE_DOCUMENT_VERSION,
|
||||
PLAYER_START_MOVEMENT_TEMPLATE_SCENE_DOCUMENT_VERSION,
|
||||
@@ -467,7 +468,8 @@ describe("scene document JSON", () => {
|
||||
variableHeight: true,
|
||||
maxHoldMs: 220,
|
||||
moveWhileJumping: false,
|
||||
moveWhileFalling: false
|
||||
moveWhileFalling: false,
|
||||
directionOnly: true
|
||||
},
|
||||
sprint: {
|
||||
speedMultiplier: 1.8
|
||||
@@ -951,6 +953,7 @@ describe("scene document JSON", () => {
|
||||
const {
|
||||
moveWhileJumping: _moveWhileJumping,
|
||||
moveWhileFalling: _moveWhileFalling,
|
||||
directionOnly: _directionOnly,
|
||||
...legacyJump
|
||||
} = playerStart.movementTemplate.jump;
|
||||
const legacyDocument = {
|
||||
@@ -975,6 +978,39 @@ describe("scene document JSON", () => {
|
||||
expect(migratedDocument.entities[playerStart.id]).toEqual(playerStart);
|
||||
});
|
||||
|
||||
it("migrates version 34 Player Start jump settings to include default air direction mode", () => {
|
||||
const playerStart = createPlayerStartEntity({
|
||||
id: "entity-player-start-legacy-air-direction",
|
||||
movementTemplate: {
|
||||
kind: "responsive"
|
||||
}
|
||||
});
|
||||
const {
|
||||
directionOnly: _directionOnly,
|
||||
...legacyJump
|
||||
} = playerStart.movementTemplate.jump;
|
||||
const legacyDocument = {
|
||||
...createEmptySceneDocument({
|
||||
name: "Legacy Player Air Direction Scene"
|
||||
}),
|
||||
version: PLAYER_START_AIR_CONTROL_SCENE_DOCUMENT_VERSION,
|
||||
entities: {
|
||||
[playerStart.id]: {
|
||||
...playerStart,
|
||||
movementTemplate: {
|
||||
...playerStart.movementTemplate,
|
||||
jump: legacyJump
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const migratedDocument = migrateSceneDocument(legacyDocument);
|
||||
|
||||
expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION);
|
||||
expect(migratedDocument.entities[playerStart.id]).toEqual(playerStart);
|
||||
});
|
||||
|
||||
it("round-trips authored third-person Player Start navigation", () => {
|
||||
const playerStart = createPlayerStartEntity({
|
||||
id: "entity-player-start-third-person",
|
||||
|
||||
@@ -574,6 +574,70 @@ describe("player-locomotion", () => {
|
||||
expect(step?.locomotionState.planarSpeed).toBeCloseTo(0);
|
||||
});
|
||||
|
||||
it("reorients airborne movement using existing speed without adding more", () => {
|
||||
const step = stepPlayerLocomotion({
|
||||
dt: 0.1,
|
||||
feetPosition: {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 0
|
||||
},
|
||||
movementYawRadians: 0,
|
||||
airDirectionYawRadians: Math.PI / 2,
|
||||
standingShape: FIRST_PERSON_PLAYER_SHAPE,
|
||||
verticalVelocity: -2,
|
||||
previousLocomotionState: createIdleRuntimeLocomotionState("airborne"),
|
||||
previousPlanarDisplacement: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0.45
|
||||
},
|
||||
jumpBufferRemainingMs: 0,
|
||||
coyoteTimeRemainingMs: 0,
|
||||
jumpHoldRemainingMs: 0,
|
||||
crouched: false,
|
||||
wasJumpPressed: false,
|
||||
input: FORWARD_INPUT,
|
||||
movement: {
|
||||
...DEFAULT_MOVEMENT,
|
||||
jump: {
|
||||
...DEFAULT_MOVEMENT.jump,
|
||||
directionOnly: true
|
||||
}
|
||||
},
|
||||
resolveMotion: (feetPosition, motion): ResolvedPlayerMotion => ({
|
||||
feetPosition: {
|
||||
x: feetPosition.x + motion.x,
|
||||
y: feetPosition.y + motion.y,
|
||||
z: feetPosition.z + motion.z
|
||||
},
|
||||
grounded: false,
|
||||
collisionCount: 0,
|
||||
groundCollisionNormal: null,
|
||||
collidedAxes: {
|
||||
x: false,
|
||||
y: false,
|
||||
z: false
|
||||
}
|
||||
}),
|
||||
resolveVolumeState: () => createVolumeState(),
|
||||
probeGround: () => ({
|
||||
grounded: false,
|
||||
distance: null,
|
||||
normal: null,
|
||||
slopeDegrees: null
|
||||
}),
|
||||
canOccupyShape: () => true
|
||||
});
|
||||
|
||||
expect(step).not.toBeNull();
|
||||
expect(step?.locomotionState.locomotionMode).toBe("airborne");
|
||||
expect(step?.planarDisplacement.x).toBeCloseTo(0.45);
|
||||
expect(step?.planarDisplacement.z).toBeCloseTo(0);
|
||||
expect(step?.locomotionState.requestedPlanarSpeed).toBeCloseTo(4.5);
|
||||
expect(step?.locomotionState.planarSpeed).toBeCloseTo(4.5);
|
||||
});
|
||||
|
||||
it("sinks toward the water surface while keeping the head above water", () => {
|
||||
const step = stepPlayerLocomotion({
|
||||
dt: 0.1,
|
||||
|
||||
@@ -179,6 +179,9 @@ describe("Player Start inspector", () => {
|
||||
const variableJumpCheckbox = screen.getByTestId(
|
||||
"player-start-movement-variable-jump-enabled"
|
||||
);
|
||||
const airDirectionOnlyCheckbox = screen.getByTestId(
|
||||
"player-start-movement-air-direction-only-enabled"
|
||||
);
|
||||
const jumpBufferInput = screen.getByTestId(
|
||||
"player-start-movement-jump-buffer"
|
||||
);
|
||||
@@ -217,6 +220,10 @@ describe("Player Start inspector", () => {
|
||||
fireEvent.click(variableJumpCheckbox);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(airDirectionOnlyCheckbox);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
fireEvent.change(jumpBufferInput, {
|
||||
target: {
|
||||
@@ -233,7 +240,8 @@ describe("Player Start inspector", () => {
|
||||
moveSpeed: 5.7,
|
||||
jump: {
|
||||
bufferMs: 75,
|
||||
variableHeight: false
|
||||
variableHeight: false,
|
||||
directionOnly: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user