The functions of unity Camera camera component and cinemachine camera component realize lens angle rotation, panning, zooming, position reset, automatic obstacle avoidance, multi-camera switching and other related setting skills

Note: Each function in this article is implemented using cinemachine and camera components respectively, please extract as needed. If you have any questions, please leave a message below and I will answer them. In addition, it is not a loss to add attention to you, is it? . This article will update other functions on January 5, 2021

1. Smooth switching of multiple cameras

When there are multiple virtual cameras in the scene, closing the current main virtual camera will smoothly switch to all cameras with higher priority values ​​in the open state. That is to say, when a camera is turned off and a camera is turned on at the same time, the lens will pan smoothly.

Implementation of FreeLocckCam and Camera

//先停再开,可以在权值相同且同时开启的情况下切换相机
//FreeLocckCam、Camera都可以使用这种方式
camerObject.SetActive (false)
camerObject.SetActive (true)

Switching speed and smooth curve can be set in the inspector

2. Reset the camera

Resetting the camera includes resetting the position, viewing angle, and viewing distance

Camera component implementation

public void ResetCamera(){
    
    
	// 重置视距
	this.Camera.main.OrthographicSize = this.defaultViewScale;
	this.Camera.main.FieldOfView = this.defaultViewScale;
	// 重置位置
	this.Camera.main.tansform.position = this.defaultPos;
	this.Camera.main.tansform.rotation = this.defaultRot;
}

Implementation of FreeLookCam component

Since freelook has its own look-around coordinate system, it is necessary to reset not only the camera but also the related parameters of the freelook component

public void ResetCamera(){
    
    
	// 重置角度
	//将binding mode改为LockToTargetWithWorldUp
	freeLookCam.PreviousStateIsValid = false;
	freeLookCam.m_XAxis.Value = 0;
	freeLookCam.m_YAxis.Value = 0.5f;
	//如果X轴位置有问题,请查看heading>bias值
	// 重置视距
	this.mainCineCamera.m_Lens.OrthographicSize = this.defaultViewScale;
	this.mainCineCamera.m_Lens.FieldOfView = this.defaultViewScale;
	// 重置位置
	this.mainCineCamera.LookAt.tansform = this.LookAtDefaultPos;
	this.mainCineCamera.Follow.transform = this.followDefalutPos;
}

3. Rotation Angle of View

There are two ways to rotate the viewing angle, one is to look around the camera itself as the center. The other is centered on the target, and the camera rotates around the target.

Rotate around a target with FreeLookCam

First add the freelookCam component in the scene, and then set the follow object and lookat object in the inspector. The follow object refers to the origin of the camera as it rotates around the object. Lookat refers to the position where the lens is focused. No matter how you rotate it, the camera will always face the object.
The height and radius of this rotation range can be set in the top, middle, and buttom of the inspector

	public float rotateAxisSpeed_x = 3f;
    public float rotateAxisSpeed_y = 3f;
    public void RotateAxis(float x, float y)
    {
    
    
        mainCineCamera.m_XAxis.m_InputAxisValue = x * rotateAxisSpeed_x;
        mainCineCamera.m_YAxis.m_InputAxisValue = y * rotateAxisSpeed_y;
    }
    void Update(){
    
    
     	float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        this.RotateAxis(h,v);
    }

4. Pan perspective

The so-called panning angle of view is to perform a relative panning operation on the camera under the current angle of view of the camera.

Camera component implementation


    public float moveSpeedXY = 10f;
    // 以前后移动速度
    public float moveSpeedZ = 60f;

    void Update()
    {
    
    
        // 获取水平及滚轮按键值 区间为 0-1f
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float mouse = Input.GetAxis("Mouse ScrollWheel");
        //调用平移的方法
        transform.Translate(new Vector3(h * moveSpeedXY, v * moveSpeedXY, mouse * moveSpeedZ) * Time.deltaTime, Space.Self);
    }

Implementation of FreeLocckCam component

There are two situations to consider when using this component:

1 There is a situation where there is no target to follow

This implementation is relatively simple, similar to the implementation using the Camera component above, only that it is not the camera itself that needs to be moved, but the Follow object.

2 There is a situation of following and having a target

Having a follow target means that the look-around function and the pan function need to coexist. Since the camera always faces the target when rotating the camera, if you simply move the Follow object, the angle of view will still be facing the target direction. So it is necessary to ensure that the follow object and the lookat object are at the same time convenient. Since our requirement is to "translate according to the camera's perspective", in order to avoid an infinite loop, it is necessary to establish a tracking relationship for these objects. There are also many ways to realize this function, two of which are introduced below

The first implementation method:

