unity画矩形框,单选框选和多选

亲测可用,材质球随便创建一个就好

参考https://blog.csdn.net/lizhenxiqnmlgb/article/details/88570731?utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/qq_38049291/article/details/79891491?utm_source=distribute.pc_relevant.none-task

都是亲测可用的

画矩形框

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


public class DrawTest : MonoBehaviour {
    /// <summary>
    /// 材质球
    /// </summary>
    public Material mat;
    /// <summary>
    /// 鼠标开始的位置
    /// </summary>
    private Vector2 FirstMousePosition;
    /// <summary>
    /// 鼠标结束的位置
    /// </summary>
    private Vector2 SecondMousePosition;
    private bool StartRender = false;
    private Renderer[] gameobjects;
// Use this for initialization
void Start ()
    {
        gameobjects = FindObjectsOfType<Renderer>();	
}

// Update is called once per frame
void Update ()
    {
        //获取鼠标按下
        if(Input.GetMouseButtonDown(0))
        {
            StartRender = true;
            FirstMousePosition = Input.mousePosition;
            PickGameObject();
        }
        //获取鼠标抬起
        if (Input.GetMouseButtonUp(0))
        {
            StartRender = false;
            ChangeTwoPoint();
            PickGameObject();
            FirstMousePosition = SecondMousePosition = Vector2.zero;
        }
        SecondMousePosition = Input.mousePosition;
}
 
    private void OnPostRender()
    {
        if (StartRender)
        {
            mat.SetPass(0);
            GL.LoadOrtho();
            GL.Begin(GL.LINES);
            DrawLine(FirstMousePosition.x, FirstMousePosition.y, SecondMousePosition.x, SecondMousePosition.y);
            GL.End(); 
        }
    }
    /// <summary>
    /// 画线
    /// </summary>
    /// <param name="x1"></param>
    /// <param name="y1"></param>
    /// <param name="x2"></param>
    /// <param name="y2"></param>
    private void DrawLine(float x1, float y1, float x2, float y2)
    {
        GL.Vertex(new Vector3(x1 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y1 / Screen.height, 0));
    }
    /// <summary>
    /// 改变两点
    /// </summary>
    private void ChangeTwoPoint()
    {
        if (FirstMousePosition.x > SecondMousePosition.x)
        {
            float position1 = FirstMousePosition.x;
            FirstMousePosition.x = SecondMousePosition.x;
            SecondMousePosition.x = position1;
        }
        if (FirstMousePosition.y > SecondMousePosition.y)
        {
            float position2 = FirstMousePosition.y;
            FirstMousePosition.y = SecondMousePosition.y;
            SecondMousePosition.y = position2;
        }
    }
    /// <summary>
    /// 改变物体颜色
    /// </summary>
    private void PickGameObject()
    {
        //遍历所有的组件
        foreach (Renderer item in gameobjects)
        {//判断位置
            Vector3 position = Camera.main.WorldToScreenPoint(item.transform.position);
            if (position.x >= FirstMousePosition.x & position.x <= SecondMousePosition.x & position.y >= FirstMousePosition.y & position.y <= SecondMousePosition.y)
            {

//改变颜色

                item.material.color = Color.red;
            }
            else
            {

//改变颜色

                item.material.color = Color.white;
            }


        }
    }
}
————————————————
版权声明:本文为CSDN博主「沧海难为水y」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38049291/article/details/79891491

单选多选和框选

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine.EventSystems;
using UnityEngine.UI;
 
 
/// <summary>
/// 功能:单选、多选(按住左边的Ctrl+点击)、框选
/// </summary>
public enum State
{
    OnLeft,
    OnCtrlLeft
}
 
 
public class MultipleSelection : MonoBehaviour
{
 
    //定义一根射线
    private Ray ray;
    //枚举默认的点击状态是左键点击的状态
    private State clickState = State.OnLeft;
    private Vector3 v1, v2;
  
 
 
    //************弹窗信息
 
    //info面板
   // public GameObject infoPanel;
    //碰撞信息
    private RaycastHit hitInfo;
 
 
    //画线的材质
    // public Material mat;
    //鼠标一开始点击的位置
    private Vector2 FirstMouseposition;
    //鼠标松开的位置
    private Vector2 SecondMousePosition;
    //是否画线标志位
    private bool StartRender = false;
    //renderer数组用来保存各个对象身上的组件
    private Renderer[] gameObjects;
    //单选和框选的标志位
    private bool isKuangxuan=false;
    //用来存储每次点击的对象以及对象的颜色
    private Dictionary<GameObject, Color> dict;
    //鼠标点击的对象
    private GameObject clickGameObject;
 
   // public RectTransform rectTrans;
    //public RectTransform objRectTrans;
    //选择到的对象,用来做显示隐藏
    public static List<GameObject> objlist = new List<GameObject>();
 
   // BoxCollider[] objCollider;
 
    //获取renderer中心点所需要的变量
    float xmax = 0;
    float ymax = 0;
    float zmax = 0;
    float xmin = 0;
    float ymin = 0;
    float zmin = 0;
 
    void Start()
    {
        dict = new Dictionary<GameObject, Color>();
        //找到对象中含有的renderer组件
        gameObjects = FindObjectsOfType<Renderer>();
      //  objCollider = FindObjectsOfType<BoxCollider>();
    }
   
 
    void Update()
    {
        
 
        //**********************多选
        if (Input.GetKey(KeyCode.LeftControl) && Input.GetMouseButtonDown(0))
        {
            objlist.Clear();
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hitInfo))
            {
                //得到当前点击物体的颜色,并放入字典中
                OnChangeColor();
                objlist.Add(hitInfo.transform.gameObject);
            }
 
        }
        else
        if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
        {
            //点击空白处,清空
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hitInfo))
            {
                if (hitInfo.collider)
                {
                   // infoPanel.gameObject.SetActive(false);
                    RecoverColor();
                    clickState = State.OnCtrlLeft;
                    objlist.Clear();
                }
            }
            else
            {
               // infoPanel.gameObject.SetActive(false);
                RecoverColor();
                clickState = State.OnCtrlLeft;
                objlist.Clear();
            }
 
        }
        //点击ESC键,清空选中
        if (Input.GetKey(KeyCode.Escape))
        {
           // infoPanel.gameObject.SetActive(false);
            RecoverColor();
            clickState = State.OnCtrlLeft;
            objlist.Clear();
        }
                
        if (clickState != State.OnLeft)
        {
            //鼠标左键单击的时候
            if (Input.GetMouseButtonDown(0))
            {
                v1 = Input.mousePosition;
                StartRender = true;
                FirstMouseposition = Input.mousePosition;
                //选取对象
                //PickGameObject();
                isKuangxuan = true;
 
            }
        }
        if (Input.GetMouseButtonUp(0) && isKuangxuan == true)
        {
            objlist.Clear();
            v2 = Input.mousePosition;
            if (Vector3.Distance(v1, v2) < 1)
            {
                StartRender = false;
 
                ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                //******************单选
                if (Physics.Raycast(ray, out hitInfo))
                {
                    OnChangeColor();
                    objlist.Add(hitInfo.transform.gameObject);
                }
            }
            
            else
            {
                //******************框选
                StartRender = false;
                ChangeTwoPoint();
                //将线框里的对象都进行变色处理
                PickGameObject();
                //选择完毕后,将两个点归0
                FirstMouseposition = SecondMousePosition = Vector2.zero; 
            }
            
            isKuangxuan = false;
 
        }
        SecondMousePosition = Input.mousePosition;
 
 
        clickState = State.OnLeft;
 
      
    }
 
    /// <summary>
    /// 存储原色,以及变色
    /// </summary>
    void OnChangeColor()
    {
        clickGameObject = hitInfo.transform.gameObject;
        if (dict.ContainsKey(clickGameObject)) return;
        dict.Add(clickGameObject, clickGameObject.GetComponent<Renderer>().material.color);
        if (clickGameObject.GetComponent<Renderer>().material.color == Color.blue)
            clickGameObject.GetComponent<Renderer>().material.color = new Color(0,0.5f,1);
        else
            clickGameObject.GetComponent<Renderer>().material.color = Color.blue;
    }
    /// <summary>
    /// 恢复颜色
    /// </summary>
    void RecoverColor()
    {
        //遍历字典让颜色恢复到原来的状态
        if (dict.Count != 0)
        {
            foreach (var kvp in dict)
            {
                kvp.Key.GetComponent<Renderer>().material.color = kvp.Value;
            }
            dict.Clear();
        }
    }
 
    //OnPostRender在相机渲染完所有物体之后被调用。只有该脚本
    //附于相机并启用时才会调用这个函数。OnPostRender可以是一个协同程序,在函数中调用yield语句即
    void OnPostRender()
    {
        if (StartRender)
        {
            //激活第一个pass,设置材质通道
            // mat.SetPass(0);
            GL.Color(Color.green);
            //辅助函数用来做一个正交投影变换,用来绘制2D图形
            GL.LoadOrtho();
            //开始绘制四边形
            GL.Begin(GL.LINES);
            DrawLine(FirstMouseposition.x, FirstMouseposition.y, SecondMousePosition.x, SecondMousePosition.y);
            GL.End();
        }
    }
 
 
    void DrawLine(float x1, float y1, float x2, float y2)
    {
        GL.Vertex(new Vector3(x1 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y1 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x2 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y2 / Screen.height, 0));
        GL.Vertex(new Vector3(x1 / Screen.width, y1 / Screen.height, 0));
    }
 
    void ChangeTwoPoint()
    {
        //右下角往左上方向进行框选
        if (FirstMouseposition.x > SecondMousePosition.x)
        {
            float position1 = FirstMouseposition.x;
            FirstMouseposition.x = SecondMousePosition.x;
            SecondMousePosition.x = position1;
        }
 
        //左上角往右下方向进行框选
        if (FirstMouseposition.y > SecondMousePosition.y)
        {
            float position2 = FirstMouseposition.y;
            FirstMouseposition.y = SecondMousePosition.y;
            SecondMousePosition.y = position2;
        }
    }
 
    //框选对象
    void PickGameObject()
    {
        objlist.Clear();
        foreach (Renderer item in gameObjects)
        {
            Vector3 position = Camera.main.WorldToScreenPoint(GetCenterPoint(item));
            if (position.x >= FirstMouseposition.x & position.x <= SecondMousePosition.x & position.y >= FirstMouseposition.y & position.y <= SecondMousePosition.y)
            {
                //if (dict.ContainsKey(clickGameObject)) return;
                dict.Add(item.gameObject, item.material.color);
                item.material.color = Color.blue;
                objlist.Add(item.transform.gameObject);
            }
        }
        
    }
    //获取renderer组件的中心点
    Vector3 GetCenterPoint(Renderer render)
    {
        Vector3 vmax = render.bounds.max;
        Vector3 vmin = render.bounds.min;
        xmax = vmax.x;
        ymax = vmax.y;
        zmax = vmax.z;
        xmin = vmin.x;
        ymin = vmin.y;
        zmin = vmin.z;
        return (new Vector3((xmax + xmin) * 0.5f, (ymax + ymin) * 0.5f, (zmax + zmin) * 0.5f));
    }
 
 
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山竹炒大蒜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值