您的位置:首页 > 移动开发 > Unity3D

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这一步取消

脚本内容如下:

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 摄像机