1. 程式人生 > >unity通過滑鼠批量刪除(隱藏)物體

unity通過滑鼠批量刪除(隱藏)物體

一個模型層級很多 通過點選或者長按來一次處理一個gameobject處理模型效率實在低,於是怎麼通過滑鼠框選來處理模型呢?

隨便建個場景測試下,用幾個cube 代替特別複雜的模型



試試效果:


我這裡為了省事直接把cube拖拽到數組裡的,實際開發中可以通過定義的事件動態儲存模型 Dictionary<string, GameObject>對應的儲存

指令碼;

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

public class hzTest: MonoBehaviour
{

    public List<GameObject> characters;
    public Color rectColor = Color.yellow;

    private Vector3 start = Vector3.zero;//記下滑鼠按下位置


    public Material rectMat = null;//這裡使用Sprite下的defaultshader的材質即可

    private bool drawRectangle = false;//是否開始畫線標誌

    // Use this for initialization

    void Start()
    {

        //rectMat = new Material("Shader \"Lines/Colored Blended\" {" +

        //"SubShader { Pass { " +

        //"    Blend SrcAlpha OneMinusSrcAlpha " +

        //"    ZWrite Off Cull Off Fog { Mode Off } " +

        //"    BindChannels {" +

        //"      Bind \"vertex\", vertex Bind \"color\", color }" +

        //"} } }");//生成畫線的材質

        rectMat.hideFlags = HideFlags.HideAndDontSave;

        rectMat.shader.hideFlags = HideFlags.HideAndDontSave;//不顯示在hierarchy面板中的組合,不儲存到場景並且解除安裝Resources.UnloadUnusedAssets不解除安裝的物件。

    }


    void Update()
    {

        if (Input.GetMouseButtonDown(0))
        {

            drawRectangle = true;//如果滑鼠左鍵按下 設定開始畫線標誌

            start = Input.mousePosition;//記錄按下位置

        }
        else if (Input.GetMouseButtonUp(0))
        {

            drawRectangle = false;//如果滑鼠左鍵放開 結束畫線
            checkSelection(start, Input.mousePosition);
        }
    }



    void OnPostRender()
    {//畫線這種操作推薦在OnPostRender()裡進行 而不是直接放在Update,所以需要標誌來開啟

        if (drawRectangle)
        {

            Vector3 end = Input.mousePosition;//滑鼠當前位置

            GL.PushMatrix();//儲存攝像機變換矩陣,把投影檢視矩陣和模型檢視矩陣壓入堆疊儲存

            if (!rectMat)

                return;

            rectMat.SetPass(0);//為渲染啟用給定的pass。

            GL.LoadPixelMatrix();//設定用螢幕座標繪圖

            GL.Begin(GL.QUADS);//開始繪製矩形

            GL.Color(new Color(rectColor.r, rectColor.g, rectColor.b, 0.1f));//設定顏色和透明度,方框內部透明

            //繪製頂點
            GL.Vertex3(start.x, start.y, 0);

            GL.Vertex3(end.x, start.y, 0);

            GL.Vertex3(end.x, end.y, 0);

            GL.Vertex3(start.x, end.y, 0);

            GL.End();


            GL.Begin(GL.LINES);//開始繪製線

            GL.Color(rectColor);//設定方框的邊框顏色 邊框不透明

            GL.Vertex3(start.x, start.y, 0);

            GL.Vertex3(end.x, start.y, 0);

            GL.Vertex3(end.x, start.y, 0);

            GL.Vertex3(end.x, end.y, 0);

            GL.Vertex3(end.x, end.y, 0);

            GL.Vertex3(start.x, end.y, 0);

            GL.Vertex3(start.x, end.y, 0);

            GL.Vertex3(start.x, start.y, 0);

            GL.End();

            GL.PopMatrix();//恢復攝像機投影矩陣

        }

    }

    //檢測被選擇的物體
    void checkSelection(Vector3 start, Vector3 end)
    {

        Vector3 p1 = Vector3.zero;

        Vector3 p2 = Vector3.zero;

        if (start.x > end.x)
        {//這些判斷是用來確保p1的xy座標小於p2的xy座標,因為畫的框不見得就是左下到右上這個方向的

            p1.x = end.x;

            p2.x = start.x;

        }

        else
        {

            p1.x = start.x;

            p2.x = end.x;

        }

        if (start.y > end.y)
        {

            p1.y = end.y;

            p2.y = start.y;

        }

        else
        {

            p1.y = start.y;

            p2.y = end.y;

        }

        foreach (GameObject obj in characters)
        {//把可選擇的物件儲存在characters數組裡

            Vector3 location = Camera.main.WorldToScreenPoint(obj.transform.position);//把物件的position轉換成螢幕座標

            if (location.x < p1.x || location.x > p2.x || location.y < p1.y || location.y > p2.y)

          //  || location.z < Camera.main.nearClipPlane || location.z > Camera.main.farClipPlane)//z方向就用攝像機的設定值,看不見的也不需要選擇了

            {
                //disselecting(obj);//上面的條件是篩選 不在選擇範圍內的物件,然後進行取消選擇操作,比如把物體放到default層,就不顯示輪廓線了
                //print("---" + obj.name);
                //obj.SetActive(false);
            }

            else

            {
                //selecting(obj);//否則就進行選中操作,比如把物體放到畫輪廓線的層去
                // print("+++" + obj.name);
               obj.SetActive(false);

            }

        }

    }
}