I’m trying to make top down camera for an RTS game. I can move it with WASD and edge scroll (not at the moment though). I can also free look around with LMB and raise and lower the camera with the scroll wheel.
I want it to keep the set height with the scroll wheel for example 100 units, always. So when going up or down hills it will move the camera on the Z axis.
I manage this by getting Camera Set Height. I get this variable from the scroll wheel function, wich looks like this:
Then when I move the camera with WASD it send a line trace from the cameras position straight down. On hit i get distance. This sets the variable Camera Height.
Which kind of works. I got some bugs like sometimes when I go over realy steep and high obstacles it shoots the camera far far away up on the Z axis. After this, all movements on WASD just makes it go further up. So I wanted to try another solution wich uses the Add Movement Input just like I do with X and Y axis. Only this time it would be the Z axis. looks like this:
Not a bug, you are using the visibility channel for the line trace so any tree on the landscape it hits would shoot you up the height of the tree + the set camera distance. if you create a new trace channel in the project settings and use this with the landscape your trace should only hit the landscape.
You could also attach a camera to a spring arm, which automatically handles smooth movement and camera collision, then you again use a custom channel to collide only with the landscape or objects you want to collide with.
I think maybe you can consider a different approach for your implementation. It doesn’t seem like a good idea to calculate the camera’s position in real-time. Instead, you can place an empty component (such as an arrow component) using a blueprint. Then, you can move the camera boom and camera below it accordingly. After that, you only need to manipulate the translation of the arrow and adjust the length of the boom. I apologize for my poor English, but please have a look and understand the general idea.
Yes, I know about that and my intention was to change the channels in a later stage. However the problem is that when i have, say, a set height to 100. I the move my camera to a hill thats 500 units high it mives my camera to 600. But when I move it to a hill thats much higer. Maybe 2000 high, instead of moving to 2100 i get shot up into the air several thousands units high. And WASD stops moving on X and Y and on Z instead, and only up.
I will have a limit on Z movement so in theory it should not colide with the ground. Do you still think it would be a good idea to have a spring arm?
This would just be a bug to debug, doesn’t sound too strange. Could be your trace returns a garbage hit value when it doesn’t hit, or it hits something unexpected. Maybe it even hits itself and shoots up every tick. Make sure the camera doesn’t turn sideways (use absolute values to set rotation, not local / relative, don’t add but set)
Yes because it handles smooth movement and advanced collision out of the box. When the landscape under your trace is at 100 but next to the camera is a mountain at 2000 your spring arm handles the sideways collision as well. It will also not stutter if you enable smooth movement.
You could change a few things. On the last image you are using the UP vector of the pawn, instead of actual “up” from the landscape to the world absolute up. If that pawn rotates it’s not up anymore. Next you are using not the pawn or absolute rotation but the control rotation which can be anything. If you can, use one source to get your direction vectors from.
Also why do you use AddMovementInput as i fwalking with a character before setting the location manually? You could just set the actor location, just make sure not to fall through the landscape (disable gravity). Looks a bit hacky, you could probably just use a pawn and remove AddMovementInput.
I will look into this as others have recommended this as well!
AddMovementInput just came from a tutorial I read. I have now tried implementing the same function with SetActorLocation instead. However I could’t come up with a solution to just use one SetActorLocation, so I have one for X axis and one for Y axis.
As of now I haven’t had time to implement the automatic height adjusting functions so right now I only use my CameraSetHeight value chosen with the scroll wheel. This is what it looks like right now:
Is ther a way to do this with just one SetActorLocation node?
I have tried to find a true world XYZ to use as a reference instead om using the pawns XYZ. But I’m not sure how the get a reference to truew world up. Maby make an static actor used just for referencing true world XYZ?
My reasoning to put the trace to fire while using WASD was to reduce load. It seems excessive to fire a trace every tick if I’m not moving the camera? Regarding the oter features I will need to read a bit but clamp seems like a nice feature I have thought about but diden’t know the name for.
(Current Position + Calculated X addition + Calculated Y Addition) == new position. So right where you add the current position to X you also want to add the calculated Y, then pass that into the SetActorLocation node.
You don’t need to get anything. By default absolute axis is X+ forward Z+ Up Y+ Right. so positive Z goes up. It’s not relative to anything that’s why it is absolute.
ActorPosition + Vector(0, 0, 500)
Tick is fine, otherwise the actor position would never update unless you press a button. Setting position on tick for one controlled pawn is not a heavy operation.