0
\$\begingroup\$

I want to grab my terrain and move the camera with my mouse, this was fairly simple to do using speed:

Code (CSharp):

newPosition = transform.position; //Set in Start
//...
 
// In update
newPosition -= new Vector3(Input.GetAxis("Mouse X") * cameraDragSpeed, 0, Input.GetAxis("Mouse Y") * cameraDragSpeed);
transform.position = Vector3.Lerp(transform.position, newPosition, GameManager.Instance.GetNormalizedTimescale() * acceleration);

But I dont want to use speed, I want to use the difference between the drag origin (or the last drag position) and the new drag position.

I got some code running that oddly work "kind of" well, but has periods where it starts acting rly strangly, like the camera will keep panning while I hold down my button, even tho im not moving the mouse. But it happens very randomly. Or sometimes the drag speed is really responsive but other times its like im dragging in mud.

Code (CSharp):

// In update
// Drag movement
            if (Input.GetMouseButtonDown(1))
            {
                cameraMovementDragOrigin = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
            }
            else if (Input.GetMouseButton(1))
            {
                var diff = cameraMovementDragOrigin - new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
                newPosition += new Vector3(diff.x, 0, diff.y);
                transform.position = newPosition;
                return;
            }

Can someone spot what im doing wrong?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This should help you out. Put it on the camera.

using System;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CameraDragMove : MonoBehaviour
{
    [SerializeField] private float sensitivity = 1f;
    [SerializeField] private float lerpT = 0.5f;
    
    private Camera _camera;
    
    private Vector3 _initialMousePosOnXZPlane = Vector3.zero;
    private Vector3 _initialCameraPos = Vector3.zero;
    private Vector3 _desiredPos = Vector3.zero;

    private void Start()
    {
        _camera = GetComponent<Camera>();
        _desiredPos = transform.position;
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
            _desiredPos = transform.position;
            _initialCameraPos = transform.position;
            _initialMousePosOnXZPlane = GetMousePositionOnXZPlane();
        }
        else if (Input.GetMouseButton(1))
        {
            var mouseDeltaOnXZPlane = _initialMousePosOnXZPlane - GetMousePositionOnXZPlane();
            _desiredPos = _initialCameraPos + mouseDeltaOnXZPlane * sensitivity;
        }
    }

    private void LateUpdate()
    {
        transform.position = Vector3.Lerp(transform.position, _desiredPos, lerpT);
    }

    private Vector3 GetMousePositionOnXZPlane()
    {
        return GetScreenPointOnPlane(Vector3.up, Vector3.zero, Input.mousePosition);
    }

    private Vector3 GetScreenPointOnPlane(Vector3 planeNormal, Vector3 planeOrigin, Vector3 screenPoint)
    {
        var plane = new Plane(planeNormal, planeOrigin);
        var mouseRay = _camera.ScreenPointToRay(screenPoint);
        if (plane.Raycast(mouseRay, out var hitDistance))
        {
            return mouseRay.GetPoint(hitDistance);
        }

        throw new Exception("Invalid raycast");
    }
}

Here is a diagram that explains what this script is doing:

Diagram

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .