【Unity3D】简单常用的功能实现2——视角的跟随、旋转、缩放

【视角的跟随、旋转、缩放实现】

首先,在实现这些功能之前,我们给Hierarchy面板中的主摄像机额外包装几层Empty Object,形成一个新的摄像机结构,如下图(当然这些空物体的命名大家按自己方便就是了):

 

然后调整一下CameraUpAndDown、CameraZoomContainer的几个参数(注意,调参这个步骤一定不要漏掉,调参是为了使主摄像机在旋转拉伸时能始终对准物体):

如图:

CameraUpAndDown物体rotateZ轴90°。(旋转CameraUpAndDown的Z轴是为了使主摄像机视角在旋转、拉伸时始终对准物体,)

 

 

CameraZoomContainer物体RotateY轴-90°。(旋转CameraZoomContainer的Y轴是为了使编辑器状态下视角在旋转、拉伸时始终对准物体,但不修改的话并不会影响运行时的视角)

CameraZoomContainer物体Position.X改为一个正数,(不一定是4,只要能使你的主摄像机观察到物体就行,0的话会使主摄像机距离物体太近。)

 

第二步,在CameraFollowAndRotate的Inspector面板下添加一个脚本(这里我把这个脚本命名为CameraCtrl),代码如下:

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 public class CameraCtrl : MonoBehaviour
 6 {
 7     public static CameraCtrl Instance;
 8 
 9     /// <summary>
10     /// 摄像机结构下的几个子物体, m_CameraUpAndDown控制垂直观察角度,m_CameraZoomContainer控制镜头对准方向, m_CameraContainer控制物体与镜头间距离
11     /// </summary>
12     [SerializeField]
13     private Transform m_CameraUpAndDown;
14     [SerializeField]
15     private Transform m_CameraZoomContainer;
16     [SerializeField]
17     private Transform m_CameraContainer;
18 
19     private void Awake()
20     {
21         Instance = this;
22     }
23 
24     //初始化函数
25     public void Init()
26     {
27         //如果Camera垂直观察角度的初始值、Camera与物体距离的初始值在限定范围外,进行矫正
28         m_CameraUpAndDown.Rotate(0, 0, 45f);
29         m_CameraUpAndDown.localEulerAngles = new Vector3(0, 0, Mathf.Clamp(m_CameraUpAndDown.localEulerAngles.z, 1f, 90f));
30         m_CameraContainer.localPosition = new Vector3(0, 0, Mathf.Clamp(m_CameraContainer.localPosition.z, -5f, 0));
31     }
32 
33     //实时看向主角物体
34     public void AutoLookAt(Vector3 position)
35     {
36         m_CameraZoomContainer.LookAt(position);
37     }
38 
39     /// <summary>
40     /// 控制Camera水平旋转 左=0 右=1
41     /// </summary>
42     /// <param name="type"></param>
43     public void SetCameraRotate(int type)
44     {
45         transform.Rotate(0, 20 * Time.deltaTime * (type == 0 ? 1 : -1), 0);
46     }
47 
48     /// <summary>
49     /// 控制Camera垂直旋转 上=0 下=1
50     /// </summary>
51     /// <param name="type"></param>
52     public void SetCameraUpAndDown(int type)
53     {
54         m_CameraUpAndDown.Rotate(0, 0, 20 * Time.deltaTime * (type == 0 ? 1 : -1));
55         //锁定Camera垂直观察角度的范围1°至90°
56         m_CameraUpAndDown.localEulerAngles = new Vector3(0, 0, Mathf.Clamp(m_CameraUpAndDown.localEulerAngles.z, 1f, 90f));
57     }
58 
59     /// <summary>
60     /// 控制Camera和物体的距离 拉近=0 拉远1
61     /// </summary>
62     /// <param name="type"></param>
63     public void SetCameraZoom(int type)
64     {   //注意,虽然方法名有Zoom,但是控制镜头与物体距离的是m_CameraContainer,所以这里修改m_CameraContainer的position的Z轴
65         m_CameraContainer.Translate(Vector3.forward * 4 * Time.deltaTime * (type == 0 ? 1 : -1));
66         m_CameraContainer.localPosition = new Vector3(0, 0, Mathf.Clamp(m_CameraContainer.localPosition.z, -5f, 0));
67     }
68 }

 

注意!  13、15、17三个序列化字段的赋值要在CameraFollowAndRotate的Inspector面板中进行,使这些变量指向对应的组件,如下图:

 

第三步,在 视角要跟随的Object 的脚本中 实现对CameraCtrl脚本方法的调用,这里就简单举例了:

 1 //该方法在要跟随的Object的脚本的Update()中调用即可实现视角的旋转、缩放以及视角的实时跟随
 2 private void cameraAutoFollow()
 3 {
 4     if (CameraCtrl.Instance == null) { return; }
 5     //Camera实时同步主角物体的位置并使镜头对准主角物体
 6     CameraCtrl.Instance.transform.position = gameObject.transform.position;
 7     CameraCtrl.Instance.AutoLookAt(gameObject.transform.position);
 8 
 9 
10     //依照按键调整镜头视角,以按Q键实现顺时针水平旋转为例子
11     if (Input.GetKey(KeyCode.Q))
12     {
13         CameraCtrl.Instance.SetCameraRotate(0);      //参数为1 则为逆时针水平旋转
14         //CameraCtrl.Instance.SetCameraUpAndDown(0); //视角垂直旋转
15         //CameraCtrl.Instance.SetCameraZoom(0);      //视角缩放
16     }
17 }

 

 最后,对这个摄像机结构再总结一下:

CameraFollowAndRotate:通过修改该Object的Position,我们可以实现视角对移动物体的跟随、RotateY轴则可以实现视角对物体的水平旋转观察。

CameraUpAndDown:通过Rotate该Object的Z轴,我们可以实现视角对移动物体的垂直旋转观察。Z轴旋转要初始为90°

CameraZoomContainer:运行的时候Lookat方法会实时Rotate各个轴使摄像机镜头对准物体。Y轴旋转要初始为-90°以方便编辑器视窗下对Camera的调试,X轴设置为一个合适的正数就可以。

CameraContainer:通过修改该Object的Position.Z属性来拉近或拉远主摄像机与物体的距离,实现缩放。

posted @ 2020-07-02 00:50  469の一方爬行  阅读(1304)  评论(0编辑  收藏  举报