Detecting object using the side of Camera3D's view
Toxe I think they don't necessarily need to move the "walls" with respect to each other. The walls just need to follow the camera, equidistant on each side at some max distance which will be suitable for when the camera is fully zoomed out, since they aren't necessary when the camera is zoomed in.
- Edited
- Best Answerset by Gowydot
The easiest way is to just use camera frustum planes. To constrain camera between two limiter Node3D origins simply check if one of them is in the frustum and push camera to left/right for distance that's equal to limiter node's distance to corresponding frustum plane (projected onto camera's left-right basis vector). This will work for ortho as well as perspective cameras. Just make sure that camera never sees both limiters.
func constrain_camera_left_right(camera: Camera3D, left: Node3D, right: Node3D) -> void :
var frustum = camera.get_frustum()
var left_plane = frustum[2]
var right_plane = frustum[4]
var d = min(0, left_plane.distance_to(left.global_position))
camera.translate_object_local(Vector3.RIGHT * (d/left_plane.normal.dot(camera.global_transform.basis.x)))
d = min(0, right_plane.distance_to(right.global_position))
camera.translate_object_local(Vector3.RIGHT * (d/right_plane.normal.dot(camera.global_transform.basis.x)))
Exactly the same approach can be applied to keep a player inside camera frustum, just use opposite sides of frustum planes, i.e. invert the plane normals and move the player instead of camera.
@Tomcat @Toxe @award
Yea I think creating collision walls is the most straight forward solution. However, I will give xyz's solution a go as I've never done it before.
@xyz
I got the constrain_camera_left_right working so thanks so much! But..
same approach can be applied to keep a player inside camera frustum, just use opposite sides of frustum planes
func constrain_player_left_right(player: CharacterBody3D) -> void :
var frustum = cam.get_frustum()
var left_plane = frustum[2]
var right_plane = frustum[4]
player.translate_object_local(Vector3.LEFT * (-left_plane.normal.dot(global_transform.basis.x)))
player.translate_object_local(Vector3.LEFT * (-right_plane.normal.dot(global_transform.basis.x)))
This is not working as I have no clue what I'm doing.
Can you give me an example code on constraining players inside? I would like to see a working example and try to understand it after.
Will you be using orthographic camera only?
My plan is to have orthographic camera for players and perspective camera for background and somehow sync them. I did try it using subviewport and it kind of worked but also with errors, but that's another question for later
- Edited
Gowydot This is not working as I have no clue what I'm doing.
Can you give me an example code on constraining players inside? I would like to see a working example and try to understand it after.
Sometimes I feel I'm just being used on this forum for code solicitation when ChatGPT fails to produce copy-pastable results. Sigh
I'll knock you up an example. Stay tuned. In the meantime maybe work on getting some clues about how this works. Being clueless is not a good place to be for a game developer
Btw doing it via frustum planes is much more elegant and clean than managing colliders. Especially if you use perspective camera.
- Edited
Gowydot There you go:
func constrain_node_to_camera_left_right(node: Node3D, camera: Camera3D, margin: float) -> void:
var frustum = camera.get_frustum()
var left_plane = frustum[2]
var right_plane = frustum[4]
var d = max(0, left_plane.distance_to(node.global_position) + margin)
node.translate_object_local(Vector3.RIGHT * (-d/left_plane.normal.dot(node.global_transform.basis.x)))
d = max(0, right_plane.distance_to(node.global_position) + margin)
node.translate_object_local(Vector3.RIGHT * (-d/right_plane.normal.dot(node.global_transform.basis.x)))
Note that this expects node to move along its local x axis so it will constrain that axis only. It can be generalized for an arbitrary axis but I won't go into it here since you probably won't ever need it for this type of game.
First of all thanks for the code, I really appreciated. When I tried it although it works as intended it also introduces other problems like my expanding camera no longer works or the player can drag the other player along with the camera. I'm gonna have to look deeper into it over the weekend. I agreed that using frustum is more elegant but I've never work with it before so it gonna take some times to learn.
Sometimes I feel I'm just being used
Sorry that was not my intention. As I said in another thread somewhere the way I learn is to see a working example and then go back to learn it myself one line at a time. If it makes you feel any better I've never used ChatGpt for anything I did try to do it myself several times before asking for an example code.
- Edited
Gowydot it also introduces other problems like my expanding camera no longer works or the player can drag the other player along with the camera
That has nothing to do with code I posted. You should make sure that the rest of your code and setup function properly and that constrains are applied in appropriate order. And remember, you asked for code examples that you can learn from. So try to understand what the code does and adapt it to your specific needs.