Search the Community

Showing results for tags 'first person camera'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • HTML5 Game Coding
    • News
    • Game Showcase
    • Facebook Instant Games
    • Coding and Game Design
  • Frameworks
    • Phaser 3
    • Phaser 2
    • Pixi.js
    • Babylon.js
    • Panda 2
    • melonJS
    • Haxe JS
    • Kiwi.js
  • General
    • General Talk
  • Business
    • Collaborations (un-paid)
    • Jobs (Hiring and Freelance)
    • Services Offered

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Twitter


Skype


Location


Interests

Found 1 result

  1. I think I may be using rotation incorrectly, but I'm not sure what I'm doing wrong. I'd ask a more specific question, but I truly have no idea how to narrow things down. So either I have a small stupid bug somewhere (could be...) or just a fundamental misunderstanding of something 3D, in which case I hope someone in this forum can point it out. I've got a multiplayer first person shooter where the game client sends its keystrokes and camera rotation to the server. This is used to rotate the player's mesh (which is just a cube with a red face for forward) and then move the player around. The player is not limited to moving along the ground, and can in fact just look up into the sky and press forward and fly around... so I guess they're a little more like space ships that can strafe than true first person shooter characters. Everything looked like it was working perfectly until I started comparing the client predicted positions to the server authoritative positions. Now I don't mean to drag anyone down the rabbit hole of netcode, and I strongly suspect my bug is something very basic relating to rotating a mesh and then trying to move it forward (or left, or right, or backwards). To rotate the camera, I'm just capturing mouse movement and multiplying by a mouseSensitivity input.onmousemove = (e) => { if (input.isPointerLocked) { camera.rotation.y += e.movementX * mouseSensitivity camera.rotation.x += e.movementY * mouseSensitivity } } I'm not sure if that is correct, but it looks and feels like a first person shooter. Every frame the client produces a command that looks like this: { forward: <Boolean> input.frameState.forward, backward: <Boolean> input.frameState.backward, left: <Boolean> input.frameState.left, right: <Boolean> input.frameState.right, rotationX: <Float32> camera.rotation.x, rotationY: <Float32> camera.rotation.y, rotationZ: <Float32> camera.rotation.z, delta: <Float32> deltaTime } This contains the state of the movement-related keys, and how long they've been held down (determinism note: holding 'W' for 0.187 seconds at speed 100 is a deterministic calculation which can be repeated by server and client to get the same result). It also contains the camera rotation, which I'm wondering if this correct..? I'd like to note that I've used this type of command structure in several games and that it is truly deterministic, but that I've never done this in 3D, so perhaps my error is just the rotation. The actual movement logic move(command) { // rotate the mesh to the same rotation as the camera mesh.rotation.x = command.rotationX mesh.rotation.y = command.rotationY mesh.rotation.z = command.rotationZ // unit vector of our movement let unit = BABYLON.Vector3.Zero() if (command.forward) { unit.z += 1 } if (command.backward) { unit.z -= 1 } if (command.left) { unit.x -= 1 } if (command.right) { unit.x += 1 } unit.normalize() // rotating the unit vector to the context of this entity let heading = mesh.getDirection(unit) // full vector, movement and magnitude let velocityCoef = speed * command.delta let velocity = heading.multiplyByFloats(velocityCoef, velocityCoef, velocityCoef) // move mesh.position.x += velocity.x mesh.position.y += velocity.y mesh.position.z += velocity.z let y = ground.getHeightAtCoordinates(mesh.position.x, mesh.position.z) // added a little padding to keep the cube off of the ground if (mesh.position.y < y + 1) { mesh.position.y = y + 1 } } So the mesh gets rotated instantly to the rotation specified in the command. The command's rotation is just the camera's rotation. Is this a mistake..? Is copying the values of the camera's rotation vector TO the player mesh rotation not in fact what I should be doing to get the player to face in the same direction as the camera? After that I do that unit vector stuff which encompasses what I consider to be first person-style movement with strafes: forward, backward, left, and right. The direction the mesh actually moves when all is said and done is calculated by mesh.getDirection, and then multiplied by the velocity. I worry about both the above ideas, because I've been combing this forum looking for babylon first person shooter examples, and they're all different from this and from one another. None of them copy the camera's rotation vector on the player, and none of them use getDirection. I see other people using matrices, local/global thingies, getfrontposition, and other properties of cameras. I feel like I'm missing something. And yet, my game SEEMS to work pretty well. It wasn't even until I started integrating the clientside prediciton layer that I started to notice that there were tiny inconsistencies with the positions of objects. When moving the mouse and rotating the camera, there are no clientside prediction errors. If the client predicts that rotationX is 0.1234, the server always agrees. This is no surprise because the camera rotation is in fact client authoritative. When hitting W A S D or the arrow keys in any combination without rotating the camera, there are no clientside prediction errors. The length of any key press is known. The client produces its own local version of the movement. The server then receives the identical command and moves the player by an identical amount. At some point the client will receive a snapshot of server data that contains the state of the gameworld after having factored in the aforementioned command, at which point the client will know if the movement it predicted a few frames ago lined up with the server authoritative movement. This is the actual hard part of clientside prediction and I'm pleased to say it is working and even supports collisions with the terrain mesh. It isn't even the case that it sometimes has a mild error -- it literally never has an error, and this should be expected given that there are no collisions between players, so there's never any unknown state to the client that could potentially cause it miscalculate a position. However when moving the mouse AND holding any of the movement keys, the predictions are incorrect every frame! Because of the way this engine is put together the position gets reconciled, and it recovers. But what is throwing off the deterministic calculation? A.) rotate a mesh to a specific XYZ, B.) find a forward vector C.) move a specific distance along that vector. I'm clearly not doing A->B->C otherwise it would be deterministic and there would be no error. I tried to recreate the movement code without a network, and got even more confused because setting the xyz of a mesh.rotation and then using mesh.getDirection to attempt to move it forward produced no turning in the BJS playground, the sphere just kept moving in one direction: https://playground.babylonjs.com/#LD0IDK#2. There are two spheres, one remains stationary, the other one is moved 3 steps by 3 commands each of which rotates the mesh before moving it forward. It ends up going straight, which I don't understand given that it is being rotated and that it moves in the direction it is facing (or that was my intention). So perhaps therein lines the issue, though if this playground doesn't work how does my game even do anything at all... Here's a gif of what the camera controls and cube players look like (all of the visible cubes are bots that are sending random commands tho, so never-mind they crazy directions that they're facing).