【Unity3D】點擊交互——簡單工廠


實現一個很簡單的點擊小游戲,學習交互相關的內容,在不實時創建銷毀的情況下,使用簡單工廠創建、管理、回收、復用標記。

游戲概述:點擊出現標記,兩秒內自動消失

 

游戲展示:

 

 

 


1.1實現點擊效果。
  1.1.1用 Plane 或其他物體做地面, tag 為“Finish”
    先創建Plane,並選擇tag為Finish。

  1.1.2點擊地面后,出現一個圓形攻擊標記,兩秒后自動消失。注意:該攻擊標記不能擋住點擊。(Primitive Objects / Cylinder)

    1.點擊對象出現事件,之前設置地板的tag為Finish,可以利用tag找到對象,對應編寫事件。

 

if (hit.collider.gameObject.tag.Contains ("Finish"))

    2.圓形攻擊標記,按提示創建Cylinder作為攻擊標記。

GameObject cylinder_1 = GameObject.CreatePrimitive (PrimitiveType.Cylinder);

    3.剛開始不知道不能擋住點擊該如何完成,這一點是在整體實現之后才查到相關資料解決的,加上下面一句代碼,把圓柱形標記設為不啟用,這樣就不會妨礙在同一地方繼續點擊生成或出現圓柱形標記。

cylinder_1.GetComponent<Collider> ().enabled = false; // 不影響再次點擊

    4.整理代碼,如下。

        void Update() {
            Vector3 mp = Input.mousePosition;
            cm = Camera.main;
            Ray ray = cm.ScreenPointToRay (mp);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit)) {
                // 如果點擊到標簽為Tag的對象
                if (hit.collider.gameObject.tag.Contains ("Finish")) {
                    Vector3 finishposition = hit.point + new Vector3(0f,0.8f,0f);
                    
                    GameObject cylinder_1 = GameObject.CreatePrimitive (PrimitiveType.Cylinder);
                    cylinder_1.GetComponent<Collider> ().enabled = false;
                    cylinder_1.transform.position = hit.point+ new Vector3(0f,0.8f,0f);
                    
                }
            }
        }

現在可以點擊創建圓柱形標記,但是還不會消失。要求需要在兩秒內自動消失,考慮增加一個類專門管理消失。(消失不是destroy,如下面所提示的,對象創建之后,放在列表內,不必釋放,因為釋放再重建耗費太多資源。)做到這一步,需要先使用簡單工廠,先放上代碼,后續在下一點再講述。

專門管理延時的類:

  1.1.3請使用一個簡單工廠創建、管理這些的標記,並自動收回這些標記(注意,這些對象創建后,放在列表內,不必釋放)。
為適應下面紅色字體要求,修改類名和相關函數名。
用戶僅需申請使用即可 GameObject myFactory.placeAttackMark(Vector3 position)
myFactory為工廠類,其中的placeAttackMark(Vector3 position)函數為具體實現。
建立myFactory.cs,建立placeAttackMark函數和對象列表(public List<GameObject> free = new List<GameObject>();),將之前Update里面的內容放到placeAttackMark中。考慮到需要回收對象(修改位置或者隱藏,讓用戶無法看到),在創建新的標記時需要判斷對象列表里還有沒有可用的,有則復用不創建。

 修改之前Update里面的內容,如下所示:重要代碼后寫有注釋。

        public void placeAttackMark(Vector3 target) {
            cm = Camera.main;
            Ray ray = cm.ScreenPointToRay (target);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit)) {
                // 如果點擊到標簽為Tag的對象
                GameObject cylinder_1;
                if (hit.collider.gameObject.tag.Contains ("Finish")) {
                    Vector3 finishposition = hit.point + new Vector3(0f,0.8f,0f);
                    if (free.Count == 0) { // 如果未使用的圓柱形標記為空,則創建
                        cylinder_1 = GameObject.CreatePrimitive (PrimitiveType.Cylinder);
                        cylinder_1.GetComponent<Collider> ().enabled = false; // 不影響再次點擊
                        cylinder_1.transform.position = hit.point+ new Vector3(0f,0.8f,0f);
                        
                    } else {
                        // 還有標記空閑,復用標記
                        cylinder_1 = free[0];
                        free.RemoveAt(0); // 用了之后移除
                        cylinder_1.transform.position = hit.point + new Vector3(0f,0.8f,0f);
                    }
                    // 兩秒后自動消失
                    waitToRecovery wt = cylinder_1.AddComponent<waitToRecovery>();
                    wt.delay2min (cylinder_1, free);
                }
            }

        }

 

最后,在用戶端直接訪問 myFactory.placeAttackMark(Vector3 position)即可。
在這里,如之前一樣,在myFactory里面實現了GetInstance方法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Com.mygame;

public class BaseCode : MonoBehaviour {

    private Camera cm;
    private GameObject temp;
    // Use this for initialization
    void Start () {
        cm = Camera.main;
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown (0)) {
            Vector3 mp = Input.mousePosition;
            myFactory.GetInstance ().placeAttackMark (mp);
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM