【Unity3D開發(fā)】簡單工廠模式

本文同時(shí)發(fā)布至我的個(gè)人博客,點(diǎn)擊進(jìn)入我的個(gè)人博客閱讀。本博客供技術(shù)交流與經(jīng)驗(yàn)分享,可自由轉(zhuǎn)載。轉(zhuǎn)載請?jiān)谠u論區(qū)或私信簡單通知,感謝!

游戲需求

  • 實(shí)現(xiàn)點(diǎn)擊效果。
  • Plane 或其他物體做地面, tag 為Finish
  • 點(diǎn)擊地面后,出現(xiàn)一個(gè)圓形攻擊標(biāo)記,兩秒后自動(dòng)消失。注意:該攻擊標(biāo)記不能擋住點(diǎn)擊。(Primitive Objects / Cylinder)
  • 請使用一個(gè)簡單工廠創(chuàng)建、管理這些的標(biāo)記,并自動(dòng)收回這些標(biāo)記(注意,這些對象創(chuàng)建后,放在列表內(nèi),不必釋放)。

效果展示:

實(shí)現(xiàn)過程

(一)CameraPlane 的基本配置

? 設(shè)置好Camera的位置與角度,并設(shè)置視圖為正交,如下圖:

? 為方便顯示,創(chuàng)建Plane后再添加一個(gè)Material,使其變?yōu)樗{(lán)色,如下圖:

(二)定義并實(shí)現(xiàn)EsayFactory

? 首先創(chuàng)建一個(gè)繼承MonoBehaviourBasecode類,自定義一個(gè)namespace并引用,在該namespace定義并實(shí)現(xiàn)EsayFactory類。

? EsayFactory類為工廠類,它負(fù)責(zé)管理Cylinder的創(chuàng)建、停用和重復(fù)使用。重復(fù)使用的實(shí)現(xiàn)主要通過講使用完畢的Cylinder加入一個(gè)List中,在需要時(shí)重新拿出使用的方法來實(shí)現(xiàn)。這樣做的好處是,避免了重復(fù)地創(chuàng)建和銷毀游戲?qū)ο螅軠p少游戲的內(nèi)存消耗。

? 需要注意的是:嚴(yán)格控制單實(shí)例,避免用戶創(chuàng)建多個(gè)EsayFactory對象。

public class EsayFactory : System.Object
{
    public List<GameObject> markList = new List<GameObject>();
    private static EsayFactory _factory;
    private Camera _camera;
    
    //控制單實(shí)例
    public static EsayFactory GetInstance()
    {
        if (_factory == null)
        {
            _factory = new EsayFactory();
            _factory._camera = Camera.main;
        }
        return _factory;
    }

    public void placeAttackMark(Vector3 target)
    {
        Ray _ray = _camera.ScreenPointToRay(target);
        RaycastHit _hit;
        if (Physics.Raycast(_ray, out _hit))
        {
            if (_hit.collider.gameObject.tag.Contains("Finish"))
            {
                GameObject attackMark;
                //List中若無可用對象則創(chuàng)建新對象
                if (markList.Count == 0)
                {
                    attackMark = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                    //避免Cylinder擋住點(diǎn)擊
                    attackMark.GetComponent<Collider>().enabled = false;
                }
                //若有可用對象則拿出重用
                else
                {
                    attackMark = markList[0];
                    markList.RemoveAt(0);
                }
            attackMark.transform.SetParent(_hit.collider.gameObject.transform);
            attackMark.transform.position = _hit.point;
              //添加一個(gè)自定義的實(shí)現(xiàn)了延時(shí)2s刪除功能的組件
            DelayToDelete _delay = attackMark.AddComponent<DelayToDelete>();
            _delay.delete(markList, attackMark, 2.0f);
        }
    }
}

(三)實(shí)現(xiàn)延時(shí)刪除

? DelayToDelete繼承MonoBehaviour類,實(shí)現(xiàn)了兩個(gè)方法:私有方法delayTo()實(shí)現(xiàn)了具體延時(shí)功能的實(shí)現(xiàn),公有方法delete()實(shí)現(xiàn)了具體的2秒后刪除的功能需求。這里采用了Action類來代替Invoke()方法,其好處是拓展性更強(qiáng),可讀性也更高。StartCoroutineMonoBehaviour中的一個(gè)調(diào)用協(xié)同程序的方法,通過使用 yield return new WaitForSeconds(delaySeconds);可以實(shí)現(xiàn)延時(shí)一定實(shí)現(xiàn)后執(zhí)行。

public class DelayToDelete : MonoBehaviour
{
    public void delete(List<GameObject> markList, GameObject attackMark, float  delaySeconds)
    {
        StartCoroutine(delayTo(() =>
        {
          //移出游戲范圍并加入List中等待重用
            attackMark.transform.position = new Vector3(0f, -99f, 0f);
            markList.Add(attackMark);
        }
        , 2.0f));
    }

    private IEnumerator delayTo(Action action, float delaySeconds)
    {
      //延時(shí)執(zhí)行action();
        yield return new WaitForSeconds(delaySeconds);
        action();
    }
}

(四)完成Basecode

? Basecode類主要負(fù)責(zé)每幀檢查用戶是否做了點(diǎn)擊事件,若點(diǎn)擊則調(diào)用placeAttackMark方法:

public class Basecode : MonoBehaviour {
    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            Vector3 point = Input.mousePosition;
            EsayFactory.GetInstance().placeAttackMark(point);
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,789評論 25 709
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,255評論 6 342
  • 重讀《向死而生》,心有所感 向死而生,大概只有在鬼門關(guān)走過一遭的人才會(huì)真正明白生的可貴和如何過好這一生吧,才會(huì)體會(huì)...
    你就是我最美的未來閱讀 374評論 0 0
  • 你說過,但你沒做。 你沒說,并也沒做。 你說了,并且做了。 你沒說,但你做了
    風(fēng)與光閱讀 207評論 0 1

友情鏈接更多精彩內(nèi)容