- Home /
How to prevent a 3rd person camera from clipping into terrain
i have a third person shooter game and when you are running down a hill or falling off a mountain the camera goes inside the terrain... any ideas on how to fix i also tried adding a box collider i dont know if it mattered but the collider didnt work
Answer by spinaljack · Aug 21, 2010 at 01:07 PM
Use a ray cast to determine the distance to the camera from the target point. If the ray hits an object between the camera and the target point then move the camera closer to the target.
e.g.
function Update(){
var relativePos = transform.position - (target.position);
var hit : RaycastHit;
if (Physics.Raycast (target.position, relativePos, hit, distance+0.5)) {
Debug.DrawLine(target.position,hit.point);
distanceOffset = distance - hit.distance + 0.8;
distanceOffset = Mathf.Clamp(distanceOffset,0,distance);
}else{
distanceOffset = 0;
}
}
Clamp the distance offset so that it's never a negative number.
Distance is the normal distance of the camera from the target point.
The 3rd Person camera script:
function LateUpdate () {
// view zoom
distance-=Input.GetAxis("Mouse ScrollWheel")*zoomSpeed;
if(distance<1)
distance = 1; // max zoom
if(distance>6)
distance = 6; // min zoom
if (target) {
x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;
y = ClampAngle(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * Vector3(0.0, 0.0, -distance+distanceOffset) + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
You'll want to change the figures to match your near clip plane on your camera.
can you please convert this to C# . Im trying to do it myself but I get lots of errors since im not that good at scripting
Are you still interested in converting this to C#? Or did you figure it out?
Answer by RocketFriday · Jan 11, 2018 at 10:28 PM
I converted the script to C# for anyone who wants it. I made a script called TestCamera and attached it to my Camera, set the player as the target. It's kinda glitchy, I suspect something in the last 5 lines of code. It's not perfect but with some minor tweaking should point you in the right direction.
public class TestCamera : MonoBehaviour {
Vector3 relativePos;
public Transform target;
public float distance = 3f;
public float distanceOffset;
public float zoomSpeed = 2f;
public float xSpeed = 300f;
public float ySpeed = 300f;
public float yMinLimit = 50f;
public float yMaxLimit = 180f;
void Update()
{
relativePos = transform.position - (target.position);
RaycastHit hit;
if (Physics.Raycast(target.position, relativePos, out hit, distance + 0.5f))
{
Debug.DrawLine(target.position, hit.point);
distanceOffset = distance - hit.distance + 0.8f;
distanceOffset = Mathf.Clamp(distanceOffset, 0, distance);
}
else
{
distanceOffset = 0;
}
}
//Clamp the distance offset so that it's never a negative number.
//Distance is the normal distance of the camera from the target point.
//The 3rd Person camera script:
void LateUpdate()
{
// view zoom
distance -= Input.GetAxis("ScrollWheel") * zoomSpeed;
if (distance < 1)
distance = 1; // max zoom
if (distance > 6)
distance = 6; // min zoom
if (target != null)
{
float x = Input.GetAxis("MouseX") * xSpeed * 0.02f;
float y = Input.GetAxis("MouseY") * ySpeed * 0.02f;
y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * new Vector3(0.0f, 0.0f, -distance + distanceOffset) + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
//You'll want to change the figures to match your near clip plane on your camera.
}
Its glitch because you are using mathf.clamp on a rotation check this link out.link text
Good to know, but I just converted what was posted above to C#. Thanks for the info tho!
Also for the raycast direction do the Camera's negative transform.forward.
Answer by hydrix · Feb 02, 2018 at 04:52 PM
This is working flawlessly for me. Camera is setup so that the scroll movement changes the camera's z localposition, so setting that variable directly controls how far the camera is from the is from the player.
RaycastHit ray;
public float clipOffset = 0.1f;
public Vector3 clipCheckOffset = new Vector3(0,1,0);
void Update() {
Debug.DrawRay(camera.transform.position, (
(player.transform.position + clipCheckOffset) -
camera.transform.position));
if (
Physics.Raycast(camera.transform.position, ( player.transform.position + clipCheckOffset) -
camera.transform.position, out ray, -camera.transform.localPosition.z - 0.5f,
worldLayerMask)
)
{
camera.transform.position = ray.point + ((player.transform.position + clipCheckOffset) -
camera.transform.position).normalized * clipOffset;
Debug.Log("hit something");
}
}
RaycastHit ray;
Player player;
Layer$$anonymous$$ask worldLayer$$anonymous$$ask;
public float clipOffset = 0.1f;
public Vector3 clipCheckOffset = new Vector3(0, 1, 0);
void Update()
{
Debug.DrawRay(GetComponent<Camera>().transform.position, (
(player.transform.position + clipCheckOffset) -
GetComponent<Camera>().transform.position));
if (
Physics.Raycast(GetComponent<Camera>().transform.position, (player.transform.position + clipCheckOffset) -
GetComponent<Camera>().transform.position, out ray, -GetComponent<Camera>().transform.localPosition.z - 0.5f,
worldLayer$$anonymous$$ask)
)
{
GetComponent<Camera>().transform.position = ray.point + ((player.transform.position + clipCheckOffset) -
GetComponent<Camera>().transform.position).normalized * clipOffset;
Debug.Log("hit something");
}
}
An update for the current unity. I think this works well for terrain but not for building walls
What do you mean by 'scroll' movement ,- did you mean to say rotation ?
ty
no, scrolling the mousewheel moves the camera further or closer to the player on my setup. The camera is a child of something on the player so I can use mycamera.transform.localPosition to do that.
O$$anonymous$$ even better, using that which is often used in so many games is so handy, thx for verify! Just to be clear, does this so as OP requested a year+ ago, to make sure camera doesn't clip through terrain ( maybe not walls) , OR just the mouse zoom thing..
I could use both, but mainly I wanted to stop clipping.
Answer by junctionboss · Oct 01, 2014 at 03:10 AM
sorry but I'm tad new at knowing where to copy /paste. WIll this work with the free look camera rig. I could never get the 3d person ( plumber guy) character controlller to rotate camera corectly using cursor keys which I prefer using.
So what goes where here,,I tried copy pasting '3rd person camres script' code you have here, and I got compiler errors:
Assets/Sample Assets/Cameras/Scripts/clippingfix.cs(4,14): error CS0101: The namespace global::' already contains a definition for NewBehaviourScript'
thx jb
Firstly, you shouldn't post questions as answers, add a comment ins$$anonymous$$d.
Secondly, you're getting the error because you must have another script with the same namespace.
Namespaces are the names of classes inside the script. They are found immediately after Using: UnityEngine; Etc.
The Namespace $$anonymous$$UST match the actual name of the script in the project view of the unity editor.
Posting with diff. nick, but its still me ofc:
Hi , I stopped using Unity for a time, but back- what did you mean I must have 'another' script.. I get the description of namespace and matching names etal , great advice for artist who is coder in training, I think going well enough.
thx
All namespaces must match with only the file that contains them. So it is likely that the FILE is named "clippingfix.cs" but the namespace of that file is named "NewBehaviourScript" or something else.
OR you have a script somewhere with the two of the same namespaces but different file names. Seen here
Answer by Silvermurk · May 06, 2016 at 09:01 AM
Here`s a link on makeing camera, controller and a terrain-collision avoiance. http://www.3dbuzz.com/training/view/3rd-person-character-system
Your answer
Follow this Question
Related Questions
weird texture distortion 0 Answers
Screen.lockCursor Acting Irregular 2 Answers
Glitching model edges from blender to unity texture? 1 Answer
Strange Glitch Whenever I First Open Unity 0 Answers
Grass water delete underneath? 0 Answers