5-8 摄像机视距控制

  在上一章中,创建了新的摄像机层级关系。在这一章中我们来实现第一个功能,就是摄像机的视距远近控制。我们可以用一个float变量记录当前的视距,当这个值为0的时候表示摄像机视距最远,反之为1的时候表示摄像机的视距最近。初始值为1即最近。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
public class HexMapCamera : MonoBehaviour
{
//camera视距控制,0最远,1最近
private float zoom = 1f;

}

  在PC平台下,摄像机改变视距通常都是通过鼠标滚轮或者类似的输入方法控制,所以我们可以使用Unity默认的MouseScrollWheelUpdate方法里检查是否有输入增量,如果有再调用相应方法调整视距。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class HexMapCamera : MonoBehaviour
{


private void Update()
{
//检测鼠标滚轮是否有输入,有输入的话就调用 AdjustZoom
float zoomDelta = Input.GetAxis("Mouse ScrollWheel");
if (zoomDelta != 0f)
{
AdjustZoom(zoomDelta);
}
}

/// <summary>
/// 控制camera视距远近
/// </summary>
/// <param name="delta">鼠标滚轮输入的值</param>
private void AdjustZoom(float delta)
{

}
}

  要控制视距缩放就简单的加上输入增量,然后将值限制在0-1之间即可。代码如下:

HexMapCamera.cs
1
2
3
4
5
private void AdjustZoom(float delta)
{
//将变化值限制在0到1之间
zoom = Mathf.Clamp01(zoom + delta);
}

  因为摄像机Stick的子物体,我们在改变摄像机视距远近,其实就是在改变Stick的Z轴坐标。添加两个公共类型的float变量,用来规定Stick的最远和最近距离。由于我们创建的地图相对较小,先暂时设置为-250和-45。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
public class HexMapCamera : MonoBehaviour
{
//camera的最远和最近视距
public float stickMinZoom;
public float stickMaxZoom;



}

  设置好视距的最近最远值后,根据stickMinZoomstickMaxZoomzoom三个数值进行插值计算,得出Stick的Z轴坐标值,也就是摄像机的视距。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
private void AdjustZoom(float delta)
{


//视距远近其实就是stick.localPosition.z的值
//设置最大值和最小值后,根据zoom取其插值即可
float distance = Mathf.Lerp(stickMinZoom, stickMaxZoom, zoom);
stick.localPosition = new Vector3(0f, 0f, distance);
}

  现在能调整摄像机的视距了,但还是有些不太好用。通常游戏中的摄像机会在视距拉远的时候从斜向45度视角过渡到由上至下俯视角。这里我们可以通过旋转Swivel来实现,所以也同样为Swivel添加最大和最小的旋转角度标量,默认设置为90和45。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
public class HexMapCamera : MonoBehaviour
{
//camera的俯角和仰角值
public float swivelMinZoom;
public float swivelMaxZoom;



}

  与计算Stick的Z轴坐标值类似,我们使用swivelMinZoomswivelMaxZoomzoom三个值进行插值计算,得出Swivel的X轴旋转角度。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
private void AdjustZoom(float delta)
{


//在视距远近变化的时候,俯仰角也会变化
//视距最小时是斜向45度,视距最大是垂直90度
float angle = Mathf.Lerp(swivelMinZoom, swivelMaxZoom, zoom);
swivel.localRotation = Quaternion.Euler(angle, 0f, 0f);
}

  我们可以通过调整鼠标滚轮的灵敏度设置来控制视距的变化速度,在 Edit / ProjectSettings / Input Manager 面板中可以找到Mouse ScrollWhell / Sensitivity,例如可以把灵敏度默认值0.1改为0.025来获得更为平滑的视距变化感觉。

  如果不希望每次都要在Input Manager中修改鼠标滚轮的灵敏度,我们也可以创建一个控制鼠标灵敏度的变量,需要修改鼠标滚轮灵敏度的时候,我们只需要修改这个变量的值就可以了。代码如下:

HexMapCamera.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HexMapCamera : MonoBehaviour
{
//控制鼠标滚轮灵敏度,数值越大,速度越慢
[SerializeField] private float zoomSensitivity = 4;



private void AdjustZoom(float delta)
{
//添加了灵敏度控制
zoom = Mathf.Clamp01(zoom + delta/zoomSensitivity);


}
}

  至此我们就完成了通过鼠标滚轮控制摄像机视距远近的功能,但是只能调整视距还无法满足灵活编辑地图的需求。在接下来的章节中,我们将为摄像机添加移动的功能。

Github代码