How to make player can place block in this context?

I have a folder with this files:

three.min.js (604.4 KB)
style.css (172 Bytes)

script.js (17.8 KB)
PointerLockControls.js (3.1 KB)
perlin.js (10.2 KB)




index.html (752 Bytes)

The problem is that when I press ‘keyT’ which is supossed to place block, it doenst interact me corrrectly, except with this command, which interacts puttting a block when i stay:

// Función para colocar un bloque en la posición siguiente en la dirección de la cámara
function placeBlock1() {
geometry = new THREE.BoxGeometry( 1, 1, 1 );
material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
cube = new THREE.Mesh( geometry, material );
cube.position.set(Math.floor(camera.position.x),Math.floor(camera.position.y),Math.floor(camera.position.z));
scene.add( cube );
}

I want only the player puts the blocks, like in minecraft… its possible? thanks anyway.

EDIT:

I tried this:

function placeBlock1() {
// Definir la geometría y el material del bloque
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

// Crear el cubo
const cube = new THREE.Mesh(geometry, material);

// Ajustar la posición del cubo
// Queremos que el bloque se coloque frente al jugador, no en la misma posición
const offsetDistance = 2; // Distancia frente al jugador
const direction = new THREE.Vector3(0, 0, -1).applyQuaternion(camera.quaternion);
cube.position.copy(camera.position).add(direction.multiplyScalar(offsetDistance));

cube.position.x=Math.floor(cube.position.x)
cube.position.y=Math.floor(cube.position.y)
cube.position.z=Math.floor(cube.position.z)

// Añadir el cubo a la escena
scene.add(cube);

// Imprimir la posición para depuración
console.log(`Block placed at: (${cube.position.x}, ${cube.position.y}, ${cube.position.z})`);

}

And it get me some improvement of placing the position of the player’s block…

Ofc, there’s quite a few billion of Minecraft clones made in three :relieved:

Can you replicate the issue in a smaller codepen / code sandbox? Debugging the code in its current form is not too viable and would take a long long time. Plus, when writing a smaller isolated codepen for us to debug, it’s not unlikely that you may find the solution to the issue yourself.

This is the function that i want to change:

// Función para colocar un bloque en la posición siguiente en la dirección de la cámara
function placeBlock1() {
// Definir la geometría y el material del bloque
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

// Crear el cubo
const cube = new THREE.Mesh(geometry, material);

// Ajustar la posición del cubo
// Queremos que el bloque se coloque frente al jugador, no en la misma posición
const offsetDistance = 5; // Distancia frente al jugador
const direction = new THREE.Vector3(0, 0, -1).applyQuaternion(camera.quaternion);
cube.position.copy(camera.position).add(direction.multiplyScalar(offsetDistance));

cube.position.x=Math.floor(cube.position.x)
cube.position.y=Math.floor(cube.position.y)
cube.position.z=Math.floor(cube.position.z)

// Añadir el cubo a la escena
scene.add(cube);

// Imprimir la posición para depuración
console.log(`Block placed at: (${cube.position.x}, ${cube.position.y}, ${cube.position.z})`);

}

EDIT 2:
I improved the block placement. Now can place with textures & bad made collision:

