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() {
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
renderer.render( scene, camera );//Calculating and redering new frame

View File

@@ -1,8 +1,8 @@
//ground
import * as THREE from 'three';
export function createGround() {
const geometry = new THREE.PlaneGeometry(10, 10);
export function createGround(height, width) {
const geometry = new THREE.PlaneGeometry(height, width);
const material = new THREE.MeshBasicMaterial({ color: 0xa3c973 });
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
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
const fenceModel = await loadModel('src/objects/models/fence.gltf');
//Getting width of one fence
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 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){
let fence1 = await loadModel('src/objects/models/fence.gltf');//Loading fences ( saved in cache, so file is loaded one time only )
let fence2 = await loadModel('src/objects/models/fence.gltf');//This loop will create the 4 walls of fences around the ground
let fence3 = await loadModel('src/objects/models/fence.gltf');
let fence4 = await loadModel('src/objects/models/fence.gltf');
let fence1 = fenceModel.scene.clone()
let fence2 = fenceModel.scene.clone()
let fence3 = fenceModel.scene.clone()
let fence4 = fenceModel.scene.clone()
fence1.scene.scale.set(0.05,0.05,0.05);
fence2.scene.scale.set(0.05,0.05,0.05);
fence3.scene.scale.set(0.05,0.05,0.05);
fence4.scene.scale.set(0.05,0.05,0.05);
fence1.scale.set(0.05,0.05,0.05);
fence2.scale.set(0.05,0.05,0.05);
fence3.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
fence2.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), 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));
fence1.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));//Correctly rotated for that face
fence2.rotateOnWorldAxis(new THREE.Vector3(0,0,1), MathUtils.degToRad(90));
fence3.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90));
fence4.scene.rotateOnWorldAxis(new THREE.Vector3(1,0,0), MathUtils.degToRad(90));
fence1.position.y = groundHitBox.max.y - 0.25;//TOP SIDE
fence1.position.x = groundHitBox.min.x + fenceWidth + i;
fence1.scene.position.y = groundHitBox.max.y;//TOP SIDE
fence1.scene.position.x = groundHitBox.min.x + i;
fence2.position.y = groundHitBox.min.y + 0.25;//BOTTOM SIDE
fence2.position.x = groundHitBox.max.x - i;
fence2.scene.position.y = groundHitBox.min.y;//BOTTOM SIDE
fence2.scene.position.x = groundHitBox.max.x - i;
fence3.position.y = groundHitBox.min.y + i ;//RIGHT SIDE
fence3.position.x = groundHitBox.max.x - 0.25;
fence3.scene.position.y = groundHitBox.min.y + i ;//RIGHT SIDE
fence3.scene.position.x = groundHitBox.max.x;
fence4.position.y = groundHitBox.max.y - fenceWidth - i;//LEFT SIDE
fence4.position.x = groundHitBox.min.x + 0.25;
fence4.scene.position.y = groundHitBox.max.y - i;//LEFT SIDE
fence4.scene.position.x = groundHitBox.min.x;
alignGround(ground, fence1);
alignGround(ground, fence2);
alignGround(ground, fence3);
alignGround(ground, fence4);
alignGround(ground, fence1.scene);
alignGround(ground, fence2.scene);
alignGround(ground, fence3.scene);
alignGround(ground, fence4.scene);
scene.add(fence1.scene);
scene.add(fence2.scene);
scene.add(fence3.scene);
scene.add(fence4.scene);
scene.add(fence1);
scene.add(fence2);
scene.add(fence3);
scene.add(fence4);
fences.push(fence1);
fences.push(fence2);
@@ -101,6 +96,7 @@ export async function addAssetsOnScene(scene){
return {
ground: ground,
fenceScenes: fences,
player: player,
};
}

View File

@@ -1,6 +1,6 @@
import * as THREE from 'three';
const ANIMATION_SPEED_MULTIPLIER = 1.4;
const ANIMATION_SPEED_MULTIPLIER = 1.6;
let mixersToUpdateEachFrame = [];
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
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);
player.scene.position.add(delta);
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(!player.animationActions.Walk.isRunning()) player.animationActions.Walk.play();//Playing walk animation