Added collisions with objects on scene

Player will now be stopped by fences
Also added the possibility to define the size of ground
Also edited speed of animations
Also optimized the loading of fences
This commit is contained in:
2023-11-17 10:42:14 +01:00
parent 13aece594d
commit 256654502e
5 changed files with 64 additions and 46 deletions

View File

@@ -38,7 +38,7 @@ Animations.addAnimationMixerOnMesh(assets.player, ["Walk"]);
function animate() { function animate() {
requestAnimationFrame( animate ); requestAnimationFrame( animate );
PlayerMovement.updatePlayerPositionAnimation(assets.player, camera);//Updating player position and rotation PlayerMovement.updatePlayerPositionAnimation(assets.player, camera, scene);//Updating player position and rotation
Animations.updateAnimations(Clock.getDelta());//Playing animations Animations.updateAnimations(Clock.getDelta());//Playing animations
renderer.render( scene, camera );//Calculating and redering new frame renderer.render( scene, camera );//Calculating and redering new frame

View File

@@ -1,8 +1,8 @@
//ground //ground
import * as THREE from 'three'; import * as THREE from 'three';
export function createGround() { export function createGround(height, width) {
const geometry = new THREE.PlaneGeometry(10, 10); const geometry = new THREE.PlaneGeometry(height, width);
const material = new THREE.MeshBasicMaterial({ color: 0xa3c973 }); const material = new THREE.MeshBasicMaterial({ color: 0xa3c973 });
const plane = new THREE.Mesh(geometry, material); const plane = new THREE.Mesh(geometry, material);

View File

@@ -26,65 +26,60 @@ export async function addAssetsOnScene(scene){
scene.add(new THREE.AmbientLight(0x404040, 50));//Light, required to see scene.add(new THREE.AmbientLight(0x404040, 50));//Light, required to see
const ground = createGround();
scene.add(ground);
/* -------------------- /* --------------------
ADDING FENCES ADDING GROUND AND FENCES
-------------------- */ -------------------- */
const groundHitBox = new THREE.Box3().setFromObject(ground); // Calculating ground size
const groundXSize = groundHitBox.max.x - groundHitBox.min.x;
const groundySize = groundHitBox.max.y - groundHitBox.min.y;
let fences = [];//List of created fences let fences = [];//List of created fences
const fenceModel = await loadModel('src/objects/models/fence.gltf'); const fenceModel = await loadModel('src/objects/models/fence.gltf');
//Getting width of one fence //Getting width of one fence
fenceModel.scene.scale.set(0.05, 0.05, 0.05); fenceModel.scene.scale.set(0.05, 0.05, 0.05);
fenceModel.scene.rotateOnWorldAxis(new THREE.Vector3(1, 0, 0), MathUtils.degToRad(90)); fenceModel.scene.rotateOnWorldAxis(new THREE.Vector3(1, 0, 0), MathUtils.degToRad(90));//Must be standing up
const fenceHitBox = new THREE.Box3().setFromObject(fenceModel.scene); const fenceHitBox = new THREE.Box3().setFromObject(fenceModel.scene);
const fenceWidth = fenceHitBox.max.y - fenceHitBox.min.y; const fenceWidth = fenceHitBox.max.y - fenceHitBox.min.y;
//Creating the ground
const ground = createGround(6*fenceWidth, 6*fenceWidth);
scene.add(ground);
const groundHitBox = new THREE.Box3().setFromObject(ground); // Calculating ground size
const groundXSize = groundHitBox.max.x - groundHitBox.min.x;
const groundySize = groundHitBox.max.y - groundHitBox.min.y;
for(let i = 0; i<groundXSize; i=i+fenceWidth){ for(let i = 0; i<groundXSize; i=i+fenceWidth){
let fence1 = await loadModel('src/objects/models/fence.gltf');//Loading fences ( saved in cache, so file is loaded one time only ) let fence1 = fenceModel.scene.clone()
let fence2 = await loadModel('src/objects/models/fence.gltf');//This loop will create the 4 walls of fences around the ground let fence2 = fenceModel.scene.clone()
let fence3 = await loadModel('src/objects/models/fence.gltf'); let fence3 = fenceModel.scene.clone()
let fence4 = await loadModel('src/objects/models/fence.gltf'); let fence4 = fenceModel.scene.clone()
fence1.scene.scale.set(0.05,0.05,0.05); fence1.scale.set(0.05,0.05,0.05);
fence2.scene.scale.set(0.05,0.05,0.05); fence2.scale.set(0.05,0.05,0.05);
fence3.scene.scale.set(0.05,0.05,0.05); fence3.scale.set(0.05,0.05,0.05);
fence4.scene.scale.set(0.05,0.05,0.05); fence4.scale.set(0.05,0.05,0.05);
fence1.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90));//Must be standing up fence1.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));//Correctly rotated for that face
fence2.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90)); fence2.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));
fence1.scene.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));//And correctly rotated for that face
fence2.scene.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));
fence3.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90)); fence1.position.y = groundHitBox.max.y - 0.25;//TOP SIDE
fence4.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90)); fence1.position.x = groundHitBox.min.x + fenceWidth + i;
fence1.scene.position.y = groundHitBox.max.y;//TOP SIDE fence2.position.y = groundHitBox.min.y + 0.25;//BOTTOM SIDE
fence1.scene.position.x = groundHitBox.min.x + i; fence2.position.x = groundHitBox.max.x - i;
fence2.scene.position.y = groundHitBox.min.y;//BOTTOM SIDE fence3.position.y = groundHitBox.min.y + i ;//RIGHT SIDE
fence2.scene.position.x = groundHitBox.max.x - i; fence3.position.x = groundHitBox.max.x - 0.25;
fence3.scene.position.y = groundHitBox.min.y + i ;//RIGHT SIDE fence4.position.y = groundHitBox.max.y - fenceWidth - i;//LEFT SIDE
fence3.scene.position.x = groundHitBox.max.x; fence4.position.x = groundHitBox.min.x + 0.25;
fence4.scene.position.y = groundHitBox.max.y - i;//LEFT SIDE alignGround(ground, fence1);
fence4.scene.position.x = groundHitBox.min.x; alignGround(ground, fence2);
alignGround(ground, fence3);
alignGround(ground, fence4);
alignGround(ground, fence1.scene); scene.add(fence1);
alignGround(ground, fence2.scene); scene.add(fence2);
alignGround(ground, fence3.scene); scene.add(fence3);
alignGround(ground, fence4.scene); scene.add(fence4);
scene.add(fence1.scene);
scene.add(fence2.scene);
scene.add(fence3.scene);
scene.add(fence4.scene);
fences.push(fence1); fences.push(fence1);
fences.push(fence2); fences.push(fence2);
@@ -101,6 +96,7 @@ export async function addAssetsOnScene(scene){
return { return {
ground: ground, ground: ground,
fenceScenes: fences,
player: player, player: player,
}; };
} }

