当我们在用摄像机跟随目标物体移动时,可能还伴随着移动物体的旋转和场景的远近等等。那么问题来了,当我们旋转物体时,出现万象锁现象怎么办?!或者 同一物体 在进行多种操作时,旋转缩放移动等出现冲突怎么办?!
干货来了,对摄像机操作优化来了!!!
>干货来了!
1.先创建五个空物体,按层级放置。分别体现 CameraController、RotateX、RotateY、ZoomZ、LookAt,把Camera 放在最下面.
##如下图:
![QQ图片20160908145740.png](http://upload-images.jianshu.io/upload_images/2570889-5e27488d7551a8e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2、在最上面控制器上创建脚本 CameraController.cs
(思想:通过获取移动物体的transform 组件里面的 position、rotation的值,传递给CameraController摄像机,实现 摄像机 跟随 移动对象的 旋转缩放和移动。)
代码如下:
#region 单例
private static CameraController instance;
public static CameraController Instance
{
get {
return instance;
}
}
void Awake()
{
instance = this;
}
#endregion
#region 序列化域
[SerializeField]
private Transform mCameraRotateX;
[SerializeField]
private Transform mCameraRotateY;
[SerializeField]
private Transform mCameraZoomZ;
[SerializeField]
private Transform mCameraLookAt;
#endregion
#region 属性
private float sensitiveVal = 10f;
private float rotateSensitiveVal = 60f;
private float minValue = -10f;
private float maxValue = -3f;
#endregion
#region 方法
/// <summary>
/// 摄像机跟随
/// </summary>
/// <param name="position"></param>
public void AutoFollow(Vector3 position)
{
transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * sensitiveVal);
}
/// <summary>
/// X轴跟随旋转 角度
/// </summary>
/// <param name="id">id = 1 表示正方向,-1 表示负方向</param>
public void RotateX(int id)
{
float value = Time.deltaTime * id * rotateSensitiveVal;
mCameraRotateX.localEulerAngles += new Vector3(value, 0, 0);
}
/// <summary>
/// Y轴旋转角度
/// </summary>
/// <param name="id"> id = 1表示正方向,-1 表示负方向</param>
public void RotateY(int id)
{
float value = Time.deltaTime * id * rotateSensitiveVal;
mCameraRotateY.localEulerAngles += new Vector3(0, value, 0);
}
/// <summary>
/// 指向 物体
/// </summary>
/// <param name="position"></param>
public void LookAt(Vector3 position)
{
mCameraLookAt.LookAt(position);
}
/// <summary>
/// 摄像机 跟随 Z轴 缩放缩放范围【-10,-3】
/// </summary>
/// <param name="id"></param>
public void ZoomZ(int id)
{
float value =mCameraZoomZ.localPosition.z + Time.deltaTime * id * sensitiveVal;
value = Mathf.Clamp(value, minValue, maxValue);
mCameraZoomZ.localPosition = new Vector3(0, 0, value);
}
#endregion
、、、、
> 用到的数学函数为:
1.Mathf.Clamp(float value, float min, float max);
value 为默认值,其取值范围为[min,max]
2.Vector3.Lerp(Vector3 a, Vector3 b, float t);
表示:Linearly interpolates between two vectors.
两个向量之间的线性插值
作用: 平滑跟随,防止出现卡顿或抖动现象
3.transform.LocalEulerAngles
// Summary:
// ///
// The rotation as Euler angles in degrees relative to the parent transform's rotation.
//欧拉角的旋转度相对于父变换的旋转。
// ///
public Vector3 localEulerAngles { get; set; }
>简单的创建一个 移动对象Sphere,并把自身的相关transform参数 ,通过调用上面的方法来传递。
###代码:
、、、、
//定义变量
float scrollWheel = 0f;
float hor;
float ver;
void Update()
{
#region 用键盘控制 移动物体移动
hor = Input.GetAxis("Horizontal");
ver = Input.GetAxis("Vertical");
transform.position += new Vector3(hor, 0, ver);
#endregion
#region 根据滚轮的前后滑动 缩放镜头
scrollWheel = Input.GetAxis("Mouse ScrollWheel");
if (scrollWheel != 0)
{
CameraController.Instance.ZoomZ(scrollWheel > 0 ? 1 : -1);
}
#endregion
#region 当按下A时 摄像机绕物体正向旋转,当按下d时 摄像机绕物体对象 反向旋转
if (Input.GetKey(KeyCode.Z))
{
CameraController.Instance.RotateY(1);
}
if (Input.GetKey(KeyCode.C))
{
CameraController.Instance.RotateY(-1);
}
#endregion
#region 当按下X时 摄像机绕X轴旋转 正向旋转,当按下V时 摄像机 绕X轴反向旋转
if (Input.GetKey(KeyCode.X))
{
CameraController.Instance.RotateX(1);
}
if (Input.GetKey(KeyCode.V))
{
CameraController.Instance.RotateX(-1);
}
#endregion
}
void LateUpdate()
{
//传递 移动对象 坐标参数,使摄像机 一直指向 移动对象,且跟随对象移动
CameraController.Instance.LookAt(transform.position);
CameraController.Instance.AutoFollow(transform.position);
}
、、、、