[let scene, camera, renderer, controls;
let moveForward = false;
let moveBackward = false;
let moveLeft = false;
let moveRight = false;
let moveUp = false;
let moveDown = false;

let instancedMesh, dirtInstancedMesh; // Declarar globalmente
let destroyedBlocks = {}; // Registrar bloques destruidos

function init() {
// Escena
scene = new THREE.Scene();

// Cámara
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(5, 5, 5);

// Renderizador con antialiasing y sombras habilitadas
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Tipo de sombra suave
renderer.toneMapping = THREE.CineonToneMapping ;
document.body.appendChild(renderer.domElement);

// Definir un color de fondo de la escena
const backgroundColor = new THREE.Color("#08f");
scene.background = backgroundColor;

// Configurar luz direccional simulando la luz del día
const light = new THREE.DirectionalLight("#ff8", 5); // Color amarillo, intensidad 5
light.position.set(20, 40, 20); // Posición de la luz
light.castShadow = true; // Permitir que la luz emita sombras

// Ajustes de sombra
light.shadow.mapSize.width = 4096; // Ancho del mapa de sombra
light.shadow.mapSize.height = 4096; // Alto del mapa de sombra
light.shadow.camera.near = 0.5; // Distancia cercana de la cámara de sombra
light.shadow.camera.far = 1000; // Distancia lejana de la cámara de sombra
light.shadow.camera.left = -200; // Margen izquierdo de la cámara de sombra
light.shadow.camera.right = 200; // Margen derecho de la cámara de sombra
light.shadow.camera.top = 200; // Margen superior de la cámara de sombra
light.shadow.camera.bottom = -200; // Margen inferior de la cámara de sombra

scene.add(light);

// Crear un InstancedMesh para los cubos
const worldSize = 50; // Tamaño del mundo
const cubeSize = 1; // Tamaño de cada cubo
const depth = 10; // Profundidad del terreno

const instancesCount = (worldSize * 2 + 1) * (worldSize * 2 + 1); // Número total de instancias de superficie
const dirtInstancesCount = instancesCount * depth; // Número total de instancias de subsuelo

const cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
const textureLoader = new THREE.TextureLoader();

// Cargar texturas (ajusta las rutas según tus texturas)
const cubeTextureTop = textureLoader.load('top.jpg');
const cubeTextureSide = textureLoader.load('side.jpg');
const cubeTextureBottom = textureLoader.load('bottom.jpg');

// Crear materiales para cada cara del cubo
const materials = [
    new THREE.MeshStandardMaterial({ map: cubeTextureSide }),   // Cara frontal
    new THREE.MeshStandardMaterial({ map: cubeTextureSide }),   // Cara trasera
    new THREE.MeshStandardMaterial({ map: cubeTextureTop }),    // Cara superior
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara inferior
    new THREE.MeshStandardMaterial({ map: cubeTextureSide }),   // Cara derecha
    new THREE.MeshStandardMaterial({ map: cubeTextureSide })    // Cara izquierda
];

const dirtMaterials = [
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara frontal
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara trasera
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara superior
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara inferior
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom }), // Cara derecha
    new THREE.MeshStandardMaterial({ map: cubeTextureBottom })  // Cara izquierda
];

// Crear los InstancedMeshes
instancedMesh = new THREE.InstancedMesh(cubeGeometry, materials, instancesCount);
instancedMesh.castShadow = true;
instancedMesh.receiveShadow = true;

dirtInstancedMesh = new THREE.InstancedMesh(cubeGeometry, dirtMaterials, dirtInstancesCount);
dirtInstancedMesh.castShadow = true;
dirtInstancedMesh.receiveShadow = true;

collisions = {}

generateWorld = (x1, z1) => {
    scene.add(instancedMesh);
    scene.add(dirtInstancedMesh);
    targetObject.position.set(x1, camera.position.y, z1)
    light.position.set(x1 + 20, camera.position.y + 40, z1 + 20);
    // Llenar los InstancedMeshes con las posiciones de los cubos
    const matrix = new THREE.Matrix4();
    let index = 0;
    for (let x = x1 - worldSize; x <= x1 + worldSize; x++) {
        for (let z = z1 - worldSize; z <= z1 + worldSize; z++) {
            const surface = Math.floor(
                noise.simplex2(x / 30, z / 30) * 8 +
                noise.simplex2(x / 300, z / 300) * 35 +
                noise.simplex2(x / 3000, z / 3000) * 100
            ); // Altura del terreno

            // Verificar si el bloque está destruido
            if (!destroyedBlocks[`x${x}y${surface}z${z}`]) {
                matrix.makeTranslation(x, surface, z);
                instancedMesh.setMatrixAt(index, matrix);
                collisions[`x${x}y${surface}z${z}`] = true;
            } else {
                // Si el bloque no está puesto, moverlo fuera de la vista:
                matrix.makeTranslation(9999, 9999, 9999);
                instancedMesh.setMatrixAt(index, matrix);
            }

            for (let i = 1; i < depth; i++) {
                if (!destroyedBlocks[`x${x}y${surface - i}z${z}`]) {
                    matrix.makeTranslation(x, surface - i, z);
                    dirtInstancedMesh.setMatrixAt(index * depth + i, matrix);
                    collisions[`x${x}y${surface - i}z${z}`] = true;
                } else {
                    matrix.makeTranslation(9999, 9999, 9999);
                    dirtInstancedMesh.setMatrixAt(index * depth + i, matrix);
                }
            }

            index++;
        }
    }
    instancedMesh.instanceMatrix.needsUpdate = true;
    dirtInstancedMesh.instanceMatrix.needsUpdate = true;
}

