Hello community
I’m trying to make a collision system using Box3.
Each player have their meshes in a group (this.group), red on the gif.
In the constructor of the Player class, I create the AABB box using setFromObject
which is white on the gif.
this.hitbox = new THREE.Box3().setFromObject(this.group);
this.hitboxHelper = new THREE.Box3Helper(this.hitbox, new THREE.Color('#ffffff'));
this.group.add(this.hitboxHelper);
In a setInterval loop (to simulate frame update loop and avoid spamming in case of problems), I make setFromObject
again to update positions and then have accurate collisions.
But, when I change the positions or the rotation of the group, the hitbox have a weird behavior :
What I’m doing wrong ?
Thank you
AABB means axis-aligned bounding boxes
dim of your box3helper ( AABB) is calcuted according x,y,z axis at every time . so if use it after rotation of your group , dim change and will be different at every time .
A correct AABB encapsulating a group of objects looks like so: https://jsfiddle.net/vLtq1dhw/
As you can see, the fiddle uses an instance of BoxHelper
.
If you want to achieve the same with Box3Helper
, you have to recompute the AABB manually every frame: https://jsfiddle.net/vLtq1dhw/1/
As mentioned by @elysium11, Box3
is an AABB so it can never be rotated.
Thank you @elysium11, @Mugen87
As I described, I don’t transform the AABB itself.
Only things I do is playing with the group.
Take a look to the update
method called each frame :
public update(delta: number) {
this.hitbox.setFromObject(this.group);
if (this.actions.move.left || this.actions.move.right) {
const direction = this.actions.move.right ? 1 : -1;
const rotationDelta = (this.stats.turnSpeed / 40) * direction * delta;
this.group.rotation.y += rotationDelta;
Game.emitPlayerUpdate({
action: 'move',
data: {
rotation: {
y: this.group.rotation.y
}
}
});
}
if (this.actions.move.forward || this.actions.move.backward) {
const direction = this.actions.move.forward ? 1 : -1;
const translationDelta = (this.stats.moveSpeed / 10) * delta;
this.group.translateOnAxis(new THREE.Vector3(0, 0, direction), translationDelta);
Game.emitPlayerUpdate({
action: 'move',
data: {
position: {
x: this.group.position.x,
z: this.group.position.z
}
}
});
}
}
The result is still unexepected :
What could cause this phenomenon ?
you init once hitbox
this.hitbox = new THREE.Box3().setFromObject(this.group);
this.hitboxHelper = new THREE.Box3Helper(this.hitbox, new THREE.Color(’#ffffff’));
this.group.add(this.hitboxHelper);
but after you write ( this is the origin of issue )
public update(delta: number) {
this.hitbox.setFromObject(this.group);
the only thing you have to do is to translate or rotate your group but don t redefine hitbox inside update .
edit : step 1
you define your group and your hitbox .
step 2
you rotate or translate your group
step 3
update hitbox , so dim are bigger than initial
step 4
you rotate or translate group which contain now a hitbox bigger
step 5
update hitbox , so dim bigger than previous step 4
and so on = your hitbox ( see by your helperbox ) increase )
1 Like
Ok so Box3 doesn’t need to be updated ?
I tried this before, I can see with the Box3Helper that the hitbox follows the group but collisions (with intersectsBox
) are not accurate or even completely wrong.
If I update with setFromObject
, the hitbox grows yes but collisions are accurate.
I probably miss something…
Thank you for your answer
if you need an aabb hitbox with update , so don’t add at start , your hitbox to your group , like this it will not increase .
1 Like
You are the man, you solved my issue !
Thank you @elysium11.
export default abstract class Collidable {
public hitbox: THREE.Box3;
public hitboxHelper: THREE.Box3Helper;
constructor() {
this.hitbox = new THREE.Box3();
this.hitboxHelper = new THREE.Box3Helper(this.hitbox);
this.initHitbox();
}
public initHitbox() {
Engine.addToScene([this.hitboxHelper]);
}
public updateHitbox(group: THREE.Group) {
this.hitbox.setFromObject(group);
}
}
And in the player class, at every frame :
this.updateHitbox(this.group);