转载自:http://www.unitymanual.com/blog-10192-2681.html
我总结了一下,RPG中摄像机无非就三个功能:
- 跟随猪脚
- 绕猪脚旋转
- 可以拉近或拉远视角
额,在写代码之前我们先理一下思路,定义哪些变量,猪脚肯定要的,我们定义target(gameobject),摄像机肯定需要一个高度,定义distance(float)。
[code]csharpcode:
using UnityEngine;
using System.Collections;
public class CameraTest : MonoBehaviour {
public GameObject target;//我们万圣的猪脚
public float distance = 2;//摄像机离target的距离
public Vector3 position;//摄像机的位置
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Follow();
}
void Follow()//摄像机跟随target
{
Vector3 distancePos = new Vector3(0,0,-distance);
position = transform.rotation * distancePos + target.transform.position;//更新摄像机的位置,根据target的位置
transform.position = position;
}
}
把代码赋值给主摄像机,然后调整摄像机的旋转位置到合适的地方,运行,然后改动cube的position,可以看到game视图中,摄像机真的跟着移动了,好神奇!!!!
第一个功能算是完成了,不过接下来还要优化,别急,我们下面来实现第二个功能,绕猪脚旋转。
旋转是怎么旋转?可能有些小伙伴会问。当然是360度无死角的绕猪脚旋转观察,假如说猪脚是女性咋办?好吧我邪恶了!
RPG中摄像机的旋转,我们只需要修改x轴和y轴的旋转就行了,有兴趣的小伙伴可以运行上面的代码,去inspector视窗中手动调整一下rotation试试,看看效果!
发现随着x,y的不断变化,摄像机就绕着猪脚旋转啦!
那么好,我们假定按下鼠标右键不放上下左右移动,摄像机就上下左右旋转。开始写代码,同样需要定义变量,这里x(float),y(float)来记录摄像机的旋转角度。
我们只需要修改x,y就行了。
[code]csharpcode:
using UnityEngine;
using System.Collections;
public class CameraTest : MonoBehaviour {
public GameObject target;//我们万圣的猪脚
public float distance = 2;//摄像机离target的距离
public Vector3 position;//摄像机的位置
public float x;//存储摄像机在x轴的旋转角
public float y;//存储摄像机在z轴的旋转角
private bool isActive;//记录鼠标右键是否按下不放
// Use this for initialization
void Start () {
x = transform.eulerAngles.x;
y = transform.eulerAngles.y;
}
// Update is called once per frame
void Update () {
Follow();
RotateCamera();
}
void Follow()//摄像机跟随target
{
Quaternion rotation = Quaternion.Euler(x,y,0);//Quaternion.Euler 欧拉角:返回一个旋转角度,绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度
Vector3 distancePos = new Vector3(0,0,-distance);
position = rotation * distancePos + target.transform.position;//更新摄像机的位置,根据target的位置
transform.position = position;
transform.rotation = rotation;//这里是我们更新摄像机的旋转
}
void RotateCamera()
{
if (Input.GetMouseButtonDown(1)){
isActive = true;
}
if (Input.GetMouseButtonUp(1))
{
isActive = false;
}
if (target && isActive) {
x -= Input.GetAxis("Mouse Y");
y += Input.GetAxis("Mouse X");
}
}
}
运行试试,真的旋转了,好开心!好Happy!
我说过代码在刚开始的时候是不完整的,我们需要不断地优化,那么这个代码有和缺点呢?
对,就是不能控制旋转速度,假设有一天我要加快旋转速度怎么办。很简单定义一个speedX,speedY(float),
x -= Input.GetAxis("Mouse Y") * speedY;
y += Input.GetAxis("Mouse X") * speedX;
[code]csharpcode:
private float xLerp,yLerp;
public float lerpSpeed;//旋转平滑度
[code]csharpcode:
void RotateCamera()
{
if (Input.GetMouseButtonDown(1)){
isActive = true;
}
if (Input.GetMouseButtonUp(1))
{
isActive = false;
}
if (target && isActive) {
xLerp -= Input.GetAxis("Mouse Y") * speedY;
yLerp += Input.GetAxis("Mouse X") * speedX;
}
x = Mathf.Lerp(x,xLerp,Time.deltaTime * lerpSpeed);
y = Mathf.Lerp(y,yLerp,Time.deltaTime * lerpSpeed);
}
还有我们发现当上下旋转摄像机会转到地面以下,这就有点糟糕!所以我们要定义MaxLimit,MinLimit变量(float)限定xLerp的值,使之落在两者之间。
[code]csharpcode:
public float MaxLimit = 75;
public float MinLimit = 15;
[code]csharpcode:
if (target && isActive) {
xLerp -= Input.GetAxis("Mouse Y") * speedY;
yLerp += Input.GetAxis("Mouse X") * speedX;
xLerp = Mathf.Clamp(xLerp,MinLimit,MaxLimit);
}
[code]csharpcode:
public float scrollSpeed;//缩放速度
public float Maxzoom;//缩放最大值
public float Minzoom;//缩放最小值
private float distanceLerp;
[code]csharpcode:
void Start () {
x = transform.eulerAngles.x;
y = transform.eulerAngles.y;
distanceLerp = distance;
}
[code]csharpcode:
void ScrollMouse()
{
distance = Mathf.Lerp(distance,distanceLerp,Time.deltaTime * 5);
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
distanceLerp = Vector3.Distance (transform.position , target.transform.position);
distanceLerp = Mathf.Clamp(distanceLerp - Input.GetAxis("Mouse ScrollWheel")*scrollSpeed, Minzoom, Maxzoom);
}
}