Unity3D使用鼠標旋轉縮放平移視角
Unity使用鼠標旋轉縮放平移視角,供大家參考,具體內容如下
用代碼在Game界面完美實現Scene界面的操作方法。
使用方法:把腳本掛在相機上,把跟蹤的target拖到腳本上。
視角跟蹤的是一個空物體,當然如果你是做RPG游戲需要跟蹤某一角色的視角,那就不需要中鍵平移功能,把空物體換成角色就行。
代碼主要是分三部分功能進行實現。
1.右鍵拖動控制視角的旋轉;
2.滾輪旋轉控制視角的縮放;
3.中鍵拖動控制視角的平移。
右鍵拖動控制旋轉主要是用GetAxis獲得鼠標在x方向與y方向平移的距離,相機的旋轉是通過旋轉相機本體坐標系的x軸與y軸實現的,重要的是在旋轉相機的同時,要控制相機和target物體的相對距離,即同時控制相機繞target物體的旋轉。這個網上多數實現都相同,不贅述
中鍵滾輪控制視角的縮放,定義Distance變量控制相機與target的距離(相機z軸方向的距離),用GetAxis獲得滾輪旋轉的程度,控制Distance的變動。這里和網上已有的方法也沒什么區(qū)別。
中鍵拖動控制視角的平移,之前在網上查找相關的實現,結果實際效果都比較差,所以自己實現了一下。視角的平移是通過獲取中鍵在屏幕坐標系下的平移的方向向量,然后轉換為世界坐標系下的target坐標的平移,然后調整相機的位置進行相應的平移以保證旋轉和縮放不受影響。
屏幕坐標系的平移轉換到世界坐標系下的平移,本質上就是世界坐標系下沿著相機的本體坐標系的x與y軸進行相應的平移。所以只需要求出屏幕坐標系x與y方向的平移,分別乘以相機x與y軸的方向向量,然后與target原來的坐標相加,就可以獲得target平移后的位置,再將相機的位置平移過去即實現了視角的平移,這種平移保證了相機平面和target之間的相對距離保持不變。具體代碼如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLookTest : MonoBehaviour {
//相機跟隨的目標物體,一般是一個空物體
public Transform target;
private int MouseWheelSensitivity = 1; //滾輪靈敏度設置
private int MouseZoomMin = 1; //相機距離最小值
private int MouseZoomMax = 20; //相機距離最大值
private float moveSpeed = 10; //相機跟隨速度(中鍵平移時),采用平滑模式時起作用,越大則運動越平滑
private float xSpeed = 250.0f; //旋轉視角時相機x軸轉速
private float ySpeed = 120.0f; //旋轉視角時相機y軸轉速
private int yMinLimit = -360;
private int yMaxLimit = 360;
private float x = 0.0f; //存儲相機的euler角
private float y = 0.0f; //存儲相機的euler角
private float Distance = 5; //相機和target之間的距離,因為相機的Z軸總是指向target,也就是相機z軸方向上的距離
private Vector3 targetOnScreenPosition; //目標的屏幕坐標,第三個值為z軸距離
private Quaternion storeRotation; //存儲相機的姿態(tài)四元數
private Vector3 CameraTargetPosition; //target的位置
private Vector3 initPosition; //平移時用于存儲平移的起點位置
private Vector3 cameraX; //相機的x軸方向向量
private Vector3 cameraY; //相機的y軸方向向量
private Vector3 cameraZ; //相機的z軸方向向量
private Vector3 initScreenPos; //中鍵剛按下時鼠標的屏幕坐標(第三個值其實沒什么用)
private Vector3 curScreenPos; //當前鼠標的屏幕坐標(第三個值其實沒什么用)
void Start () {
//這里就是設置一下初始的相機視角以及一些其他變量,這里的x和y。。。是和下面getAxis的mouse x與mouse y對應
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
CameraTargetPosition = target.position;
storeRotation = Quaternion.Euler (y + 60, x, 0);
transform.rotation = storeRotation; //設置相機姿態(tài)
Vector3 position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元數表示一個旋轉,四元數乘以向量相當于把向量旋轉對應角度,然后加上目標物體的位置就是相機位置了
transform.position = storeRotation * new Vector3 (0, 0, -Distance) + CameraTargetPosition; //設置相機位置
// Debug.Log("Camera x: "+transform.right);
// Debug.Log("Camera y: "+transform.up);
// Debug.Log("Camera z: "+transform.forward);
// //-------------TEST-----------------
// testScreenToWorldPoint();
}
void Update () {
//鼠標右鍵旋轉功能
if (Input.GetMouseButton (1)) {
x += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle (y, yMinLimit, yMaxLimit);
storeRotation = Quaternion.Euler (y + 60, x, 0);
var position = storeRotation * new Vector3 (0.0f, 0.0f, -Distance) + CameraTargetPosition;
transform.rotation = storeRotation;
transform.position = position;
} else if (Input.GetAxis ("Mouse ScrollWheel") != 0) //鼠標滾輪縮放功能
{
if (Distance >= MouseZoomMin && Distance <= MouseZoomMax) {
Distance -= Input.GetAxis ("Mouse ScrollWheel") * MouseWheelSensitivity;
}
if (Distance < MouseZoomMin) {
Distance = MouseZoomMin;
}
if (Distance > MouseZoomMax) {
Distance = MouseZoomMax;
}
var rotation = transform.rotation;
transform.position = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + CameraTargetPosition;
}
//鼠標中鍵平移
if (Input.GetMouseButtonDown (2)) {
cameraX = transform.right;
cameraY = transform.up;
cameraZ = transform.forward;
initScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
Debug.Log ("downOnce");
//targetOnScreenPosition.z為目標物體到相機xmidbuttonDownPositiony平面的法線距離
targetOnScreenPosition = Camera.main.WorldToScreenPoint (CameraTargetPosition);
initPosition = CameraTargetPosition;
}
if (Input.GetMouseButton (2)) {
curScreenPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
//0.01這個系數是控制平移的速度,要根據相機和目標物體的distance來靈活選擇
target.position = initPosition - 0.01f * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);
//重新計算位置
Vector3 mPosition = storeRotation * new Vector3 (0.0F, 0.0F, -Distance) + target.position;
transform.position = mPosition;
// //用這個會讓相機的平移變得更平滑,但是可能在你buttonup時未使相機移動到應到的位置,導致再進行旋轉與縮放操作時出現短暫抖動
//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
}
if (Input.GetMouseButtonUp (2)) {
Debug.Log ("upOnce");
//平移結束把cameraTargetPosition的位置更新一下,不然會影響縮放與旋轉功能
CameraTargetPosition = target.position;
}
}
//將angle限制在min~max之間
static float ClampAngle (float angle, float min, float max) {
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
void testScreenToWorldPoint () {
//第三個坐標指的是在相機z軸指向方向上的距離
Vector3 screenPoint = Camera.main.WorldToScreenPoint (CameraTargetPosition);
Debug.Log ("ScreenPoint: " + screenPoint);
// var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
// Debug.Log("worldPosition: "+worldPosition);
}
}
實現的效果如下圖:
demo工程在此下載:MouseLookDemoWithUnity3D
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持我們。
您可能感興趣的文章
- 01-10C#使用Dispose模式實現手動對資源的釋放
- 01-10C#3.0使用EventLog類寫Windows事件日志的方法
- 01-10C#使用windows服務開啟應用程序的方法
- 01-10c# ArrayList的使用方法小總結
- 01-10C#使用ADO.Net部件來訪問Access數據庫的方法
- 01-10C#禁止textbox復制、粘貼、剪切及鼠標右鍵的方法
- 01-10C#使用Mutex簡單實現程序單實例運行的方法
- 01-10使用Nopcommerce為商城添加滿XX減XX優(yōu)惠券功能
- 01-10winform實現限制及解除鼠標移動范圍的方法
- 01-10C#中yield用法使用說明


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現txt定位指定行完整實例
- 01-10WinForm實現仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現讀取注冊表監(jiān)控當前操作系統已
隨機閱讀
- 01-10C#中split用法實例總結
- 01-10delphi制作wav文件的方法
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現頁面的局部加載
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文


