Hello,
I hope someone here can help me. I want to implement a camera that can switch between 3rd person view (orbit camera) and a free moving mode (like in League of Legends but in 3 dimensional space) by pressing a button. In the free moving mode the camera should behave like it does in the Scene View of Unity.
I use the Freelook Camera from Cinemachine because of the orbit mode.
However, when I put the camera in 3rd person view and then set it back to free moving, it does some weird things. The Main Camera rotates on the Z-axis (although I explicitly set the Z-axis of the Freelook Camera to 0), which causes it to move sometimes mirrored. What am I doing wrong?
My code: (component of the freelook camera)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Cinemachine;
using TMPro;
public class FreeMovingCamControl : MonoBehaviour
{
[Header("Rotation speed")]
public float speedH;
public float speedV;
[Header("Movement speed")]
public float movementSpeed;
[Header("Scrolling speed")]
public float scrollSpeed;
[Header("Player transform")]
public Transform olaf;
private float horizontal;
private float vertical;
private Vector3 newPos;
private Vector3 newRot;
private CinemachineFreeLook cinemachine;
[Header("UI")]
public bool cameraLocked = true;
public TextMeshProUGUI btText;
void Awake()
{
// Initialize variables
horizontal = speedH;
vertical = speedV;
cinemachine = transform.GetComponent<CinemachineFreeLook>();
if (cameraLocked)
{
LockCam();
}
else
{
UnlockCam();
}
}
void Update()
{
if (cameraLocked) // orbit camera
{
if (Input.GetKeyDown("space"))
{
UnlockCam();
}
if (Input.GetMouseButton(1))
{
cinemachine.m_XAxis.m_InputAxisName = "Mouse X";
cinemachine.m_YAxis.m_InputAxisName = "Mouse Y";
}
else
{
cinemachine.m_XAxis.m_InputAxisName = "";
cinemachine.m_YAxis.m_InputAxisName = "";
cinemachine.m_XAxis.m_InputAxisValue = 0;
cinemachine.m_YAxis.m_InputAxisValue = 0;
}
float zoom_direction = Math.Sign(Input.GetAxis("Mouse ScrollWheel"));
if (zoom_direction != 0f) // forward
{
cinemachine.m_Orbits[0].m_Height -= zoom_direction * scrollSpeed;
cinemachine.m_Orbits[1].m_Radius -= zoom_direction * scrollSpeed;
cinemachine.m_Orbits[2].m_Height += zoom_direction * scrollSpeed;
}
}
else
{
if (Input.GetKeyDown("space"))
{
LockCam();
}
if (Input.GetMouseButton(1)) // right mouse button pressed -> rotate camera
{
horizontal += speedH * Input.GetAxis("Mouse X");
vertical -= speedV * Input.GetAxis("Mouse Y");
transform.eulerAngles = new Vector3(vertical, horizontal, 0.0f);
}
else // prevent rotating camera without clicking any button (just cinemachine stuff that happens otherwise)
{
cinemachine.m_XAxis.m_InputAxisName = "";
cinemachine.m_YAxis.m_InputAxisName = "";
cinemachine.m_XAxis.m_InputAxisValue = 0;
cinemachine.m_YAxis.m_InputAxisValue = 0;
}
if (Input.GetMouseButton(2)) // mouse wheel pressed -> move camera upwards or sideways
{
newPos = transform.position;
newPos.y -= speedV * Input.GetAxis("Mouse Y");
transform.position = newPos;
//transform.Translate(-Camera.main.transform.right * Input.GetAxisRaw("Mouse X") * movementSpeed, Space.World);
transform.Translate(-transform.right * Input.GetAxisRaw("Mouse X") * movementSpeed, Space.World);
Debug.Log("Camera main: " + Camera.main.transform.right);
Debug.Log("Freelook: " + transform.right);
}
float zoom_direction = Math.Sign(Input.GetAxis("Mouse ScrollWheel")); // positive -> 1, negative -> -1, zero -> 0
if (zoom_direction != 0f) // scrolling moves camera forwards or backwards
{
transform.Translate(Camera.main.transform.forward * scrollSpeed * zoom_direction, Space.World);
}
}
}
public void UnlockCam()
{
cameraLocked = false;
btText.text = "cam free";
cinemachine.m_Follow = null;
cinemachine.m_LookAt = null;
cinemachine.GetComponent<CinemachineCollider>().enabled = false;
}
public void LockCam()
{
horizontal = transform.forward.y;
vertical = transform.forward.x;
cameraLocked = true;
btText.text = "cam locked";
cinemachine.m_Follow = olaf;
cinemachine.m_LookAt = olaf;
transform.eulerAngles = Vector3.zero;
cinemachine.GetComponent<CinemachineCollider>().enabled = true;
}
public void OnButtonClick()
{
if (cameraLocked)
{
UnlockCam();
}
else
{
LockCam();
}
}
}