Stop camera from going trough walls
Asked Answered
H

8

0

I am making a third person shooter. And a want the camera to follow behind the player. But i dont want the camera to pass trough walls, when the player stands with his back close to a wall. How can i achive this?

Hom answered 6/6, 2023 at 1:17 Comment(0)
M
0

Off the top of my head:

Put a collider on the camera (sphere or box). Make sure you make a physics material with no friction, and add it to the collider (so the camera doesnt slow down when it hits, say, a wall, due to drag). Then add a script to the camera along the lines of this (psuedocode, wont actually work):

if the camera collides with something

lerp camera in Z direction towards playerObject to minimum distance from playerObject (that way camera never goes through playerObject)

if camera is at minimum distance, lerp opacity of playerObject material to 30% (so player doesnt block view of environment)

if camera exits collision

lerp camera in Z direction away from playerObject to maximum distance from player
lerp playerObject material opacity to 100%

Hope this is helpful.

Musty answered 21/6, 2023 at 10:39 Comment(0)
M
0

The simplest answer is to just put a collision sphere around your camera, but check out the Lerps tutorial for a complete 3rd person camera system.

Malediction answered 6/6, 2023 at 0:58 Comment(1)

Could you give me a link to the Lerps tutorial you are referring to?

Hom
M
0

In the Unity Scripting Forums, there's a topic about a World of Warcraft type control scheme that might work for you. A few people worked on a problem just like this with their camera so that it won't go through walls and follows the terrain or objects that get in the way, always keeping the character in view.

Maybe It'll help you,

http://forum.unity3d.com/viewtopic.php?t=18073&highlight=wow

Malediction answered 9/4, 2010 at 3:17 Comment(2)

I tryed it, but it isn't relay the effect im looking for. I want the camera to always be directly behind the player. And only get pushed closer the the player when it collides with a wall, and only be pushed directly towards the player and not sideways. How can i achieve this result?

Hom

Wow camera is now located here: http://forum.unity3d.com/threads/wow-camera-movement.16949/

Maimaia
M
0

Off the top of my head:

Put a collider on the camera (sphere or box). Make sure you make a physics material with no friction, and add it to the collider (so the camera doesnt slow down when it hits, say, a wall, due to drag). Then add a script to the camera along the lines of this (psuedocode, wont actually work):

if the camera collides with something

lerp camera in Z direction towards playerObject to minimum distance from playerObject (that way camera never goes through playerObject)

if camera is at minimum distance, lerp opacity of playerObject material to 30% (so player doesnt block view of environment)

if camera exits collision

lerp camera in Z direction away from playerObject to maximum distance from player
lerp playerObject material opacity to 100%

Hope this is helpful.

Musty answered 21/6, 2023 at 10:39 Comment(0)
C
0

The code for this is simple:

Have your camera code track the desired location behind the player (where the camera should be if there are no obstructions), the desired location is not necessarily where you want the camera to be on a given frame. Rather you calculate the position between the desired location and the player that is unobstructed by any walls using a Raycast or RaycastAll (depending on whether or not you'll potentially have multiple obstructing objects between the camera and player).

Here's some sample c# code:

RaycastHit hit;
Vector3 targetPosition;

if (Physics.Raycast(desiredPosition, playerTransform.position - desiredPosition, out hit, (playerTransform.position - desiredPosition).magnitude, wallLayers))
{
    targetPosition = (hit.point - playerTransform.position) * 0.8f + playerTransform.position;
    /* 
       Note that I move the camera to 80% of the distance
       to the point where an obstruction has been found
       to help keep the sides of the frustrum from still clipping through the wall
    */
}
else
{
    targetPosition = desiredPosition;
}

In the sample code:

  • desiredPosition is the world space position that the unobstructed camera would be placed at

  • playerTransform is the Transform component of the player character the camera is following

  • wallLayers is a LayerMask that contains the layer with all of the wall colliders in it

  • targetPosition is the point in world space that the Camera will actually be moved to.

Cabbage answered 5/9, 2010 at 17:33 Comment(1)

targetPosition = (hit.point - playerTransform.position) 0.8f + playerTransform.position; not really sure what to do with this line of code is not even valid code...

Baras
M
0

try this:- http://blockmonkey.com/my-work/unity-3d-work/

Master answered 24/2, 2011 at 13:11 Comment(0)
A
0

I found the easiest fix for this! If you use the standard FPS Controller, just go to the camera and under Clipping Planes, change the property : Near to 0.01!!! And it’s fixed, just saw it a while ago, Easy as 1… 2… 3!! Hope it helps!

-Roman

Ammonify answered 6/6, 2023 at 1:21 Comment(0)
A
0

The correct way would be to:

  1. Determine where would you ideally have your camera if there were no walls
  2. Raycast the world from your player (or camera focus point) to the desired camera position, with the ray max. length equals the distance from focus to desired point.
  3. Simply put the camera at the raycast hit point if it hit something: raycast gives you distance result. So simple formula is: camPos = focusPos + rayDirection*(hitDistance - wallOffset); add wallOffset so the camera doesn’t end up stuck right on the wall, but slightly further of it
Amorous answered 1/4, 2016 at 8:57 Comment(0)
W
0

Try this, I tested it a couple times and it works well :wink:

(In case the camera mistakes the player as an object, use the inverse on the layermask variable)

The First script is the camera script that detects the object that hits the camera

The normal point is the original point of the camera;
Player max is the distance of the player from the camera

public Transform NormalPoint, PlayerMax, ThCam;
public float moveSpeed;
public float distance;
public CameraTriggerFix CTF;

public int layerMask = (1 << 8);

void Update()
{

    distance = Vector3.Distance(ThCam.position, PlayerMax.position);

    Vector3 fwd = transform.TransformDirection(Vector3.forward);

    if (Physics.Raycast(this.transform.position, fwd, 10))
    {
        CTF.gameObject.GetComponent<Collider>().enabled = true;
        ThCam.position = Vector3.Lerp(ThCam.position, PlayerMax.position, moveSpeed * Time.deltaTime);
        print("There is something in front of the object!");
    }
    else
    {
        CTF.gameObject.GetComponent<Collider>().enabled = false;
        ThCam.position = Vector3.Lerp(ThCam.position, NormalPoint.position, moveSpeed * Time.deltaTime);
    }
}

Attach the camera script to the camera then add a sphere collider to the cam, check isTrigger to true and a rigid-body and make sure to set gravity to false. After you’ve done that, add the next script underneath this to the camera. This script improves the accuracy and the how long the camera has to stay on that object.

 public CameraProtectionScript CHD;
    public bool Enter;


    private void OnTriggerEnter(Collider other)
    {
        if (other.tag != "Untagged")
        {
            CHD.ThCam.position = Vector3.Lerp(CHD.ThCam.position, CHD.PlayerMax.position, CHD.moveSpeed * Time.deltaTime);
            Enter = true;
            CHD.enabled = false;
        }
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.tag != "Untagged")
        {
            CHD.ThCam.position = Vector3.Lerp(CHD.ThCam.position, CHD.PlayerMax.position, CHD.moveSpeed * Time.deltaTime);
            Enter = true;
            CHD.enabled = false;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.tag != "Untagged")
        {
            CHD.enabled = true;
            Enter = false;
            this.GetComponent<Collider>().enabled = false;
        }
    }

Hope this helps ;)!

Westney answered 8/4, 2017 at 23:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.