您好,登錄后才能下訂單哦!
這篇文章主要介紹了怎么用Unity實(shí)現(xiàn)掘地求升游戲的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇怎么用Unity實(shí)現(xiàn)掘地求升游戲文章都會(huì)有所收獲,下面我們一起來看看吧。
1.場(chǎng)景搭建
說干就干,我們來實(shí)際操作一下。
新建一個(gè)場(chǎng)景,用簡(jiǎn)易的3D物體來組裝成猛男和錘子,掛上不同的材質(zhì)用顏色區(qū)分一下。
然后分別掛上Rigibody,因?yàn)槲覀兿氲氖亲?D平面運(yùn)行,因此在Rigibody上分別鎖了Z軸的移動(dòng)和X,Y軸的旋轉(zhuǎn),順便把錘子上的重力去掉,因?yàn)榇龝?huì)要用代碼去控制錘子的位置。
2.控制錘頭
新建一個(gè)腳本掛載在父節(jié)點(diǎn)上,分別獲取身體和錘子。
我們想要的效果是錘子能一直跟隨鼠標(biāo)移動(dòng)且錘頭一直指向鼠標(biāo),思路是在錘頭添加一個(gè)空的子節(jié)點(diǎn)作為錘頭的錨點(diǎn),然后讓整個(gè)錘子圍繞著這個(gè)錨點(diǎn)的Z軸旋轉(zhuǎn)讓錘柄指向身體的方向。
public GameObject body;public GameObject hammer;Rigidbody body_rig;Rigidbody hammer_rig;Transform hammer_anchor;void Start(){ body_rig = body.GetComponent<Rigidbody>(); hammer_rig = hammer.GetComponent<Rigidbody>(); hammer_anchor = hammer.transform.GetChild(2);}//物理相關(guān)的操作一般最好放在FixedUpdate里進(jìn)行,與系統(tǒng)的物理計(jì)算保持同步 private void FixedUpdate() { HammerControl(); }void HammerControl(){ //獲取鼠標(biāo)在屏幕上的坐標(biāo)并轉(zhuǎn)換為世界坐標(biāo) Vector2 MousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); //通過修改錘子身上剛體的速度讓錘子移動(dòng),向量的起點(diǎn)用錘頭的坐標(biāo) //注意這里要讓錘頭的錨點(diǎn)與錘子本身的坐標(biāo)的Z值相等,為了讓旋轉(zhuǎn)軸與世界坐標(biāo)的Z軸平行,同理鼠標(biāo)坐標(biāo)的Z值也直接使用錘子的坐標(biāo)的Z值 hammer_rig.velocity = (new Vector3(MousePosition.x, MousePosition.y, hammer.transform.position.z) - hammer_anchor.position) * 10; //獲取身體到鼠標(biāo)的方向 Vector3 direction = (new Vector3(MousePosition.x, MousePosition.y, hammer_anchor.position.z) - new Vector3(body.transform.position.x, body.transform.position.y, hammer_anchor.position.z)).normalized; //讓錘子沿著錘頭錨點(diǎn)轉(zhuǎn)向身體的方向 hammer.transform.RotateAround(hammer_anchor.position, Vector3.Cross(hammer_anchor.up, direction), Vector3.Angle(hammer_anchor.up, direction)); }
效果如圖:
但是現(xiàn)在問題來了,因?yàn)橹皇呛?jiǎn)單模擬功能的效果,所以猛男并沒有手,但是最終我們是希望錘子活動(dòng)的范圍離猛男有一個(gè)最大距離的限制,這樣看起來好像是有一只無形的手來操作錘子一樣,該如何計(jì)算這個(gè)范圍呢?
由圖可見這個(gè)問題的思路是,當(dāng)錘頭錨點(diǎn)在最大活動(dòng)范圍里面時(shí)是跟著鼠標(biāo)的坐標(biāo)走,當(dāng)處于最大活動(dòng)范圍外的時(shí)候是跟著錘頭錨點(diǎn)與身體坐標(biāo)的向量和最大移動(dòng)范圍形成的圓的交點(diǎn)走。這個(gè)思路用于代碼上就是當(dāng)鼠標(biāo)移動(dòng)到最大距離范圍之外時(shí)得到當(dāng)前身體到鼠標(biāo)位置的方向向量,然后讓這個(gè)向量的長(zhǎng)度等于最大距離的長(zhǎng)度。
那么,我們?cè)诖嘶A(chǔ)上修改一下代碼。
public float MaxDistance; float RelativeDistance;//單獨(dú)抽出一個(gè)函數(shù)獲取最大距離以外的轉(zhuǎn)換后的鼠標(biāo)坐標(biāo) Vector2 GetConfinedPosition(Vector2 mouseposition) { Vector2 Confined_MousePosition; //去掉body坐標(biāo)的Z值,避免計(jì)算距離時(shí)的影響 Vector2 body_position = new Vector2(body.transform.position.x, body.transform.position.y); //計(jì)算當(dāng)前鼠標(biāo)位置和身體位置的相對(duì)距離 RelativeDistance = Vector2.Distance(mouseposition, body_position); if (RelativeDistance > MaxDistance) { //當(dāng)相對(duì)距離大于自己設(shè)置的最大距離時(shí),獲取轉(zhuǎn)換以后的目標(biāo)坐標(biāo) //這里的思路需要稍稍轉(zhuǎn)一個(gè)彎,一開始是獲取的是長(zhǎng)度為最大距離,方向?yàn)樯眢w到鼠標(biāo)方向的向量。 //在這個(gè)基礎(chǔ)上加上身體的當(dāng)前坐標(biāo),其等于是將這個(gè)向量的起始點(diǎn)設(shè)置為身體的坐標(biāo)。 //最后向量與坐標(biāo)點(diǎn)可以直接相互轉(zhuǎn)換,此時(shí)轉(zhuǎn)換后的目標(biāo)坐標(biāo)就等于這個(gè)向量。 Confined_MousePosition = (mouseposition - body_position).normalized * MaxDistance + body_position; } else { //若相對(duì)距離小于最大距離那么鼠標(biāo)當(dāng)前坐標(biāo)就是目標(biāo)坐標(biāo) Confined_MousePosition = mouseposition; } return Confined_MousePosition; }
然后把HammerControl()函數(shù)內(nèi)的MousePosition的賦值修改一下:
//獲取鼠標(biāo)在屏幕上的坐標(biāo)并轉(zhuǎn)換為世界坐標(biāo),若相對(duì)距離大于最大距離則獲得轉(zhuǎn)換后的坐標(biāo) Vector2 MousePosition = GetConfinedPosition(Camera.main.ScreenToWorldPoint(Input.mousePosition));
最后調(diào)整MaxDistance到一個(gè)合適的值,效果如下:
3.控制身體的逆向運(yùn)動(dòng)
現(xiàn)在離實(shí)現(xiàn)就差最后一步了,前面思考實(shí)現(xiàn)方式的時(shí)候說過,錘頭的移動(dòng)方向與理論上身體移動(dòng)的方向剛好是相反的,并且同為以身體重心為原點(diǎn),錘子的最大移動(dòng)距離為半徑的圓的切線。那么我們順著這個(gè)思路去做。
首先還有一個(gè)先決條件,錘子不能憑空受力,必須是杵在地上或者掛在障礙物上才行。
我們先在錘頭上加一個(gè)碰撞盒子并在錘子上添加一個(gè)新建腳本,用幾句簡(jiǎn)單的代碼用來檢測(cè)錘頭是否碰撞到東西。
public class CollisionDetection : MonoBehaviour { public bool IsCollision; private void OnCollisionEnter(Collision collision) { IsCollision = true; } private void OnCollisionExit(Collision collision) { IsCollision = false; } }
這里要注意的是錘子是錘頭的父物體,所以即便碰撞盒子不在錘子上,作為父物體的錘子依然能檢測(cè)到子物體上的碰撞信息,反過來由于錘頭上并沒有剛體組件,所以腳本掛在錘頭上是檢測(cè)不到碰撞信息的。
然后當(dāng)檢測(cè)到碰撞時(shí)給予身體一個(gè)相反的速度值。
void HammerControl() { //在給hammer_rig.velocity賦值后添加下面的代碼 if(hammer.GetComponent<CollisionDetection>().IsCollision) { BodyControl(hammer_rig.velocity); } } void BodyControl(Vector3 velociy) { body_rig.velocity = -velociy; }
最后效果如下:
關(guān)于“怎么用Unity實(shí)現(xiàn)掘地求升游戲”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“怎么用Unity實(shí)現(xiàn)掘地求升游戲”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。