Unity学习笔记——俯瞰视角摄像机脚本
2018-02-03 16:36
471 查看
适用于2.5D模拟经营、战旗策略类游戏摄像机脚本,需要获取主摄像机Main Camera对象和地形terrain对象,摄像机初始位置基于地图的尺寸设定在地图上空中心位置,并且x轴旋转45度俯瞰地图。
实现了缩放摄像机(拉远、拉近)方法、WASD移动摄像机方法、按住鼠标右键旋转摄像机方法和限制摄像机移动范围方法。其中限制摄像机移动范围方法并不准确,需要获得摄像机视口范围即视野和地图相交的坐标信息,因为高度增加摄像机视野会变大,不同高度的摄像机被限制的范围应和高度建立联系,解决这一问题涉及了较深数学知识,先按下不表,使用简单的范围限制。
完成这一脚本对扩充了我的以下知识点:
1.Mathf.Sin等三角函数参数为弧度,需要把角度进行转换后传入
2. 地形尺寸获取即获取地形的碰撞器的尺寸
3.摄像机位置只能对position进行赋值、加减等操作,不能单独对position的x、y、z变量操作,因此需要声明一个Vector3变量,对此变量进行操作,再传给摄像机坐标
4.Input.GetAxis("Vertical")、Input.GetAxis("Horizontal")返回的是1或-1,使用该封装可以简化按键事件,但如果提供修改键位功能还是需要老老实实写wasd等按键的事件
5.旋转摄像机后再移动摄像机并不会按照摄像机方向移动,仍然会按照世界坐标系移动,因此移动摄像机算法中,不能使用对摄像机坐标的x、y、z直接加减,要使用摄像机坐标直接加减Vector3变量,该变量需要乘以transform.forward或transform.right方向向量,考虑到摄像机的x轴旋转了一定角度,需要把forward、right赋值为另一个Vector3变量,将其y变量赋为0,就使摄像机按照朝向的水平方向移动了
6.由于摄像机是自由移动的,没有target作为目标点,缩放就不能使用修改distance的方法,在试过很多错误道路后,我发现缩放的实现和移动唯一的不同就是把将y变量赋为0这一步取消
脚本内容如下:
实现了缩放摄像机(拉远、拉近)方法、WASD移动摄像机方法、按住鼠标右键旋转摄像机方法和限制摄像机移动范围方法。其中限制摄像机移动范围方法并不准确,需要获得摄像机视口范围即视野和地图相交的坐标信息,因为高度增加摄像机视野会变大,不同高度的摄像机被限制的范围应和高度建立联系,解决这一问题涉及了较深数学知识,先按下不表,使用简单的范围限制。
完成这一脚本对扩充了我的以下知识点:
1.Mathf.Sin等三角函数参数为弧度,需要把角度进行转换后传入
2. 地形尺寸获取即获取地形的碰撞器的尺寸
3.摄像机位置只能对position进行赋值、加减等操作,不能单独对position的x、y、z变量操作,因此需要声明一个Vector3变量,对此变量进行操作,再传给摄像机坐标
4.Input.GetAxis("Vertical")、Input.GetAxis("Horizontal")返回的是1或-1,使用该封装可以简化按键事件,但如果提供修改键位功能还是需要老老实实写wasd等按键的事件
5.旋转摄像机后再移动摄像机并不会按照摄像机方向移动,仍然会按照世界坐标系移动,因此移动摄像机算法中,不能使用对摄像机坐标的x、y、z直接加减,要使用摄像机坐标直接加减Vector3变量,该变量需要乘以transform.forward或transform.right方向向量,考虑到摄像机的x轴旋转了一定角度,需要把forward、right赋值为另一个Vector3变量,将其y变量赋为0,就使摄像机按照朝向的水平方向移动了
6.由于摄像机是自由移动的,没有target作为目标点,缩放就不能使用修改distance的方法,在试过很多错误道路后,我发现缩放的实现和移动唯一的不同就是把将y变量赋为0这一步取消
脚本内容如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraControl : MonoBehaviour { public GameObject mainCamera;//获取摄像机 public GameObject terrain;//获取地图 public float rollAngle=45;//摄像机倾斜角度 public float height=40f;//摄像机和地图的高度差 public float moveSpeed = 1.5f;//摄像机移动速度系数 public float maxRangeX;//摄像机x坐标变化范围 public float minRangeX; public float maxRangeZ;//摄像机z坐标变化范围 public float minRangeZ; public float maxRangeY = 75f;//缩放最大高度 public float minRangeY = 30f;//缩放最小高度 public float zoomSpeed = 5f;//缩放速度系数 public float rotateAngle = 0; public float rotateSpeed=100f;//旋转速度系数 Vector3 cameraPos;//摄像机临时坐标 public float sizeX;//地图尺寸x public float sizeZ;//地图尺寸z void Start () { //获取地图尺寸 sizeX = terrain.GetComponent<TerrainCollider>().bounds.size.x; sizeZ = terrain.GetComponent<TerrainCollider>().bounds.size.z; maxRangeX = terrain.transform.position.x + 0.75f * sizeX; minRangeX = terrain.transform.position.x + 0.25f * sizeX; maxRangeZ = terrain.transform.position.z + 0.75f * sizeZ; minRangeZ = terrain.transform.position.z + 0.25f * sizeZ; //设置摄像机位置 cameraPos.x = terrain.transform.position.x + sizeX/ 2 ; cameraPos.y = terrain.transform.position.y + height; cameraPos.z = terrain.transform.position.z + sizeZ/ 2 ; mainCamera.transform.position = cameraPos; mainCamera.transform.eulerAngles = new Vector3(rollAngle, 0, 0); Debug.Log("地图尺寸为:" + sizeX + "X" + sizeZ); } void Update () { //更新摄像机坐标 MoveCamera(); RotateCamera(); ZoomCamera(); LimitRange(); mainCamera.transform.position = cameraPos; } void MoveCamera() { //第一种方法按下WS、AD,Input.GetAxis()会返回1或-1 float moveZ = Input.GetAxis("Vertical"); Vector3 moveDirectionZ = transform.forward; moveDirectionZ.y = 0; cameraPos += moveDirectionZ * moveZ * moveSpeed; float moveX = Input.GetAxis("Horizontal"); Vector3 moveDirectionX = transform.right; moveDirectionZ.y = 0; cameraPos += moveDirectionX * moveX * moveSpeed; //按下shift加速移动摄像机 if (Input.GetKey(KeyCode.LeftShift)) moveSpeed = 2.5f; if (Input.GetKeyUp(KeyCode.LeftShift)) moveSpeed = 1.5f; } void ZoomCamera() { //滚动鼠标滑轮缩放摄像机 if (Input.GetAxis("Mouse ScrollWheel") > 0) { if (cameraPos.y < minRangeY) return; Vector3 moveDirectionZ = transform.forward; cameraPos += moveDirectionZ * zoomSpeed; } if (Input.GetAxis("Mouse ScrollWheel") <0) { if (cameraPos.y > maxRangeY) return; Vector3 moveDirectionZ = -transform.forward; cameraPos += moveDirectionZ * zoomSpeed; } } void RotateCamera() { //按下鼠标右键旋转摄像机 if (Input.GetMouseButton(1)) { rotateAngle = Input.GetAxis("Mouse X")*rotateSpeed*Time.deltaTime; mainCamera.transform.Rotate(0,rotateAngle,0,Space.World); } } void LimitRange() { //摄像机移动范围限制 if (cameraPos.x > maxRangeX) cameraPos.x = maxRangeX; if (cameraPos.x < minRangeX) cameraPos.x = minRangeX; if (cameraPos.z > maxRangeZ) cameraPos.z = maxRangeZ; if (cameraPos.z < minRangeZ) cameraPos.z = minRangeZ; } }
相关文章推荐
- Unity学习笔记--鹰击长空类固定视角游戏摄像机跟随
- 【Unity 3D】学习笔记二十二:unity游戏脚本(二)
- 【Unity 3D】学习笔记二十三:unity游戏脚本(三)
- Unity 3D 正交(Orthographic)摄像机尺寸学习笔记
- Unity官方第一人称射击游戏<恶魔射手>_学习笔记三(敌人脚本)
- Unity学习笔记3:随机数和动画脚本
- 【Unity 3D游戏开发学习笔记】总结摄像机和光源的使用方法
- 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头
- Unity学习笔记——Unity基础四:刚体及脚本初步
- 学习笔记:Unity战斗卡牌游戏(二)-----滑动列表及克隆删除对象以及代码添加脚本
- Unity学习笔记3:随机数和动画脚本
- Unity学习笔记 2nd —— 摄像机那些事
- Unity学习系列笔记3:随机数和动画脚本
- Unity 3D学习笔记(二)—— 脚本01
- Unity学习笔记(四)-----------脚本、parent、GetComponent、GetComponentInChildren
- Unity 3D学习笔记(三)——关于脚本
- 【Unity 3D】学习笔记二十一:unity游戏脚本(一)
- 蓝鸥Unity入门脚本组件学习笔记
- 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头
- unity3D脚本学习笔记1