Paolo Sito
Paolo Sito

Reputation: 31

Camera collision detection

I'm having trouble with my Camera script. The Camera rotates around the player by using a pivot that's assigned as a child of the camera. This works with 2 arrows (I'm developing this game for mobiles, so they're touch arrows) that allow the camera to rotate left and right.

The problem is when the Camera goes behind a wall or a huge object and can't see anything. I looked for a solution and I see that many developers used the RaycastHit or something similar.

Here's my code, the goal is to get the Camera to go closer to the pivot when near a wall in order to avoid blocking the Camera view. Can anyone help me?

public Transform target1;
public Transform pivot;

protected ButtonLeft buttonLeft;
protected ButtonRight buttonRight;

public Vector3 offset;
public bool useOffsetValues;

public float rotateSpeed;  

private void Start()
{
    buttonLeft = FindObjectOfType<ButtonLeft>();
    buttonRight = FindObjectOfType<ButtonRight>();

    if (!useOffsetValues)
    {
        offset = target1.position - transform.position;
    }

    pivot.transform.position = target1.transform.position;

    //pivot.transform.parent = target.transform;

    //USE IF U WANT TO DISAPPEAR THE CURSOR
    //Cursor.lockState = CursorLockMode.Locked;

    //pivot.transform.parent = target.transform;
    pivot.transform.parent = null;

    // usa questa dopo la costruzione del livello1
    //pivot.transform.position = target.transform.position;
}

private void Update()
{
    pivot.transform.position = target1.transform.position;

    if (buttonLeft.Pressed)
    {
        pivot.Rotate(0, -90 * Time.deltaTime, 0);
        Debug.Log("rotate left");
    }

    if (buttonRight.Pressed)
    {
        pivot.Rotate(0, 90 * Time.deltaTime, 0);
        Debug.Log("rotate left");
    }

    Ray ray = new Ray(pivot.transform.position, pivot.transform.position - transform.position);
    RaycastHit hit;

    /*float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
    float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
    pivot.Rotate(0, horizontal, 0);
    pivot.Rotate(0, horizontal, 0);
    Use this to make the camera rotate on Mouse Y axes*/
    /*float vertical = Input.GetAxis("Mouse Y") * rotateSpeed;
    target.Rotate(vertical, 0, 0); */

    //move camera based on the current rotation of the target and the original offset

    float desiredYAngle = pivot.eulerAngles.y;
    //Use this float to set the x angle of player
    float desiredXAngle = pivot.eulerAngles.x;
    //Use this rotation only if you want to rotate on Y
    //Quaternion rotation = Quaternion.Euler(0, desiredYAngle, 0);
    //Use this if u want to rotate up&down on x axes
    Quaternion rotation = Quaternion.Euler(desiredXAngle, desiredYAngle, 0);
    transform.position = target1.position - (rotation * offset);

    //transform.position = target.position - offset;

    transform.LookAt(target1);
}

Upvotes: 1

Views: 792

Answers (1)

Mykhailo Khadzhynov
Mykhailo Khadzhynov

Reputation: 467

Good approach is when you do raycast from pivot to camera, and, if some obstacle found, put camera on a ray, a bit closer to pivot, than hit point. Like this: (pseudocode, not tested):

Vector3 origin =  pivot.transform.position;
Vector3 direction = transform.position - pivot.transform.position;

float maxCameraDistance = 10;

Ray ray = new Ray(origin, direction);
RaycastHit hit;
if (Physics.Raycast(ray, maxCameraDistance))
{
    Vector3 offsetFromObstacle = -direction.normalized * 0.1f;
    transform.position = hit.point + offsetFromObstacle;
}

Upvotes: 1

Related Questions