View File

@@ -1,6 +1,6 @@
import * as THREE from 'three'; import * as THREE from 'three';
const ANIMATION_SPEED_MULTIPLIER = 1.4; const ANIMATION_SPEED_MULTIPLIER = 1.6;
let mixersToUpdateEachFrame = []; let mixersToUpdateEachFrame = [];
export function addAnimationMixerOnMesh(mesh, actions){ export function addAnimationMixerOnMesh(mesh, actions){

View File

@@ -45,14 +45,36 @@ export function handleKeyDown(event) {
} }
} }
export function updatePlayerPositionAnimation(player, camera) { export function updatePlayerPositionAnimation(player, camera, scene) {
/* Function called in the main loop /* Function called in the main loop
Used to calculate the position and orientation of the player Used to calculate the position and orientation of the player
Also used to start and stop walking animation */ Also used to start and stop walking animation
Takes player, camera and scene*/
//COLLIDERS
const raycaster = new THREE.Raycaster();//Creating a raycaster from the player
const rayDirection = new THREE.Vector3(playerDirection.x, playerDirection.y, 0).normalize();
raycaster.set(player.scene.position, rayDirection);
const intersects = raycaster.intersectObjects(scene.children, true);//Gettings objects on the path of this raycaster
const allowedDistance = 0.4;
const collisionThreshold = 0.2;
for(let i=0; i<intersects.length; i++){
if(intersects[i].distance>collisionThreshold && intersects[i].distance<allowedDistance){
//Valid colliding object, not too close ( player leg / arm ), but not too far
console.log(intersects[i]);
playerDirection.set(0, 0, 0);
break;
}
}
//MOVING
const delta = playerDirection.clone().multiplyScalar(PLAYER_SPEED); const delta = playerDirection.clone().multiplyScalar(PLAYER_SPEED);
player.scene.position.add(delta); player.scene.position.add(delta);
camera.position.add(delta);//The camera must follow the player camera.position.add(delta);//The camera must follow the player
//ANIMATING
if (playerDirection.length() > 0) {//If a movement key is pressed ( or something in playerDirection ) if (playerDirection.length() > 0) {//If a movement key is pressed ( or something in playerDirection )
if(!player.animationActions.Walk.isRunning()) player.animationActions.Walk.play();//Playing walk animation if(!player.animationActions.Walk.isRunning()) player.animationActions.Walk.play();//Playing walk animation