removeWorld = () => {
    collisions = {}
    scene.remove(instancedMesh)
    scene.remove(dirtInstancedMesh)
}
targetObject = new THREE.Object3D(); 
light.target = targetObject;
scene.add(light.target);

generateWorld(0, 0)

setInterval(() => {
    light.target.updateMatrix()
    light.target.updateMatrixWorld()
    removeWorld()
    generateWorld(Math.floor(camera.position.x), Math.floor(camera.position.z))
}, 500)

// Añadir PointerLockControls (opcional para modo espectador)
controls = new THREE.PointerLockControls(camera, document.body);
document.addEventListener('click', () => {
    controls.lock();
});
scene.add(controls.getObject()); // Agregar la cámara al mundo

// Manejar el redimensionamiento de la ventana
window.addEventListener('resize', onWindowResize);

// Manejar eventos de teclado para control de movimiento
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);

// Llamar a la función de renderizado
render();

}

// Función para manejar el redimensionamiento de la ventana
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}

// Función para manejar eventos de teclado (presionar tecla)
function onKeyDown(event) {
switch (event.code) {
case ‘KeyW’:
moveForward = true;
break;
case ‘KeyS’:
moveBackward = true;
break;
case ‘KeyA’:
moveLeft = true;
break;
case ‘KeyD’:
moveRight = true;
break;
case ‘Space’:
moveUp = true;
break;
case ‘ShiftLeft’:
case ‘ShiftRight’:
moveDown = true;
break;
case ‘KeyE’:
destroyBlocks=true;
break;
case ‘KeyQ’:
placeBlocks=true;
break;
}
}

// Función para manejar eventos de teclado (soltar tecla)
function onKeyUp(event) {
switch (event.code) {
case ‘KeyW’:
moveForward = false;
break;
case ‘KeyS’:
moveBackward = false;
break;
case ‘KeyA’:
moveLeft = false;
break;
case ‘KeyD’:
moveRight = false;
break;
case ‘Space’:
moveUp = false;
break;
case ‘ShiftLeft’:
case ‘ShiftRight’:
moveDown = false;
break;
case ‘KeyE’:
destroyBlocks=false;
break;
case ‘KeyQ’:
placeBlocks=false;
break;
}
}

// Parámetros de la gravedad:
g = 0.01
ySpeed = 0
jumpSpeed = 0.2

