Oliver Hostettler
Oliver Hostettler

Reputation: 1

Using Ray and RayCast to look around in first person

I am currently working on a small project where you controll the character in first person mode, allthough this question is also relevant for third person. What I want to do is looking around by just moving the mouse over the screen, like in any kind of first person game. My problem is that with the methods I tried so far, the camerea always continues turning when the cursor is just slightly off center.

I created a method called LookWithMouse on my PlayerBehaviour script. Here the first try:

private void LookWithMouse()
{
    Vector2 mousePos = Input.mousePosition;
    Ray ray = _camera.ScreenPointToRay(mousePos);
    Debug.DrawRay(ray.origin, ray.direction);
    Plane plane = new Plane(Vector3.up, this.transform.position);

    float distanceToPlane;

    if (plane.Raycast(ray, out distanceToPlane))
    {
        Vector3 hitPoint = ray.GetPoint(distanceToPlane);

        this.transform.LookAt(hitPoint);

        Debug.DrawLine(ray.origin, hitPoint, Color.yellow);
    }
}

Here I tried casting a ray from the camera and interscting it with a plane. Besides the problem of the constantly moving camera there is the issue that it only works as long as I dont look up. because the plane is only on the floor.

Here the other try:

private void LookWithMouse()
{
    Vector2 mousePos = Input.mousePosition;
    Vector3 point = _camera.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, _camera.nearClipPlane));
    Vector3 direction = (_camera.transform.position - point) * -1;
    Debug.Log($"Direction: {direction}");

    int layerMask = 1 << 2;
    layerMask = ~layerMask;


    RaycastHit hit;
    if (Physics.Raycast(_camera.transform.position, direction, out hit, Mathf.Infinity, layerMask))
    {
        Debug.DrawRay(_camera.transform.position, direction * hit.distance, Color.yellow);
        Debug.Log("Did Hit");
        hitPoint = hit.point;
        Debug.Log($"Hit point: {hit.point}");
    }
    this.transform.LookAt(hitPoint);
    }

Here I cast a ray and let it collide with colliders I set up around my world. This way I can look in every direction but the camera doesnt stop moving.

Another attempt which uses the GetAxis() method. I copied this script from someone online:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLook : MonoBehaviour
{
    public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
    public RotationAxes axes = RotationAxes.MouseXAndY;
    public float sensitivityX = 15F;
    public float sensitivityY = 15F;

    public float minimumX = -360F;
    public float maximumX = 360F;

    public float minimumY = -60F;
    public float maximumY = 60F;

    float rotationY = 0F;

    void Update()
    {
        if (axes == RotationAxes.MouseXAndY)
        {
            float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;

            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
        }
        else if (axes == RotationAxes.MouseX)
        {
            transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
        }
        else
        {
            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
        }
    }

    void Start()
    {
        // Make the rigid body not change rotation
        if (GetComponent<Rigidbody>())
            GetComponent<Rigidbody>().freezeRotation = true;
    }
}

Can anyone help?

Upvotes: 0

Views: 44

Answers (0)

Related Questions