Unity3D實(shí)現(xiàn)相機(jī)跟隨控制
本文實(shí)例為大家分享了Unity3D實(shí)現(xiàn)相機(jī)跟隨控制的具體代碼,供大家參考,具體內(nèi)容如下
跟隨算法
要實(shí)現(xiàn)3D攝像機(jī)的控制第一步就是先實(shí)現(xiàn)攝像機(jī)跟隨物體移動(dòng)。
要想讓相機(jī)跟隨物體移動(dòng),就要明白在一定角度下相機(jī)與物體的位置關(guān)系。
首先設(shè)置相機(jī)與物體之間的距離distance,相機(jī)與xz平面的角度為roll
所以根據(jù)三角關(guān)系可以求得映射在xz平面的距離d為distancecos(rool),相機(jī)高度為distancesin(roll)。
如下圖
現(xiàn)在就可以確定相機(jī)的高度了即y軸的坐標(biāo)相機(jī)的y軸坐標(biāo)應(yīng)該為 Camera.Main.y=物體.y+height
在xz平面中,設(shè)相機(jī)與物體的距離為d(就是上面說的那個(gè)d,distance映射在xz平面的長(zhǎng)度),相機(jī)的旋轉(zhuǎn)角度為rot。根據(jù)下圖可以看到,相機(jī)與物體的連線與x軸的角度為rot-180.根據(jù)三角函數(shù),既可以得出x軸的位移為d*sin(rot) ,z軸的位移為d*cos(rot) 。
所以說開始的時(shí)候指定distance和rot和roll就可以實(shí)現(xiàn)跟隨了。實(shí)現(xiàn)跟隨的代碼如下
public class CameraFollow : MonoBehaviour { //距離 public float distance = 15; //橫向角度 public float rot = 0; //縱向角度 30d度 public float roll = 30f * Mathf.PI * 2 / 360; //目標(biāo)物體 public GameObject target; private void Start() { target = GameObject.Find("Black Track"); } private void LateUpdate() { if (target == null) return; if (Camera.main == null) return; //目標(biāo)的坐標(biāo) Vector3 targetPos = target.transform.position; //用三角函數(shù)計(jì)算相機(jī)的位置 Vector3 cameraPos; float d = distance * Mathf.Cos(roll); float height = distance * Mathf.Sin(roll); cameraPos.x = targetPos.x + d * Mathf.Cos(rot); cameraPos.z = targetPos.z + d * Mathf.Sin(rot); cameraPos.y = targetPos.y + height; Camera.main.transform.position = cameraPos; Camera.main.transform.LookAt(target.transform); } }
在跟隨的時(shí)候我們可以在要跟隨的物體下放置一個(gè)子物體命名為cameraPoint使相機(jī)對(duì)準(zhǔn)這個(gè)子物體從而方便的更改攝像機(jī)的視角。
所以在物體下添加一個(gè)cameraPoint的子物體
并且添加代碼
//設(shè)置目標(biāo) public void SetTarget(GameObject target) { if (target.transform.Find("cameraPoint") != null) this.target = target.transform.Find("cameraPoint").gameObject; else this.target = target; }
如果準(zhǔn)的物體有名為cameraPoint的子物體,那么相機(jī)對(duì)準(zhǔn)cameraPoint子物體。
橫向與縱向旋轉(zhuǎn)攝像機(jī)
當(dāng)鼠標(biāo)向左移動(dòng)時(shí),相機(jī)隨之左轉(zhuǎn),當(dāng)鼠標(biāo)向右移動(dòng)時(shí),相機(jī)隨之右轉(zhuǎn)。
Unity的輸入軸Mouse X 和 Mouse Y 代表著鼠標(biāo)的移動(dòng)增量,也就是說當(dāng)鼠標(biāo)向左移動(dòng)時(shí),Input.GetAxis(“Mouse X”)的值會(huì)增大,向右則減少。只要讓旋轉(zhuǎn)角度rot與Mouse X成正比關(guān)系,便能通過鼠標(biāo)控制攝像機(jī)的角度。
代碼如下
//橫向旋轉(zhuǎn)速度 public float rotSpeed=0.1f; //橫向旋轉(zhuǎn) public void Rotate() { float w = Input.GetAxis("Mouse X") * rotSpeed; rot -= w; }
同理對(duì)于縱向旋轉(zhuǎn)我們需要設(shè)定一個(gè)范圍 所以代碼如下
//縱向旋轉(zhuǎn)角度 public float maxRoll = 70f * Mathf.PI * 2 / 360; public float minRoll = 0f * Mathf.PI * 2 / 360; //縱向旋轉(zhuǎn)速度 private float rollSpeed = 0.1f; //縱向旋轉(zhuǎn) public void Roll() { float w = Input.GetAxis("Mouse Y") * rollSpeed; roll -= w; if (roll > maxRoll) roll = maxRoll; if (roll < minRoll) roll = minRoll; }
滾輪調(diào)節(jié)距離
通過鼠標(biāo)滾輪調(diào)整相機(jī)與物體之間的距離
代碼如下
//距離范圍 public float maxDistance = 22f; public float minDistance = 5f; //距離變化速度 public float zoomSpeed = 0.2f; //調(diào)整距離 public void Zoom() { if(Input.GetAxis("Mouse ScrollWheel") >0) { if (distance > minDistance) distance -= zoomSpeed; } else if (Input.GetAxis("Mouse ScrollWheel") < 0) { if (distance < maxDistance) distance += zoomSpeed; } }
全部代碼
public class CameraFollow : MonoBehaviour { //距離 public float distance = 15; //橫向角度 public float rot = 0; //縱向角度 30d度 public float roll = 30f * Mathf.PI * 2 / 360; //目標(biāo)物體 public GameObject target; //橫向旋轉(zhuǎn)速度 public float rotSpeed=0.1f; //縱向旋轉(zhuǎn)角度 public float maxRoll = 70f * Mathf.PI * 2 / 360; public float minRoll = 0f * Mathf.PI * 2 / 360; //縱向旋轉(zhuǎn)速度 private float rollSpeed = 0.1f; //距離范圍 public float maxDistance = 22f; public float minDistance = 5f; //距離變化速度 public float zoomSpeed = 0.2f; private void Start() { target = GameObject.Find("Black Track"); SetTarget(target); } private void LateUpdate() { if (target == null) return; if (Camera.main == null) return; //橫向旋轉(zhuǎn) Rotate(); //縱向旋轉(zhuǎn) Roll(); //縮放 Zoom(); //目標(biāo)的坐標(biāo) Vector3 targetPos = target.transform.position; //用三角函數(shù)計(jì)算相機(jī)的位置 Vector3 cameraPos; float d = distance * Mathf.Cos(roll); float height = distance * Mathf.Sin(roll); cameraPos.x = targetPos.x + d * Mathf.Cos(rot); cameraPos.z = targetPos.z + d * Mathf.Sin(rot); cameraPos.y = targetPos.y + height; Camera.main.transform.position = cameraPos; Camera.main.transform.LookAt(target.transform); } //設(shè)置目標(biāo) public void SetTarget(GameObject target) { if (target.transform.Find("cameraPoint") != null) this.target = target.transform.Find("cameraPoint").gameObject; else this.target = target; } //橫向旋轉(zhuǎn) public void Rotate() { float w = Input.GetAxis("Mouse X") * rotSpeed; rot -= w; } //縱向旋轉(zhuǎn) public void Roll() { float w = Input.GetAxis("Mouse Y") * rollSpeed; roll -= w; if (roll > maxRoll) roll = maxRoll; if (roll < minRoll) roll = minRoll; } //調(diào)整距離 public void Zoom() { if(Input.GetAxis("Mouse ScrollWheel") >0) { if (distance > minDistance) distance -= zoomSpeed; } else if (Input.GetAxis("Mouse ScrollWheel") < 0) { if (distance < maxDistance) distance += zoomSpeed; } } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# 數(shù)組刪除元素的實(shí)現(xiàn)示例
本文主要介紹了C# 數(shù)組刪除元素的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08C#實(shí)現(xiàn)DVD借出歸還管理系統(tǒng)
這篇文章主要介紹了C#實(shí)現(xiàn)DVD借出歸還管理系統(tǒng),類似DVD管理器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06C#應(yīng)用XML作為數(shù)據(jù)庫的快速開發(fā)框架實(shí)現(xiàn)方法
這篇文章主要介紹了C#應(yīng)用XML作為數(shù)據(jù)庫的快速開發(fā)框架實(shí)現(xiàn)方法,詳細(xì)介紹了將XML作為數(shù)據(jù)庫的C#桌面應(yīng)用開發(fā)技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12unity實(shí)現(xiàn)弧形移動(dòng) 可角度自定
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)弧形移動(dòng),可角度自定,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06用Linq從一個(gè)集合選取幾列得到一個(gè)新的集合(可改列名)
這篇文章主要介紹了用Linq從一個(gè)集合選取幾列得到一個(gè)新的集合(可改列名),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12算法證明每一位都相同十進(jìn)制數(shù)不是完全平方數(shù)
這篇文章主要為大家介紹了算法證明每一位都相同十進(jìn)制數(shù)不是完全平方數(shù)的過程論述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05