Help with Character Movement

I did this 3rd-person camera tutorial I found on YouTube. I created a modified version here to account for private class members and a few design pattern issues.

The keyboard controls originally moved the character forward when pressing “w” and backward when pressing “s,” as expected. However, the “a” and “d” keys didn’t move the character left or right as you might expect, but rather turned the character (around the y axis) clockwise or counter-clockwise, respectively.

I decided to move the controls for turning the character (changing perspective) to the arrow keys, and set the “a” and “d” keys to strafe left and right. The arrow keys work. Right (d key) kind of works, but goes slowly. Left (a key) doesn’t work at all. What am I doing wrong?

Admittedly, I’m a bit of a Three.js/WebGL noob. Lines #15-17 and most of #80-169 have me stumped.

  1. If there’s one lesson to take out of this - it’s to keep your code clean :skull: Nobody, including you in a week, will understand what _Q _R and _A are - meaningful names make debugging easy, single-character names make it nearly impossible :see_no_evil:

  2. Right (d key) kind of works, but goes slowly - it’s because the dampening and acceleration is set to be different for each axis:

this.#decceleration = new THREE.Vector3(-0.0005, 0, -5.0)
this.#acceleration = new THREE.Vector3(1, 0.25, 50.0)
  1. Left (a key) doesn’t work at all - “else” statement in line 124 applies only to key “D”. So if it’s not pressed, velocity is set to 0.
1 Like
  1. If there’s one lesson to take out of this - it’s to keep your code clean :skull: Nobody, including you in a week, will understand what _Q _R and _A are - meaningful names make debugging easy, single-character names make it nearly impossible :see_no_evil:

Yeah, it took me a minute to decipher _Q, _R, and _A. Not to sound ungrateful for the original code, but it was littered with stuff like that. They’re the only ones I haven’t renamed because I’m not 100% sure what their purposes are.

  1. Right (d key) kind of works, but goes slowly - it’s because the dampening and acceleration is set to be different for each axis

I figured that, but the more I played with it, the less sense it seemed to make. I just chalked it up to “learn more Three.js.”

  1. Left (a key) doesn’t work at all - “else” statement in line 124 applies only to key “D”. So if it’s not pressed, velocity is set to 0.

Ha, that seems rather obvious now. I’m not sure if that was my goof, or something from the original author that mistakenly got left in after some earlier refactoring. I think it was supposed to be an if/if else/else.

This whole block is kind of absurd.

    if (this.#input.keys.anticlockwise) {
      _A.set(0, 1, 0)
      _Q.setFromAxisAngle(
        _A,
        4.0 * Math.PI * timeInSeconds * this.#acceleration.y
      )
      _R.multiply(_Q)
    }

    if (this.#input.keys.clockwise) {
      _A.set(0, 1, 0)
      _Q.setFromAxisAngle(
        _A,
        4.0 * -Math.PI * timeInSeconds * this.#acceleration.y
      )
      _R.multiply(_Q)
    }

    controlObject.quaternion.copy(_R)

    const oldposition = new THREE.Vector3()
    oldposition.copy(controlObject.position)

    const forward = new THREE.Vector3(0, 0, 1)
    forward.applyQuaternion(controlObject.quaternion)
    forward.normalize()

    const sideways = new THREE.Vector3(1, 0, 0)
    sideways.applyQuaternion(controlObject.quaternion)
    sideways.normalize()

    sideways.multiplyScalar(velocity.x * timeInSeconds)
    forward.multiplyScalar(velocity.z * timeInSeconds)

    controlObject.position.add(forward)
    controlObject.position.add(sideways)

Thanks. I was able to refactor a lot of that down to less, more understandable code. Even after 20+ years in JS, sometimes you just need a nudge in the right direction.