Smooth camera movement by mouse
Hello everyone. I'm learning to code with Unity. I started creating a simple 2D game for learning purposes. I want to make camera move around mouse like in mobile games, i.e. you grab the screen (with RMB in my case), you drag the mouse cursor across the screen and the image moves as if you grabbed the camera. Implementing just that was simple, but making it linearly interpolated with inertia (that is if you moved your mouse too far and then released the mouse half way to the destination, it still moves even without mouse grabbing).
So here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CircleControl : MonoBehaviour
{
public float speed = 20f;
private Rigidbody2D rb;
private bool movedSinceCameraDisplaced = false;
private Vector3 mousePositionA;
private bool cameraMoveInertia;
private Vector3 finalPosition;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.A)) {
movedSinceCameraDisplaced = true;
rb.AddForce(-Vector2.right * speed * Time.deltaTime * 1000);
}
if (Input.GetKey(KeyCode.D)) {
movedSinceCameraDisplaced = true;
rb.AddForce(Vector2.right * speed * Time.deltaTime * 1000);
}
}
void FixedUpdate() {
if (Input.GetMouseButtonDown(1)) {
// displace the camera by mouse
mousePositionA = Camera.main.ScreenToWorldPoint(Input.mousePosition);
movedSinceCameraDisplaced = false;
cameraMoveInertia = true;
}
if (cameraMoveInertia) {
// displace the camera by mouse
cameraMoveInertia = true;
var newOriginalPos = Camera.main.transform.position;
if (Input.GetMouseButton(1)) {
Vector3 mousePositionB = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 mouseDisplacementVector = mousePositionB - mousePositionA;
finalPosition = newOriginalPos - mouseDisplacementVector;
}
var newPos = Vector3.Lerp(newOriginalPos, finalPosition, Time.deltaTime * 8f);
newPos.z = 0;
var newPosMagnitude = newPos.magnitude;
newPos.z = -10;
Camera.main.transform.position = newPos;
if (newPosMagnitude > 0f && (newPos - finalPosition).magnitude <= 0.05f) {
Camera.main.transform.position = finalPosition;
cameraMoveInertia = false;
}
}
if (movedSinceCameraDisplaced) {
// center camera around the player
var pos = Vector3.Lerp(Camera.main.transform.position, transform.position, Time.deltaTime * 10f);
pos.z = -10;
Camera.main.transform.position = pos;
}
}
}
You attach this script to, say, a sprite, and the camera starts moving. What doesn't work as expected is that it works only for the first time. The second time you try to grab the camera - it doesn't work. I suspect the reason of that is Vector3.Lerp function makes the first movement 0 units away, so the check performed ((newPos - finalPosition).magnitude <= 0.05f) assumes that the camera went to it final destination and stops the movement. Maybe there is a built-in script or function or class that can help to make it work.
Thanks to anyone in advance!
Your answer
Follow this Question
Related Questions
Camera Movement Question - How to follow player in Y axis only above certain threshold? 0 Answers
please help i am geting error cs1061 1 Answer
Vector2 MoveTowards weird behaviour? 1 Answer
Reset for countdown timer - Game Quiz 0 Answers
When playing builded version of game the cameras only captures part of scene. 0 Answers