Hi! I’m relatively new to UE4, but I’ve got a few years of C++ experience. I’m not afraid to poke around in UE’s source code (which I’ve just been doing, but I’m getting nowhere fast).
So my brother is trying to make an RTS game, and a typical (and pretty necessary) part of RTS games is the ability to box select units. He’s tried using GetActorsInSelectionRectangle, but this has a nasty, unstated limitation: it only works if the camera is oriented vertically, looking straight down at the scene. From what my brother’s told me, it includes objects that may not even be on screen when using this function.
He explained the issue to me last night, and I’ve been tinkering around with it since. Two of the main challenges is that the player’s camera *will be rotated relative to the axis *and it also is using perspective projection, not orthographic. He probably wouldn’t mind switching to orthographic, but we cannot assume the camera will be in a fixed rotation. Maybe the player won’t be able to rotate it, but ideally it could at least be able to be rotated in the UE4 editor.
I have a few ideas, but I’m not too sure what makes the most sense. If you’ve already tackled something like this, chances are your solution is better than all of my ideas… if that describes you, don’t worry about reading through these.
Do keep in mind that some of these are based more on my general understanding of 3D space (gained from working with Unity and from a few math classes) than from my understanding of Unreal.
Solution 1: Frustums (or Pyramids)
This is the most direct approach, and it should always work. That being said, I think it’d also be the slowest?
The approach would be to create a frustum with a rectangular cross section. First, we figure out where the 4 corners of our selection box lie on the 3D map. (Which is easy; you just cast from the camera to the world, and get these points.) Then you create your rectangular frustum so that its “legs” pass through these 4 points. Then the other 4 points (or 1 point, if a pyramid) lie at the camera.
Thus, you end up with a 3D shape and you can do some sort of sweep cast through this. I believe UE4 already has tools for building meshes (and I know I found something else last night, too). It probably wouldn’t be too difficult to use this to create our frustum/pyramid. All we’d need to do is attach this to an actor, and then it would be easy to ask for overlaps from a blueprint.
That being said, this feels like it should be kind of slow. Maybe not too slow that it’s a concern, but it still feels grossly wasteful. AFAIK, you gotta recompute stuff every time. This isn’t such a concern for the built version, but UE4 is so porky that I could see it possibly being an issue while testing stuff in the engine. (This kind of feels like a “Just go try it” situation. I’ll do that if I don’t get any responses soon.)
Solution 2: Just borders
As mentioned before, we can, using raycasts, figure out where the 4 corners of our selection rectangle fall on the 3D map. Instead of trying to capture this whole area, we just cast boxes along the edges.
Then it becomes a matter of watching how the box grows. Whenever the box edges move, you do a box cast to see if anything new has been included/removed in the box. Then it’s just a matter of including/excluding the relevant stuff.
You also continue to check the edges, even for the edges which do not move. If anything wonders in/out of the box, you add/remove them from the selection.
Only problem is that UE4’s box casting functions… don’t support rotation? Feels like a really weird omission, but that means I’ll need to hack together some equivalent using regular raycasts. I honestly don’t understand enough about casting volumes yet, so I’ll probably need to go investigate that before I try it.
Solution 3: Pull from the rendering system?
This is more of a hunch than anything, and probably the most farfetched given what I know. But, for rendering, UE4 is probably aware of what is being rendered and what is not. If it does any culling at all, it should be able to determine what it should care about and what can be neglected.
Does the engine have a succinct way of checking what falls inside the viewport? If so, would it be very difficult to adapt that for this? Really, our box selection is just taking a portion of the camera’s vision “cone” and seeing if anything falls in there. I’m wondering if there’d be some way to take advantage of this.
This is more of a shot in the dark than anything, but I thought it might be worth bringing up, in case anyone who’s worked with the rendering stuff knows a bit more about this. If so, please feel free to talk some sense into me.