Unity實現(xiàn)彈弓功能

寫在前面

實現(xiàn)類似于憤怒的小鳥中的彈弓功能。

功能

  • 拖拽小鳥松開時發(fā)射
  • 拖拽范圍的限制

實現(xiàn)

  1. 首先要用到Unity中的一個物理組件,Spring Joint 2D往湿。它就是一個彈簧連接,就相當于兩個物體間用彈簧連接一樣研侣。不管兩個物體大于或者小于某固定的距離,都會產(chǎn)生相互作用的力楞泼。而且伴有彈性系數(shù)等驰徊。具體屬性如下圖(001):


    001.png
  2. 讓物體跟隨鼠標移動,因為鼠標是屏幕坐標系堕阔,需要轉(zhuǎn)化為世界坐標系才能賦值使用棍厂。由于是2D場景,在轉(zhuǎn)化后要修改下z軸超陆,不然會看不到物體牺弹,代碼如下:

transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position += new Vector3(0, 0, 10);
  1. 之后給拖拽限定一個范圍,讓物體在有效的范圍內(nèi)移動时呀。對此张漂,在彈弓上(Sprite圖)上創(chuàng)建一個節(jié)點(CenterObject),計算出物體到節(jié)點的方向谨娜,在定義一個距離最大值鹃锈。
if (Vector3.Distance(transform.position, CenterObject.position) > MaxDistance) {

                Vector3 pos1 = (transform.position - CenterObject.position).normalized;
                pos1 *= MaxDistance;
                transform.position = CenterObject.position + pos1;
            }

重點討論

憤怒的小鳥的彈弓功能有一個小細節(jié),就是拖拽物體碰到弓柄的時候不會透過弓柄瞧预,而是往上拉到發(fā)射口屎债,這樣顯得更加真實仅政,大致實現(xiàn)方法如下:
1 . 在會發(fā)生碰撞的地方設(shè)置碰撞體,設(shè)置IsTrigger為true盆驹。
2 . 添加監(jiān)聽事件

void OnTriggerEnter2D(Collider2D collider)
    {
        IsTrigger = true;
    }

 void OnTriggerExit2D(Collider2D collider)
    {
       IsTrigger = false;
    }

3 . 當觸發(fā)碰撞體時圆丹,將拖拽最大距離縮小,將其拉到發(fā)射口躯喇。當離開碰撞體時辫封,再將距離拉大。注意廉丽,以下代碼中第一個if代碼塊,當物體運動到發(fā)射口時倦微,且此時不再觸發(fā)碰撞體,就不會縮短距離了正压,反之增加距離欣福,這是受跟隨鼠標的影響往下移動又觸發(fā)碰撞體,產(chǎn)生了抖動的情況焦履。要避開這種情況拓劝,就是當物體處于發(fā)射口時不要增加距離。

 void OnSetpOver()
    {

         if (Vector3.Distance(transform.position, ButtomObject.position) < 0.2)
            {
                IsAddDistance = false;
            }

            else
                IsAddDistance = true;

            if (IsTrigger) 
            {
                if (IsMove)
                    MaxDistance -= 0.1f;
            }
            else
            {
                if (IsMove && MaxDistance< 0.9f && IsAddDistance)
                {
                    MaxDistance += 0.1f;
                }
            }
    }

功能源碼