// Función para actualizar la posición del personaje según las teclas presionadas
function updatePosition() {
for(i1 in placedBlocks){
key = i1;
objX=key.split(“x”)[1].split(“y”)[0];
objY=key.split(“y”)[1].split(“z”)[0];
objZ=key.split(“z”)[1];
if(
Math.floor(objX)==Math.floor(camera.position.x)
&&
Math.floor(objY)==Math.floor(camera.position.y)
&&
Math.floor(objZ)==Math.floor(camera.position.z)
){
if(objY<camera.position.y){
ySpeed=g
controls.getObject().position.y += ySpeed
}
if(objY<camera.position.y-3){
ySpeed=g
controls.getObject().position.y += ySpeed
}
}
}
const speed = 0.1; // Velocidad de movimiento del personaje
// Gravedad:
ySpeed -= g
controls.getObject().position.y += ySpeed
if (ySpeed < -0.2) { ySpeed = -0.2 }
// Colisiones:
// Abajo:
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - speed) +
“z” + Math.floor(controls.getObject().position.z)
]) {
ySpeed = g
controls.getObject().position.y += ySpeed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - speed - 1) +
“z” + Math.floor(controls.getObject().position.z)
]) {
ySpeed = g
controls.getObject().position.y += ySpeed
}
// Arriba:
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y + speed) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.y -= speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y + speed - 1) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.y -= speed
}
// Eje x:
if (collisions[
“x” + Math.floor(controls.getObject().position.x - speed) +
“y” + Math.floor(controls.getObject().position.y) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.x += speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x - speed) +
“y” + Math.floor(controls.getObject().position.y - 1) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.x += speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x + speed) +
“y” + Math.floor(controls.getObject().position.y) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.x -= speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x + speed) +
“y” + Math.floor(controls.getObject().position.y - 1) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.x -= speed
}
// Eje z:
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y) +
“z” + Math.floor(controls.getObject().position.z - speed)
]) {
controls.getObject().position.z += speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - 1) +
“z” + Math.floor(controls.getObject().position.z - speed)
]) {
controls.getObject().position.z += speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y) +
“z” + Math.floor(controls.getObject().position.z + speed)
]) {
controls.getObject().position.z -= speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - 1) +
“z” + Math.floor(controls.getObject().position.z + speed)
]) {
controls.getObject().position.z -= speed
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y) +
“z” + Math.floor(controls.getObject().position.z)
]) {
controls.getObject().position.y += speed * 2
}
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - 1) +
“z” + Math.floor(controls.getObject().position.z)
]){
controls.getObject().position.y += speed * 2
}
try {
if (moveForward) {
controls.getObject().position.x -= speed * Math.sin(getCameraRotationY());
controls.getObject().position.z -= speed * Math.cos(getCameraRotationY());
}
if (moveBackward) {
controls.getObject().position.x += speed * Math.sin(getCameraRotationY());
controls.getObject().position.z += speed * Math.cos(getCameraRotationY());
}
if (moveLeft) {
controls.getObject().position.x -= speed * Math.cos(getCameraRotationY());
controls.getObject().position.z += speed * Math.sin(getCameraRotationY());
}
if (moveRight) {
controls.getObject().position.x += speed * Math.cos(getCameraRotationY());
controls.getObject().position.z -= speed * Math.sin(getCameraRotationY());
}
if (moveUp) {
// controls.getObject().position.y += speed;
if (collisions[
“x” + Math.floor(controls.getObject().position.x) +
“y” + Math.floor(controls.getObject().position.y - 2) +
“z” + Math.floor(controls.getObject().position.z)
]) {
ySpeed = jumpSpeed
}
}
if (moveDown) {
// controls.getObject().position.y -= speed;
}
if (destroyBlocks){
destroyBlock();
}
if (placeBlocks===true){
placeBlock1();
}
} catch (e) {}
}

// Función para obtener la rotación de la cámara en el eje Y
function getCameraRotationX() {
const euler = new THREE.Euler();
euler.setFromQuaternion(camera.quaternion, ‘YXZ’);
return euler.x;
}

// Función para obtener la rotación de la cámara en el eje Y
function getCameraRotationY() {
const euler = new THREE.Euler();
euler.setFromQuaternion(camera.quaternion, ‘YXZ’);
return euler.y;
}

// Función para obtener la rotación de la cámara en el eje Y
function getCameraRotationZ() {
const euler = new THREE.Euler();
euler.setFromQuaternion(camera.quaternion, ‘YXZ’);
return euler.z;
}

placedBlocks=

