1
\$\begingroup\$

I copied a script off the internet and changed it a bit:

void LateUpdate()
{
    if (target)
    {
        x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

        y = ClampAngle(y, yMinLimit, yMaxLimit);

        Quaternion rotation = Quaternion.Euler(y, x, 0);

        RaycastHit hit;
        //Over here is probably where the problem occurs
        if (Physics.Linecast(target.position, transform.position, out hit))
        {
            if (!hit.collider.CompareTag("Player"))
            {
                distance = hit.distance;
            }
        }
        else
        {
            distance = 10f;
        }
        Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
        Vector3 position = rotation * negDistance + target.position;

        transform.rotation = rotation;
        transform.position = position;
    }
}

I made it so that if the RaycastHit's collider is null, that the distance would be reset at 10. Whenever the RaycastHit is hit, it will move the camera distance closer to the player as to get in front of the object blocking the view. All nice and dandy, but when I run the game, when I get in front of and object, it works as planned but it is very stuttery, I have a hunch it has something to do with the if statement for the linecast but I have no idea how to fix it, I tried changing LateUpdate to FixedUpdate and to Update but it still occurs. I'm still new to unity and c# so forgive me if this was a simple mistake.

Here is a video showing it happening: https://www.youtube.com/watch?v=n6ffVmq1UWs

\$\endgroup\$
  • \$\begingroup\$ The Update mode does not influence the result: -Update: update the game logic every frame: -FixedUpdate: used as Update but is better with physics - LateUpdate: runs before the Update method \$\endgroup\$ – user100681 Nov 27 '17 at 12:41
  • 1
    \$\begingroup\$ In order to optimize your script a little bit: Remove the condition if( !PhysicsLinecast .... and keep only the else. Otherwise, you cast two rays instead of one. The 2nd one is useless. And I think if (hit.collider != null) should be removed. The collider will never be null. Otherwise, the Linecast would have not detected it. \$\endgroup\$ – Hellium Nov 27 '17 at 14:27
  • \$\begingroup\$ @Hellium Oh I see, thanks for telling me. Since it is like that, is there any other way to detect if there is nothing behind the camera so it can be set back to the default distance? \$\endgroup\$ – Voon Van Eustace Nov 27 '17 at 14:32
3
\$\begingroup\$

I am not sure at all about the following.

Instead of Linecasting between the current position of the camera and the target, I would linecast between the desired position and the target.

void LateUpdate()
{
    if (target)
    {
        // Reset to the desired distance
        distance = 10 ;
        // OR the following line if you want smoother reset
        // distance = Mathf.Lerp(distance, 10, Time.deltaTime * 5);

        // Rotate according to mouse position
        x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

        y = ClampAngle(y, yMinLimit, yMaxLimit);

        Quaternion rotation = Quaternion.Euler(y, x, 0);

        // Compute the desired position
        Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
        Vector3 position = rotation * negDistance + target.position;

        RaycastHit hit;

        // Check if there is an obstacle between the desired position
        // and the target
        if (Physics.Linecast(target.position, position, out hit) && !hit.collider.CompareTag("Player"))
        {
            // Obstacle detected !
            // Computing the new position so that
            // the object is on the other side of the obstacle
            distance = hit.distance;
            negDistance = new Vector3(0.0f, 0.0f, -hit.distance);
            position = rotation * negDistance + target.position;
        }

        // Placing the object
        transform.rotation = rotation;
        transform.position = position;
    }
}
\$\endgroup\$
  • \$\begingroup\$ It didn't work, still stuttery, im starting to think using a linecast was a bad idea, should i use a collider instead? \$\endgroup\$ – Voon Van Eustace Nov 27 '17 at 14:44
  • \$\begingroup\$ It seems to work fine here. I've just forgotten to reset distance to 10 before assigning the other values (answer updated) \$\endgroup\$ – Hellium Nov 27 '17 at 14:51
  • \$\begingroup\$ That did the trick, thank you so much. Please do explain to me what you did and why. \$\endgroup\$ – Voon Van Eustace Nov 27 '17 at 14:58
  • \$\begingroup\$ Glad it worked. As I indicated, I compute the desired position first. I call Linecast to check if I can place the camera at the desired location. If not, I place the camera at the collision point, like you did in your original script. \$\endgroup\$ – Hellium Nov 27 '17 at 15:01
  • 1
    \$\begingroup\$ Comments added to my answer ;) \$\endgroup\$ – Hellium Nov 27 '17 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.