I’m trying to figure out a way of preventing my character from flying off the screen. I have managed to sort of setup some bounds but they’re not in line with the viewport. The character hits the boundary at the left and bottom of the screen but there is none for the top and right side.
I’m very new to GD Script (and programming in general) so some help with this would be greatly apprciated! I’ve attached a snippet of my code.
Please paste your code here instead of using a screenshot. You can use the </> button here to wrap the code in triple backticks (```) to format it properly.
But if you want to use clamp, I suspect your problem is related to how get_viewport().size works. The viewport size is the size of physical pixels on the screen that the actual window takes up. However, this might not match your game’s actual units, for example if you apply any zoom or stretch/maximize the window.
So, to get the actual size of the visible area, you should use get_viewport_rect().size instead.
Additionally, you should perform the clamping after calling move_and_slide(), since move_and_slide() will change the position. Otherwise your character will appear to sink into the edges a bit if the player holds a direction.
Okay, I think I’ve got a better idea of what you’re trying to do here.
Just to clarify my understanding: You’ve got a 3D character, which you’re moving around on the X and Y axis. You’ve got a 3D camera pointed towards the character. You want to limit the character’s movement to stay within the camera’s visible area.
Is that correct?
If so, because your camera is using a perspective projection, you’ll need to do some basic matrix math to make this happen. This is because the screen pixels aren’t relevant to the 3D world space.
Fortunately, Camera3D provides some handy methods to do all the work for that.
Try this clamping code:
# Screen clamping
# Get the current 3D camera.
var camera := get_viewport().get_camera_3d()
# Figure out how far the player currently is from the camera (along the camera's forward axis).
var player_pos_relative_to_camera := camera.global_transform.inverse() * global_position
var z_depth := -player_pos_relative_to_camera.z
# Get the world-coordinate corners of the visible area aligned with the player character.
var upper_left := camera.project_position(Vector2(0, 0), z_depth)
var bottom_right := camera.project_position(get_viewport().get_visible_rect().size, z_depth)
position.x = clamp(position.x, upper_left.x, bottom_right.x)
position.y = clamp(position.y, bottom_right.y, upper_left.y)
I tried my best to recreate your scene, and the above code looks like this:
That seems to have worked! Thank you
I do have some questions, since I’m very new to GD Script/programming in general I would just like to try and understand a few things if that’s okay?
Camera’s forward axis. Is the the Z axis? as that is the axis that points forward from the camera?
I’m not sure HOW the script is determining the upper left and bottom right.