// Función para destruir bloques
function destroyBlock() {
const raycaster = new THREE.Raycaster();
const direction = new THREE.Vector3(0, 0, -1);
direction.applyQuaternion(camera.quaternion);
raycaster.set(camera.position, direction);

const intersects = raycaster.intersectObject(instancedMesh);

if (intersects.length > 0) {
    const instanceId = intersects[0].instanceId;
    const matrix = new THREE.Matrix4();
    instancedMesh.getMatrixAt(instanceId, matrix);
    const position = new THREE.Vector3();
    position.setFromMatrixPosition(matrix);
    if(position.distanceTo(camera.position)<5){
        // Eliminar el bloque de las colisiones y añadirlo a los bloques destruidos
        destroyedBlocks[`x${Math.floor(position.x)}y${Math.floor(position.y)}z${Math.floor(position.z)}`] = true;
        delete collisions[`x${Math.floor(position.x)}y${Math.floor(position.y)}z${Math.floor(position.z)}`];

        // Mover el bloque fuera de la vista (o puedes optar por otras formas de "destruirlo")
        matrix.makeTranslation(9999, 9999, 9999);
        instancedMesh.setMatrixAt(instanceId, matrix);
        instancedMesh.instanceMatrix.needsUpdate = true;
    }
}

const dirtIntersects = raycaster.intersectObject(dirtInstancedMesh);

if (dirtIntersects.length > 0) {
    const instanceId = dirtIntersects[0].instanceId;
    const matrix = new THREE.Matrix4();
    dirtInstancedMesh.getMatrixAt(instanceId, matrix);
    const position = new THREE.Vector3();
    position.setFromMatrixPosition(matrix);
    if(position.distanceTo(camera.position)<5){
        // Eliminar el bloque de las colisiones y añadirlo a los bloques destruidos
        destroyedBlocks[`x${Math.floor(position.x)}y${Math.floor(position.y)}z${Math.floor(position.z)}`] = true;
        delete collisions[`x${Math.floor(position.x)}y${Math.floor(position.y)}z${Math.floor(position.z)}`];

        // Mover el bloque fuera de la vista (o puedes optar por otras formas de "destruirlo")
        matrix.makeTranslation(9999, 9999, 9999);
        dirtInstancedMesh.setMatrixAt(instanceId, matrix);
        dirtInstancedMesh.instanceMatrix.needsUpdate = true;
    }
}

for(i1 in placedBlocks){
    console.log("primer bucle")
    for(j=10;j<0;j-=0.1){
        key = i1;
        objX=key.split("x")[1].split("y")[0];
        objY=key.split("y")[1].split("z")[0];
        objZ=key.split("z")[1];
        console.log("segundo bucle: "+key)
        if(
            Math.floor(objX)==Math.floor(camera.position.x+Math.sin(getCameraRotationY())*Math.cos(getCameraRotationX())*j)
            &&
            Math.floor(objY)==Math.floor(camera.position.y+Math.sin(getCameraRotationX())*j)
            &&
            Math.floor(objZ)==Math.floor(camera.position.z+Math.cos(getCameraRotationY())*Math.cos(getCameraRotationX())*j)
        ){
            scene.remove(placedBlocks[key]);
            collisions[key]=false;
        }
    }
}

}

// Función para colocar un bloque en la posición siguiente en la dirección de la cámara
// Función para colocar un bloque en la posición apuntada por la cámara mediante raycasting
function placeBlock1() {
console.log(“Placing key pressed.”);

// Raycaster para determinar la posición del bloque
const raycaster = new THREE.Raycaster();
raycaster.set(camera.position, camera.getWorldDirection(new THREE.Vector3()));

// Array de intersecciones del rayo con objetos visibles
const intersects = raycaster.intersectObjects(scene.children);

// Si hay intersecciones, colocar el bloque en la primera intersección válida
if (intersects.length > 0) {
    const intersect = intersects[0];
    const position = new THREE.Vector3().copy(intersect.point).add(intersect.face.normal);

    // Redondear la posición a enteros
    const newPosition = new THREE.Vector3(
        Math.floor(position.x),
        Math.floor(position.y),
        Math.floor(position.z)
    );

    // Verificar si ya existe un bloque en la posición calculada
    const key = `x${newPosition.x}y${newPosition.y}z${newPosition.z}`;
    if (collisions[key]) {
        console.log("Block already exists at this position.");
        return; // Salir de la función si ya existe un bloque
    }

    // Crear un nuevo bloque en la posición calculada
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshStandardMaterial({ map: new THREE.TextureLoader().load( "bottom.jpg" ) }); // Color amarillo
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.copy(newPosition);

    mesh.castShadow=true;
    mesh.receiveShadow=true;

    // Añadir la nueva posición al sistema de colisiones
    collisions[key] = true;
    placedBlocks[key] = mesh;

    // Añadir el bloque a la escena
    scene.add(mesh);
}

}

