星盟沖突,星區(qū)視角下的縮放效果圖:
一. 手勢(shì)系統(tǒng)
使用插件EasyTouch監(jiān)聽(tīng)移動(dòng)縮放
EasyTouch.On_Pinch += CameraController.Instance.OnPinch;
EasyTouch.On_Swipe += CameraController.Instance.OnSwipe;
EasyTouch.On_Drag += CameraController.Instance.OnSwipe;
// 只監(jiān)聽(tīng)一個(gè)手指的滑動(dòng)手勢(shì) 用gesture.touchCount判斷
public void OnSwipe(Gesture gesture)
{
if (gesture.touchCount > 1)
{
return;
}
Move(gesture.swipeVector);
}
public void OnPinch(Gesture gesture)
{
Zoom(gesture.deltaPinch);
}
// 移動(dòng)攝像機(jī)
private void Move(Vector2 swipeVector)
{
...
}
// 攝像機(jī)拉近拉遠(yuǎn)
private void Zoom(float deltaPinch)
{
...
}
二. 相機(jī)lookat一個(gè)坐標(biāo)點(diǎn)的簡(jiǎn)單模型
相機(jī)以某個(gè)視角eulerAngles肤粱,距離目標(biāo)坐標(biāo)點(diǎn)distanceFromTarget厨相,lookat這個(gè)坐標(biāo)點(diǎn):
private void CameraLookatPos(Vector3 eulerAngles, float distanceFromTarget)
{
Vector3 lookatPos = GetLookatPos();
Quaternion q = Quaternion.Euler(eulerAngles);
transform.position = lookatPos - q * Vector3.forward * distanceFromTarget
transform.eulerAngles = eulerAngles
}
腳本掛在Camera上
三. 相機(jī)移動(dòng)縮放
- 使用增量記錄本次移動(dòng)縮放的變化值
- 在LateUpdate中领曼,根據(jù)相機(jī)距離蛮穿,插值計(jì)算當(dāng)前相機(jī)視角庶骄,設(shè)置相機(jī)位置
- 地圖邊界檢測(cè)
- 若合法践磅,則把移動(dòng)縮放增量加到總值单刁;
- 若檢測(cè)到越界府适,非法羔飞,則把移動(dòng)縮放增量舍棄,并在同一幀 重新設(shè)置位置position與角度eulerAngles
代碼經(jīng)過(guò)刪減簡(jiǎn)化褥傍,外部設(shè)置參數(shù)部分刪除儡嘶,僅展示移動(dòng)縮放的處理流程
private Vector3 _MovePos = Vector3.zero; // Move操作的總位移offset
private float distanceFromTarget恍风;// 當(dāng)前相機(jī)距目標(biāo)的距離,縮放操作才能改變
private Vector3 _IncreMoveVector = Vector3.zero; // Move操作的本次操作增量
private float _IncreCameraDis = 0; // Zoom 縮放操作的本次操作增量
private Vector3 _cameraEuler = Vector3.zero; // 相機(jī)距離最近時(shí)的視角朋贬,外部設(shè)置
... MIN_CAMERA_DIS; // 相機(jī)高度最低,外部設(shè)置
... VERTICAL_CAMERA_DIS; // 相機(jī)高度-垂直點(diǎn)窜骄,外部設(shè)置
... MAX_CAMERA_DIS; // 相機(jī)高度最高,外部設(shè)置
... FINAL_ANGLE邻遏; // 縮小到最小的視角,默認(rèn)是90度 俯視准验,外部設(shè)置
// 移動(dòng)攝像機(jī) 記錄增量
private void Move(Vector2 swipeVector)
{
// 計(jì)算的偏移與邊界處理有關(guān)
_IncreMoveVector.x = 計(jì)算的偏移X赎线;//-swipeVector.x * MOVE_FACTOR;
_IncreMoveVector.z = 計(jì)算的偏移Z糊饱;//-swipeVector.y * MOVE_FACTOR;
}
// 攝像機(jī)拉近拉遠(yuǎn) 記錄增量
private void Zoom(float deltaPinch)
{
// 計(jì)算的偏移與邊界處理有關(guān)
_IncreCameraDis = Mathf.Min(MAX_CAMERA_DIS, Mathf.Max(MIN_CAMERA_DIS, distanceFromTarget + deltaPinch * PINCH_FACTOR)) - distanceFromTarget;
}
private Vector3 GetMovePos()
{
return _MovePos + _IncreMoveVector;
}
private float GetCameraDis()
{
return distanceFromTarget + _IncreCameraDis;
}
// 線性插值 得出當(dāng)前高度的視角
private Quaternion GetCameraCurrAngle(float t)
{
if (t < 0 || t >= 1)
{
return Quaternion.Euler(FINAL_ANGLE, _cameraEuler.y, 0);
}
return Quaternion.Lerp(Quaternion.Euler(_cameraEuler.x, _cameraEuler.y, 0), Quaternion.Euler(FINAL_ANGLE, _cameraEuler.y, 0), t);
}
private void CameraGesture()
{
Vector3 lookatPos = GetLookatPos();
Quaternion q = GetCameraCurrAngle((GetCameraDis() - MIN_CAMERA_DIS) / (VERTICAL_CAMERA_DIS - MIN_CAMERA_DIS));
transform.position = lookatPos - q * Vector3.forward * GetCameraDis() + GetMovePos();
transform.eulerAngles = q.eulerAngles;
}
private void UpdateCamera()
{
...
CameraGesture()
...
}
private void LateUpdate()
{
UpdateCamera();
if (_IncreCameraDis == 0 || _IncreMoveVector == Vector3.zero)
{
return;
}
// 邊界檢測(cè)
if (CheckBoundary()) // 校驗(yàn)本次移動(dòng)縮放合法,則把移動(dòng)縮放增量加到總值
{
_MovePos += _IncreMoveVector;
distanceFromTarget += _IncreCameraDis;
_IncreMoveVector = Vector3.zero;
_IncreCameraDis = 0;
}
else // 校驗(yàn)本次移動(dòng)縮放越界另锋,非法,則把移動(dòng)縮放增量舍棄夭坪,并在同一幀 重新設(shè)置位置position與角度eulerAngles
{
_IncreMoveVector = Vector3.zero;
_IncreCameraDis = 0;
UpdateCamera();
}
}