溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么用Unity實(shí)現(xiàn)掘地求升游戲

發(fā)布時(shí)間:2022-01-11 15:49:22 來源:億速云 閱讀:261 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹了怎么用Unity實(shí)現(xiàn)掘地求升游戲的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇怎么用Unity實(shí)現(xiàn)掘地求升游戲文章都會(huì)有所收獲,下面我們一起來看看吧。

實(shí)現(xiàn)方法

1.場(chǎng)景搭建

說干就干,我們來實(shí)際操作一下。

新建一個(gè)場(chǎng)景,用簡(jiǎn)易的3D物體來組裝成猛男和錘子,掛上不同的材質(zhì)用顏色區(qū)分一下。

怎么用Unity實(shí)現(xiàn)掘地求升游戲

然后分別掛上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));
 }

效果如圖:


怎么用Unity實(shí)現(xiàn)掘地求升游戲

但是現(xiàn)在問題來了,因?yàn)橹皇呛?jiǎn)單模擬功能的效果,所以猛男并沒有手,但是最終我們是希望錘子活動(dòng)的范圍離猛男有一個(gè)最大距離的限制,這樣看起來好像是有一只無形的手來操作錘子一樣,該如何計(jì)算這個(gè)范圍呢?

怎么用Unity實(shí)現(xiàn)掘地求升游戲


由圖可見這個(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è)合適的值,效果如下:

怎么用Unity實(shí)現(xiàn)掘地求升游戲


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;   
 }

最后效果如下:

怎么用Unity實(shí)現(xiàn)掘地求升游戲

關(guān)于“怎么用Unity實(shí)現(xiàn)掘地求升游戲”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“怎么用Unity實(shí)現(xiàn)掘地求升游戲”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(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)容。

AI