I tried that, the camera just went through walls as if they weren’t there. I wonder if I’m handling camera collision incorrectly.
Here is a potential fix, it works around the problem and lets me keep the rigidbody on the camera holder. I reduce camera movement when the camera hit’s a boundary, then restore the original speed when they exit the boundary.
Cameras shouldn’t generally use physics, because you don’t want them to act like physical objects (banging into things, causing them to move, causing the camera to bounce off, etc.). A camera is invisible and ephemeral, and should just float in the scene wherever needed to give you a good view.
In many games — for example, RTS games — you can limit the camera mathematically, e.g., your map is only so-many by so-many units, so the camera’s point of interest should always stay within those bounds. No physics needed there.
In more complex games, camera control becomes a very deep topic quickly (google “game design camera” and set aside an afternoon for some thoughtful reading). But if you really are in a situation where you have to detect the camera passing through walls, then generally the way to do it is to cast a ray between the camera’s current position and its calculated next position. If that ray hits a wall, then you use that to limit where the camera actually goes.
Okay, so just use basic limits. I’ll post code when I finish, thanks for your expertise. It makes sense to not have any rigidybody on the camera.
The only problem is I’m calling transform.position twice, there’s probably an easy way to combine them, maybe just add them together?
void moveCameraXZ(Vector3 direction)
{
Vector3 movementPosition = direction * Time.deltaTime * (camCurrentMoveSpeed + camBoundaryCollideMoveSpeed);
movementPosition.y = 0;
transform.position += movementPosition;
//get specified percentage of the terrain's width (x)
//example if terrain length is 1024 and specified percentage is 20, then terrainBoundaryLimitX = 204.8
float terrainBoundaryLimitX = myTerrain.terrainData.size.x * terrainBoundaryPercentX / 100;
//get specified percentage of the terrain's length (z)
float terrainBoundaryLimitZ = myTerrain.terrainData.size.z * terrainBoundaryPercentX / 100;
//get the camera's current position in the game world
Vector3 limitTerrainMovement = transform.position;
//ensure the camera's x can only go between a minimum and maximum value
limitTerrainMovement.x = Mathf.Clamp(transform.position.x, terrainBoundaryLimitX, myTerrain.terrainData.size.x - terrainBoundaryLimitX);
//ensure the camera's z can only go between a minimum and maximum value
limitTerrainMovement.z = Mathf.Clamp(transform.position.z, terrainBoundaryLimitZ, myTerrain.terrainData.size.z - terrainBoundaryLimitZ);
//apply boundary terrain limits to the camera
transform.position = limitTerrainMovement;
}
I don’t think there’s anything horrible about assigning to it twice. But you could introduce a local to simplify the code a little.
void moveCameraXZ(Vector3 direction)
{
Vector3 movementPosition = direction * Time.deltaTime * (camCurrentMoveSpeed + camBoundaryCollideMoveSpeed);
movementPosition.y = 0;
Vector3 pos = transform.position + movementPosition;
//get specified percentage of the terrain's width (x)
//example if terrain length is 1024 and specified percentage is 20, then terrainBoundaryLimitX = 204.8
float terrainBoundaryLimitX = myTerrain.terrainData.size.x * terrainBoundaryPercentX / 100;
//get specified percentage of the terrain's length (z)
float terrainBoundaryLimitZ = myTerrain.terrainData.size.z * terrainBoundaryPercentX / 100;
//get the camera's current position in the game world
//ensure the camera's x can only go between a minimum and maximum value
pos.x = Mathf.Clamp(pos.x, terrainBoundaryLimitX, myTerrain.terrainData.size.x - terrainBoundaryLimitX);
//ensure the camera's z can only go between a minimum and maximum value
pos.z = Mathf.Clamp(pos.z, terrainBoundaryLimitZ, myTerrain.terrainData.size.z - terrainBoundaryLimitZ);
//apply boundary terrain limits to the camera
transform.position = pos;
}
I know this is old, but this was my issue, I had to re-stack my player object where the camera was outside of the object with the rigid body component. This also solved some other collision issues as I think the camera was somehow included or something.