文末有項目下載地址嘉裤,結(jié)合項目更容易理解郑临。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Brid : MonoBehaviour {

    //鼠標是否按下
    private bool IsClick;

    //是否觸發(fā)了碰撞體
    private bool IsTrigger;

    //鼠標是否在移動
    private bool IsMove;

    //是否允許拉長距離
    private bool IsAddDistance;

    //能夠拖拽小鳥的最長距離
    public float MaxDistance;

    //記錄鼠標0.02s前的位置
    private Vector3 firstpos;

    //計時
    private float timer = 0f;

    
    private SpringJoint2D Sp;
    private Rigidbody2D rig2d;
    public CapsuleCollider2D TargetCollider;

    public LineRenderer right;
    public Transform Rightobject;
    public Transform ButtomObject;
    public Transform Target;
    public Transform CenterObject;

    public LineRenderer left;
    public Transform Leftobject;
     
    void Awake()
    { 
        Sp = GetComponent<SpringJoint2D> ();
        rig2d = GetComponent<Rigidbody2D> ();
    }

    void OnMouseDown()
    {
        IsClick = true;
        rig2d.isKinematic = true;
    }



    void OnMouseUp()
    {
        IsClick = false;
        rig2d.isKinematic = false;
        TargetCollider.enabled = false;
        Invoke("Fly", 0.1f);
         
    }

    void OnTriggerEnter2D(Collider2D collider)
    {
        IsTrigger = true;
    }

    void OnTriggerExit2D(Collider2D collider)
    {
        IsTrigger = false;
    }

    void FixedUpdate () 
    {
        if (IsClick)
        {
            transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position += new Vector3(0, 0, 10);

            if (Vector3.Distance(transform.position, CenterObject.position) > MaxDistance) {

                Vector3 pos1 = (transform.position - CenterObject.position).normalized;
                pos1 *= MaxDistance;
                transform.position = CenterObject.position + pos1;
            }
            Line();
            OnSetpOver();
        }

        OnMouseMove();
    }

    void Fly()
    {
        Sp.enabled = false;
    }

    void Line()
    {
        right.SetPosition (0, Rightobject.position);
        right.SetPosition (1, transform.position);
        left.SetPosition (0, Leftobject.position);
        left.SetPosition (1, transform.position);
    }

    void Cancel()
    {
        
    }

    void OnMouseMove()
    {
        if (timer < 0.02f)
        {
            firstpos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            timer += Time.fixedDeltaTime;

        }
        else
        {
            if (firstpos != Camera.main.ScreenToWorldPoint(Input.mousePosition))
            {
                IsMove = true;
            }
            else
                IsMove = false;
            timer = 0;
        }
    }

    void OnSetpOver()
    {
         if (Vector3.Distance(transform.position, ButtomObject.position) < 0.2)
            {
                IsAddDistance = false;
            }

            else
                IsAddDistance = true;

            if (IsTrigger) 
            {
                if (IsMove)
                    MaxDistance -= 0.1f;
            }
            else
            {
                if (IsMove && MaxDistance< 0.9f && IsAddDistance)
                {
                    MaxDistance += 0.1f;
                }
            }
    }
}

結(jié)語

以上代碼實現(xiàn)的拖動看起來不是很順暢,更真正的憤怒的小鳥比起來顯得有些僵硬屑宠,如果讀者有更好的解決方案請告訴我厢洞。

項目下載地址:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市典奉,隨后出現(xiàn)的幾起案子躺翻,更是在濱河造成了極大的恐慌,老刑警劉巖秋柄,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件获枝,死亡現(xiàn)場離奇詭異蠢正,居然都是意外死亡骇笔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門嚣崭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笨触,“玉大人,你說我怎么就攤上這事雹舀÷樱” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵说榆,是天一觀的道長虚吟。 經(jīng)常有香客問我寸认,道長,這世上最難降的妖魔是什么串慰? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任偏塞,我火速辦了婚禮,結(jié)果婚禮上邦鲫,老公的妹妹穿的比我還像新娘灸叼。我一直安慰自己,他們只是感情好庆捺,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布古今。 她就那樣靜靜地躺著,像睡著了一般滔以。 火紅的嫁衣襯著肌膚如雪捉腥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天醉者,我揣著相機與錄音但狭,去河邊找鬼。 笑死撬即,一個胖子當著我的面吹牛立磁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剥槐,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼唱歧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了粒竖?” 一聲冷哼從身側(cè)響起颅崩,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蕊苗,沒想到半個月后沿后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡朽砰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年尖滚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞧柔。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡漆弄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出造锅,到底是詐尸還是另有隱情撼唾,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布哥蔚,位于F島的核電站倒谷,受9級特大地震影響蛛蒙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渤愁,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一宇驾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猴伶,春花似錦课舍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至办桨,卻和暖如春筹淫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背呢撞。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工损姜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殊霞。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓摧阅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绷蹲。 傳聞我的和親對象是個殘疾皇子棒卷,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Unity3D塔防開發(fā)流程 配置環(huán)境及場景搭建 編程語言:C#,略懂些許設(shè)計模式祝钢,如果不了解設(shè)計模式比规,BUG Mo...
    Grape_葡萄閱讀 2,947評論 1 3
  • 在我們的游戲開發(fā)過程中,有一個很重要的工作就是進行碰撞檢測拦英。例如在射擊游戲中子彈是否擊中敵人蜒什,在RPG游戲中是否撿...
    壹米玖坤閱讀 24,393評論 0 17
  • 事件(event)的觸發(fā)是PlayMaker交互設(shè)計的基礎(chǔ)。 鼠標(mouse)疤估、鍵盤(keyboard)灾常、按鈕(...
    shimmery閱讀 13,255評論 0 23
  • 111. [動畫系統(tǒng)]如何將其他類型的動畫轉(zhuǎn)換成關(guān)鍵幀動畫? 動畫->點緩存->關(guān)鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,046評論 3 90
  • 曼殊菲兒2018.1.15堅持記錄252天 冥想 意志力實驗:5分鐘訓練大腦冥想 專心呼吸...
    曼殊斐兒_bcbb閱讀 315評論 0 2