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

基于Unity3D的相机功能的实现(七)—— 综合篇

2017-12-10 18:19 603 查看
此篇把之前的相机功能进行了汇总,通过一个枚举类型进行切换。功能如下:

followInching:跟踪加缓动效果
freeInching:自由加缓动效果
onlyFollow:仅跟踪视角
onlyFree:仅自由视角
none:正常相机

代码如下:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[System.Serializable]
public class CameraData {
public Transform target;//相机所看目标点,若target==null,则相机为自由视角,否则为跟踪视角
public float yMinLimit = -50.0f;//y最小角度视角限制
public float yMaxLimit = 90.0f;//y最大角度视角限制
public float xMinRangeLimit = float.MinValue;//x最小限制距离
public float xMaxRangeLimit = float.MaxValue;//x最大限制距离
public float yMinRangeLimit = float.MinValue;//y最小限制距离
public float yMaxRangeLimit = float.MaxValue;//y最大限制距离
public float zMinRangeLimit = float.MinValue;//z最小距离限制
public float zMaxRangeLimit = float.MaxValue;//z最大距离限制
public float minDistanceToTarget = 0.0f;//距离目标最小距离
public float maxDistanceToTarget = 10.0f;//距离目标最大距离
public float xSpeed = 200.0f;//x角度旋转速度
public float ySpeed = 120.0f;//y角度旋转速度
public float scaleSpeed = 4.0f;//缩放速度
public float xMoveSpeed = 4.0f;//x方向平移速度
public float yMoveSpeed = 4.0f;//y方向平移速度
public float lerpSpeed = 5.0f;//差值速度(缓动速度)

//实时变化
[HideInInspector]
public float distance = 5.0f;//相机与目标点距离
[HideInInspector]
public float xCurrentAngle = 50.0f;//当前x角度
[HideInInspector]
public float yCurrentAngle = 25.0f;//当前y角度
[HideInInspector]
public float x, y;
}
public class CameraControl : MonoBehaviour {
public enum Angle {
followInching,//跟踪加缓动效果
freeInching,//自由加缓动效果
onlyFollow,//仅跟踪视角
onlyFree,//仅自由视角
none//正常相机
}

public CameraData cameraData;//Camera数据
public Angle angle;//初始默认视角

private float slowlySpeed = 2.0f;//缓动速度
private float zCurrentScale = 0.0f;//当前缩放
private float xCurrentScale = 0.0f;//当前横向平移
private float yCurrentScale = 0.0f;//当前纵向平移

private Vector2 oldPosition1;
private Vector2 oldPosition2;

void Update() {
if (Input.GetKeyDown(KeyCode.F5)) {
cameraData.x = 0;
cameraData.y = 0;
}
switch (angle) {
case Angle.followInching:
if (cameraData.ta
4000
rget != null) {
FollowAngle (true);
} else {
FreeAngle (true);
}
break;
case Angle.freeInching:
FreeAngle (true);
break;
case Angle.onlyFollow:
if (cameraData.target != null) {
FollowAngle (false);
} else {
FreeAngle (false);
}
break;
case Angle.onlyFree:
FreeAngle (false);
break;
case Angle.none:
break;
default:
break;
}
}
/// <summary>
/// 自由视角
/// </summary>
/// <param name="isSlowAction">是否缓动判断</param>
void FreeAngle(bool isSlowAction) {
#region 旋转
if (Input.GetMouseButton(1)) {
cameraData.xCurrentAngle += Input.GetAxis("Mouse X") * cameraData.xSpeed * Time.deltaTime;
cameraData.yCurrentAngle -= Input.GetAxis("Mouse Y") * cameraData.ySpeed * Time.deltaTime;
cameraData.yCurrentAngle = ClampAngle(cameraData.yCurrentAngle, cameraData.yMinLimit, cameraData.yMaxLimit);//y旋转角度限制
}
Quaternion rotationTo = Quaternion.Euler(cameraData.yCurrentAngle, cameraData.xCurrentAngle, 0);
#endregion
#region 缩放
if (Input.GetAxis("Mouse ScrollWheel") != 0.0f) {
zCurrentScale = Input.GetAxis("Mouse ScrollWheel") * cameraData.scaleSpeed;
}
#endregion
#region 平移
if (Input.GetMouseButton(0)) {
xCurrentScale = -Input.GetAxis("Mouse X") * Time.deltaTime * cameraData.xMoveSpeed;
yCurrentScale = -Input.GetAxis("Mouse Y") * Time.deltaTime * cameraData.yMoveSpeed;
xCurrentScale = xCurrentScale > 1 ? 1 : xCurrentScale;
yCurrentScale = yCurrentScale > 1 ? 1 : yCurrentScale;
xCurrentScale = xCurrentScale < -1 ? -1 : xCurrentScale;
yCurrentScale = yCurrentScale < -1 ? -1 : yCurrentScale;
}
#endregion
if (isSlowAction)//带缓动效果
{
transform.rotation = Quaternion.Lerp(transform.rotation, rotationTo, Time.deltaTime * cameraData.lerpSpeed);
transform.position = Vector3.Lerp(transform.position, transform.position + transform.forward * (zCurrentScale > 0 ? ((zCurrentScale -= Time.deltaTime * slowlySpeed) < 0 ? zCurrentScale = 0 : zCurrentScale) : ((zCurrentScale += Time.deltaTime * slowlySpeed) > 0 ? zCurrentScale = 0 : zCurrentScale)) + transform.right * (xCurrentScale > 0 ? ((xCurrentScale -= Time.deltaTime * slowlySpeed) < 0 ? xCurrentScale = 0 : xCurrentScale) : ((xCurrentScale += Time.deltaTime * slowlySpeed) > 0 ? xCurrentScale = 0 : xCurrentScale)) + transform.up * (yCurrentScale > 0 ? ((yCurrentScale -= Time.deltaTime * slowlySpeed) < 0 ? yCurrentScale = 0 : yCurrentScale) : ((yCurrentScale += Time.deltaTime * slowlySpeed) > 0 ? yCurrentScale = 0 : yCurrentScale)), Time.deltaTime * cameraData.lerpSpeed);
}
else//正常
{
Vector3 positionTo = rotationTo * new Vector3(xCurrentScale, yCurrentScale, zCurrentScale) + transform.position;
xCurrentScale = 0;
yCurrentScale = 0;
zCurrentScale = 0;
transform.rotation = rotationTo;
transform.position = positionTo;
}
transform.position = new Vector3(Mathf.Clamp(transform.position.x, cameraData.xMinRangeLimit, cameraData.xMaxRangeLimit), Mathf.Clamp(transform.position.y, cameraData.yMinRangeLimit, cameraData.yMaxRangeLimit), Mathf.Clamp(transform.position.z, cameraData.zMinRangeLimit, cameraData.zMaxRangeLimit));//自由模式区域限制
}
/// <summary>
/// 跟踪视角
/// </summary>
/// <param name="isSlowAction">是否缓动判断</param>
void FollowAngle (bool isSlowAction)
{
if (Input.GetMouseButton (1)) {
cameraData.xCurrentAngle += Input.GetAxis ("Mouse X") * cameraData.xSpeed * Time.deltaTime;
cameraData.yCurrentAngle -= Input.GetAxis ("Mouse Y") * cameraData.ySpeed * Time.deltaTime;
cameraData.yCurrentAngle = ClampAngle (cameraData.yCurrentAngle, cameraData.yMinLimit, cameraData.yMaxLimit);//y旋转角度限制
}
if (Input.GetMouseButton (0)) {
xCurrentScale = -Input.GetAxis ("Mouse X") * Time.deltaTime * cameraData.xMoveSpeed;
yCurrentScale = -Input.GetAxis ("Mouse Y") * Time.deltaTime * cameraData.yMoveSpeed;
cameraData.x += xCurrentScale;
cameraData.x = Mathf.Clamp (cameraData.x, cameraData.xMinRangeLimit, cameraData.xMaxRangeLimit);
cameraData.y += yCurrentScale;
cameraData.y = Mathf.Clamp (cameraData.y, cameraData.yMinRangeLimit, cameraData.yMaxRangeLimit);
}
cameraData.distance -= Input.GetAxis ("Mouse ScrollWheel") * cameraData.scaleSpeed;
cameraData.distance = Mathf.Clamp (cameraData.distance, cameraData.minDistanceToTarget, cameraData.maxDistanceToTarget);//缩放距离限制
Quaternion rotationTo = Quaternion.Euler (cameraData.yCurrentAngle, cameraData.xCurrentAngle, 0);
Vector3 positionTo = rotationTo * new Vector3 (cameraData.x, cameraData.y, -cameraData.distance) + cameraData.target.position;
if (isSlowAction) {//带缓动效果
transform.rotation = Quaternion.Lerp (transform.rotation, rotationTo, Time.deltaTime * cameraData.lerpSpeed);
transform.position = Vector3.Lerp (transform.position, positionTo, Time.deltaTime * cameraData.lerpSpeed);
} else {//正常
transform.rotation = rotationTo;
transform.position = positionTo;
}
}
/// <summary>
/// 限制视角旋转角度
/// </summary>
/// <param name="angle">当前角度</param>
/// <param name="min">最小旋转角度</param>
/// <param name="max">最大旋转角度</param>
/// <returns></returns>
float ClampAngle(float angle, float min, float max) {
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
//检测是否放大还是缩小
public bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
{
float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
if (leng1 < leng2)
{
return true;
}
else
{
return false;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: