unity通過滑鼠批量刪除(隱藏)物體
阿新 • • 發佈:2019-01-08
一個模型層級很多 通過點選或者長按來一次處理一個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); } } } }