// Función para renderizar la escena
function render() {
updatePosition(); // Actualizar posición según teclas presionadas
renderer.render(scene, camera);
requestAnimationFrame(render);
}

// Llamar a la función de inicialización al cargar la página
window.onload = init;](https://)

And this is the result:

This is the file:

script (1).js (21.2 KB)

A few notes, since this looks a little like a GPT-generated code here and there, and there’s things that don’t make much sense (mind, I didn’t go through all the code - just the parts usually suggested by GPT incorrectly):

  1. You’re calling render() in onWindowResize - looking at the body of your render function, could you predict what’ll happen if user resizes the window by dragging the cursor on the edge of the border and resizing it continuously?
  2. Is there a reason why you are regenerating the entire world geometry every 0.5s?
  3. Since you’re not using anything besides the .map property, you’d be getting a comparable visuals when using MeshLambertMaterial or MeshPhongMaterial instead of MeshStandardMaterial, while reducing the cost of material rendering significantly.
  4. Using a Raycaster will likely be faster and more accurate for determining collisions with bounding boxes than splitting strings and comparing names.
  5. getCameraRotationX / Y / Z methods seem to just be equivalent to reading camera.rotation.x / .y / .z directly?
  6. matrix.makeTranslation(9999, 9999, 9999); - 9999 is still a relatively renderable distance in many scenarios. If you’d like to hide an InstancedMesh, you can leave the position, but consider setting it’s scale to 0x0x0.
  7. Since they are not parallelised, you can use a single Raycaster for the entire code. There’s no need to create a new one for each operation.
  8. You’re using instanced meshes for the world, but in placeBlock you’re adding non-instanced cubes?
1 Like

Yes, i want to put non instanced blocks with the ‘Q’ or ‘R’ or another key that is not WASD and E for making new blocks, there are few because player cant place too much blocks, its for that which placed blocks needs to be apart of instanced blocks via keydown element. Apart of that, the blocks places bad, like comparised with minecraft. Can u make it placing blocks correctly and separated of the instanced meshes?

I have this script file whichis filled correctly at the moment, except the place block element:
script.js (18.4 KB)

EDIT:

for(i=0;i<10;i+=0.1){
    if(detectObjectAtPosition(
        Math.round(camera.position.x + Math.sin(getCameraRotationX()) * Math.cos(getCameraRotationY()) * i),
        Math.round(camera.position.y + Math.sin(getCameraRotationY()) * i),
        Math.round(camera.position.z + Math.cos(getCameraRotationX()) * Math.cos(getCameraRotationY()) * i)
    )){
        break
    }
    mesh.position.set(
        Math.round(camera.position.x + Math.sin(getCameraRotationX()) * Math.cos(getCameraRotationY()) * i),
        Math.round(camera.position.y + Math.sin(getCameraRotationY()) * i),
        Math.round(camera.position.z + Math.cos(getCameraRotationX()) * Math.cos(getCameraRotationY()) * i)
    );
    p1x=Math.round(mesh.position.x)
    p1y=Math.round(mesh.position.y)
    p1z=Math.round(mesh.position.z)
    collisions[`x${p1x}y${p1y}z${p1z}`] = { type: "solid" };
}

This functions place blocks, but places bad. How can I adjust Mesh.position.set?

I cant use fidddle because it doesnt import me the perlin.js module…

The solution is here (Because its impossible to progress more at this point):

script (3).js (18.5 KB)

If you press q, the blocks can push behind you. There aren’t solid, never will be solid, but yeah, the unique algorithm is this. Sorry if I did bad but i cant evade the response, so… nothing.

EDIT:

Some improvement of this is in this file:

script (4).js (20.0 KB)

EDIT #2:

I reached destroying the blocks which player has beeen placed:

script (5).js (23.2 KB)