Unity 3D\2D手机游戏开发:从学习到产品(第3版)
上QQ阅读APP看书,第一时间看更新

4.6 摄像机

因为游戏的场景可能会比较大,所以需要移动摄像机才能观察到场景的各个部分。接下来我们将为摄像机添加脚本,在移动鼠标的时候可以移动摄像机。

步骤 01 在为摄像机创建脚本前,首先创建一个空游戏体作为摄像机观察的目标点,并为其创建脚本CameraPoint.cs,它只有很少的代码。注意,CameraPoint.tif是一张图片,必须保存在工程中的Gizmos文件夹内。

        using UnityEngine;
        public class CameraPoint : MonoBehaviour
        {
            public static CameraPoint Instance = null;
            void Awake(){
              Instance = this;
        }
        // 在编辑器中显示一个图标
        void OnDrawGizmos(){
            Gizmos.DrawIcon(transform.position, "CameraPoint.tif");
        }
    }

步骤 02 创建脚本GameCamera.cs,并将其指定给场景中的摄像机。

        using UnityEngine;
        public class GameCamera : MonoBehaviour {
            public static GameCamera Inst = null;
            // 摄像机距离地面的距离
            protected float m_distance = 15;
            // 摄像机的角度
            protected Vector3 m_rot = new Vector3(-55, 180, 0);
            // 摄像机的移动速度
            protected float m_moveSpeed = 60;
            // 摄像机的移动值
            protected float m_vx = 0;
            protected float m_vy = 0;
            // Transform组件
            protected Transform m_transform;
            // 摄像机的焦点
            protected Transform m_cameraPoint;
            void Awake()
            {
              Inst = this;
              m_transform = this.transform;
            }
            void Start()
            {
              // 获得摄像机的焦点
              m_cameraPoint = CameraPoint.Instance.transform;
              Follow();
            }
            // 在Update之后执行
            void LateUpdate()
            {
              Follow();
            }
            // 摄像机对齐到焦点的位置和角度
            void Follow()
            {
                // 设置旋转角度
                m_cameraPoint.eulerAngles = m_rot;
                // 将摄像机移动到指定位置
                m_transform.position = m_cameraPoint.TransformPoint(new Vector3(0, 0, m_distance));
                // 将摄像机镜头对准目标点
                transform.LookAt(m_cameraPoint);
            }
            // 控制摄像机移动
            public void Control(bool mouse, float mx, float my)
            {
                if (! mouse)
                    return;
                m_cameraPoint.eulerAngles = Vector3.zero;
                // 平移摄像机目标点
                m_cameraPoint.Translate(-mx, 0, -my);
            }
          }

在这个脚本的Start函数中,我们首先获得了前面创建的CameraPoint,它将作为摄像机目标点的参考。

在Follow函数中,摄像机会按预设的旋转和距离始终跟随CameraPoint目标点。

LateUpdate函数和Update函数的作用一样,不同的是它始终会在执行完Update后执行,我们在这个函数中调用Follow函数,确保在所有的操作完成后再移动摄像机。

Control函数的作用是移动CameraPoint目标点,因为摄像机的角度和位置始终跟随这个目标点,所以也会随着目标点的移动而移动。

步骤 03 打开GameManager.cs脚本,在Update函数中添加代码如下:

        void Update () {
              // 如果选中创建士兵的按钮,则取消摄像机操作
              if (m_isSelectedButton)
                  return;
              // 鼠标或触屏操作,注意不同平台的Input代码不同
        #if (UNITY_IOS || UNITY_ANDROID) && ! UNITY_EDITOR
              bool press=Input.touches.Length>0? true: false;  // 手指是否触屏
              float mx = 0;
              float my = 0;
              if (press)
              {
                  if(Input.GetTouch(0).phase==TouchPhase.Moved)  // 获得手指移动距离
                  {
                      mx = Input.GetTouch(0).deltaPosition.x * 0.01f;
                      my = Input.GetTouch(0).deltaPosition.y * 0.01f;
                  }
        }
  #else
        bool press = Input.GetMouseButton(0);
        // 获得鼠标移动距离
        float mx = Input.GetAxis("Mouse X");
        float my = Input.GetAxis("Mouse Y");
  #endif
        // 移动摄像机
        GameCamera.Inst.Control(press, mx, my);
    }

这段代码的作用是获取鼠标操作的各种信息并传递给摄像机,现在运行游戏,已经可以移动摄像机了。