When panning, move the parent object of the follow and lookat targets, close the freecamera component while moving, and open it after the movement is over.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class CameraController: MonoBehaviour
{
    
    
    // 上下左右的移动速度
    public float moveSpeedXY = 10f;
    // 以前后移动速度
    public float moveSpeedZ = 60f;
    public CinemachineFreeLook freeLook;
    private bool isCameraMoving = false;
    Vector3 defaultPos;
    Vector3 defaultRot;
    void Update()
    {
    
    
        // 获取水平及滚轮按键值 区间为 0-1f
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float mouse = Input.GetAxis("Mouse ScrollWheel");
        if (h + v != 0f)
        {
    
    
            //调用平移的方法
            if (!isCameraMoving)
            {
    
    
                // 获取移动前的偏移
                defaultPos = Camera.main.transform.position - transform.position;
                defaultRot = Camera.main.transform.rotation.eulerAngles - transform.rotation.eulerAngles;
                // 关闭组件避免死循环
                freeLook.gameObject.SetActive(false);
                isCameraMoving = true;
            }
            // 平移镜头
            Camera.main.transform.Translate(new Vector3(h * moveSpeedXY, v * moveSpeedXY, mouse * moveSpeedZ) * Time.deltaTime, Space.Self);

        }
        else
        {
    
    
            if (isCameraMoving)
            {
    
    
                // 重置跟随和瞄准目标位置与主摄像机对齐
                transform.position = Camera.main.transform.position - defaultPos;
                transform.eulerAngles = Camera.main.transform.rotation.eulerAngles - defaultRot;
                // 启动freelook
                freeLook.gameObject.SetActive(true);
                isCameraMoving = false;
            }
        }
    }
}
The second way (recommended):

Keep the lookat target in line with the direction of the camera, and then let the camera's follow target follow the lookat target. When panning, just move the lookat target object. This method is more recommended, simple and reasonable.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
public class CameraController: MonoBehaviour
{
    
    
    // 上下左右的移动速度
    public float moveSpeedXY = 10f;
    // 以前后移动速度
    public float moveSpeedZ = 60f;
    public CinemachineFreeLook freeLook;
    void Update()
    {
    
    
        // 
        freeLook.LookAt.transform.eulerAngles = new Vector3(0f, Camera.main.transform.rotation.eulerAngles.y, 0f);
        // 获取水平及滚轮按键值 区间为 0-1f
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float mouse = Input.GetAxis("Mouse ScrollWheel");
        if (h + v != 0f)
        {
    
    
            freeLook.LookAt.transform.Translate(new Vector3(h * moveSpeedXY, mouse * moveSpeedZ, v * moveSpeedXY) * Time.deltaTime, Space.Self);
        }
    }
}
pay attention

Special attention needs to be paid when you perform a translation operation and you will find that the camera may rotate accordingly. This is not caused by our code, but caused by a function designed by cinecamera for the smooth transition of the camera. Just do the following settings:

  1. Find Orbits->Binding Mode in the inspector window of the freelookcam component and change it to Lock to target with world up
  2. Find the bady in top, middle, and buttom respectively, and set the related Damping to 0.
    insert image description here
  3. Please pay attention to this point. If the above settings are invalid and there is still a certain axis shaking, then it may be that the object followed by the camera uses rigid body movement. You need to find the interpolate in the rigidbody component, and try those options to set the difference to solve the problem~! !

5. Zoom perspective

Viewing zoom is achieved by modifying the camera's FieldOfView and orthographic.

Camera component implementation

private float currentViewScale;
public float scaleSpeed = 10.0f;
public float scaleMinScale = 1.0f;
public float scaleMaxScale = 150.0f;
void Start() {
    
    
        // for camera view scale
        this.currentViewScale = Camera.main.orthographic?Camera.main.OrthographicSize:Camera.main.FieldOfView;
    }
    
void Update(){
    
    
		this.currentViewScale += Input.GetAxis("Mouse ScrollWheel") * 	this.scaleSpeed;
        this.currentViewScale = Mathf.Clamp(this.currentViewScale, this.minScale, this.maxScale);
        if (Camera.main.orthographic)
        {
    
    
            Camera.main.OrthographicSize = this.currentViewScale;
        }
        else
        {
    
    
            Camera.main.FieldOfView = this.currentViewScale;
        }
  }

cinemachine component implementation

private float currentViewScale;
public float scaleSpeed = 10.0f;
public float scaleMinScale = 1.0f;
public float scaleMaxScale = 150.0f;
void Start() {
    
    
        // for camera view scale
        this.currentViewScale = Camera.main.orthographic? mainCineCamera.m_Lens.OrthographicSize:this.currentViewScale = mainCineCamera.m_Lens.FieldOfView;
    }
    
void Update(){
    
    
		this.currentViewScale += Input.GetAxis("Mouse ScrollWheel") * 	this.scaleSpeed;
        this.currentViewScale = Mathf.Clamp(this.currentViewScale, this.minScale, this.maxScale);
        if (Camera.main.orthographic == true)
        {
    
    
            this.mainCineCamera.m_Lens.OrthographicSize = this.currentViewScale;
        }
        else
        {
    
    
            this.mainCineCamera.m_Lens.FieldOfView = this.currentViewScale;
        }
  }

6. Automatically bypass obstacles

This function is only implemented using FreeLocckCam

  1. The virtual camera needs to add the cinemachine collider component
  2. Set the action layer in the cinemachine collider
  3. In the cinemachine collider, you can set the way the lens surrounds the object, the distance, the number, and the smoothness, etc.

Guess you like

Origin blog.csdn.net/lengyoumo/article/details/112347501