RTS框选

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

public class RectRender : MonoBehaviour
{
    public List<GameObject> list = new List<GameObject>();
    private bool onDrawingRect;//是否正在画框(即鼠标左键处于按住的状态)
    private Vector3 startPoint;//框的起始点,即按下鼠标左键时指针的位置
    private Vector3 currentPoint;//在拖移过程中,玩家鼠标指针所在的实时位置
    private Vector3 endPoint;//框的终止点,即放开鼠标左键时指针的位置
   
    public new Material light;
    void Update()
    {
        CheckSelection_My();
        #region 画框
        //玩家按下鼠标左键,此时进入画框状态,并确定框的起始点
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            onDrawingRect = true;
            startPoint = Input.mousePosition;
            //Debug.LogFormat("开始画框,起点:{0}", startPoint);

        }
        //在鼠标左键未放开时,实时记录鼠标指针的位置
        if (onDrawingRect)
        {
            currentPoint = Input.mousePosition;
            //selector = new Selector(startPoint, endPoint);
            执行框选事件
            //CheckSelection(selector, "soldiers");
        }

        //玩家放开鼠标左键,说明框画完,确定框的终止点,退出画框状态
        if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            endPoint = Input.mousePosition;
            onDrawingRect = false;
            //Debug.LogFormat("画框结束,终点:{0}", endPoint);
            //selector = new Selector(startPoint, endPoint);
            执行框选事件
            //CheckSelection(selector, "soldiers");
        }
        #endregion

    }
    #region Method1
    public class Selector
    {
        public float Xmin;
        public float Xmax;
        public float Ymin;
        public float Ymax;

        //构造函数,在创建选定框时自动计算Xmin/Xmax/Ymin/Ymax
        public Selector(Vector3 start, Vector3 end)
        {
            Xmin = Mathf.Min(start.x, end.x);
            Xmax = Mathf.Max(start.x, end.x);
            Ymin = Mathf.Min(start.y, end.y);
            Ymax = Mathf.Max(start.y, end.y);
        }
    }
    private Selector selector;
    void CheckSelection(Selector selector, string tag)
    {
        GameObject[] Units = GameObject.FindGameObjectsWithTag(tag);
        foreach (GameObject Unit in Units)
        {
            Vector3 screenPos = Camera.main.WorldToScreenPoint(Unit.transform.position);
            if (screenPos.x > selector.Xmin && screenPos.x < selector.Xmax && screenPos.y > selector.Ymin && screenPos.y < selector.Ymax)
            {
                Debug.LogFormat("已选中目标:{0}", Unit.name);
                Unit.GetComponent<Renderer>().material = light;
                Unit.GetComponent<Renderer>().material.shader = Shader.Find("Custom/OutLine2");
                Unit.GetComponent<Renderer>().material.SetColor("Color", Color.white);
                Unit.GetComponent<Renderer>().material.SetColor("Atmosphere_Color", Color.green);
                Unit.GetComponent<Renderer>().material.SetFloat("Size", 0.3f);
                Unit.GetComponent<Renderer>().material.SetFloat("Falloff", 4.0f);
                Unit.GetComponent<Renderer>().material.SetFloat("Transparency", 13f);
            }

        }
    }
    #endregion
    #region Check
    Vector3 PosStart = new Vector3();
    Vector3 Pos1 = new Vector3();
    Vector3 Pos2 = new Vector3();
    Vector3 PosCurrent = new Vector3();
    void CheckSelection_My()
    {
        Ray ray_curr = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray_curr, out hit,1 << LayerMask.NameToLayer("Plane")))
        {
            if (Input.GetMouseButtonDown(0))
            {
                ray_curr = Camera.main.ScreenPointToRay(Input.mousePosition);
                PosStart = hit.point;  
            }
            if (Input.GetMouseButton(0))
            {                
                Pos1 = new Vector3(PosStart.x, 0, hit.point.z);
                Pos2 = new Vector3(hit.point.x, 0, PosStart.z);
                PosCurrent = hit.point;
                Debug.DrawLine(PosStart, PosStart + Vector3.up * 100);
                Debug.DrawLine(hit.point, hit.point + Vector3.up * 100, Color.green);
                Debug.DrawLine(Pos1, Pos1 + Vector3.up * 100);
                Debug.DrawLine(Pos2, Pos2 + Vector3.up * 100);
            }
            if (Input.GetMouseButtonUp(0))
            {
                GameObject[] Units = GameObject.FindGameObjectsWithTag("soldiers");
                foreach (GameObject Unit in Units)
                {
                    if (Between(Unit, PosStart, PosCurrent))
                    {
                        Debug.LogFormat("已选中目标:{0}", Unit.name);
                        list.Add(Unit);
                        Tool.Select(Unit);
                    }
                }
            }
            if (Input.GetKeyDown(KeyCode.Space))
            {
                foreach (var item in list)
                {
                    Tool.CancelSelect(item);
                }
                list.Clear();
            }

        }
    }
    #endregion
    #region 画线
    public Material GLRectMat; //绘图的材质,在Inspector中设置
    public Color GLRectColor;//矩形的内部颜色,在Inspector中设置
    public Color GLRectEdgeColor;//矩形的边框颜色,在Inspector中设置    
    void OnPostRender()
    {
        if (onDrawingRect)
        {
            //准备工作:获取确定矩形框各角坐标所需的各个数值
            float Xmin = Mathf.Min(startPoint.x, currentPoint.x);
            float Xmax = Mathf.Max(startPoint.x, currentPoint.x);
            float Ymin = Mathf.Min(startPoint.y, currentPoint.y);
            float Ymax = Mathf.Max(startPoint.y, currentPoint.y);

            GL.PushMatrix();//GL入栈
                            //在这里,只需要知道GL.PushMatrix()和GL.PopMatrix()分别是画图的开始和结束信号,画图指令写在它们中间
            if (!GLRectMat)
                return;

            GLRectMat.SetPass(0);//启用线框材质rectMat


            GL.LoadPixelMatrix();//设置用屏幕坐标绘图


            /*------第一步,绘制矩形------*/
            GL.Begin(GL.QUADS);//开始绘制矩形,这一段画的是框中间的半透明部分,不包括边界线

            GL.Color(GLRectColor);//设置矩形的颜色,注意GLRectColor务必设置为半透明

            //陈述矩形的四个顶点
            GL.Vertex3(Xmin, Ymin, 0);//陈述第一个点,即框的左下角点,记为点1
            GL.Vertex3(Xmin, Ymax, 0);//陈述第二个点,即框的左上角点,记为点2
            GL.Vertex3(Xmax, Ymax, 0);//陈述第三个点,即框的右上角点,记为点3
            GL.Vertex3(Xmax, Ymin, 0);//陈述第四个点,即框的右下角点,记为点4

            GL.End();//告一段落,此时画好了一个无边框的矩形


            /*------第二步,绘制矩形的边框------*/
            GL.Begin(GL.LINES);//开始绘制线,用来描出矩形的边框

            GL.Color(GLRectEdgeColor);//设置方框的边框颜色,建议设置为不透明的

            //描第一条边
            GL.Vertex3(Xmin, Ymin, 0);//起始于点1
            GL.Vertex3(Xmin, Ymax, 0);//终止于点2

            //描第二条边
            GL.Vertex3(Xmin, Ymax, 0);//起始于点2
            GL.Vertex3(Xmax, Ymax, 0);//终止于点3

            //描第三条边
            GL.Vertex3(Xmax, Ymax, 0);//起始于点3
            GL.Vertex3(Xmax, Ymin, 0);//终止于点4

            //描第四条边
            GL.Vertex3(Xmax, Ymin, 0);//起始于点4
            GL.Vertex3(Xmin, Ymin, 0);//返回到点1

            GL.End();//画好啦!

            GL.PopMatrix();//GL出栈
        }        
    }
    #endregion
    bool Between(GameObject gameObject,Vector3 Start, Vector3 End)
    {
        if(gameObject.transform.position.x<=Mathf.Max(Start.x,End.x) &&
           gameObject.transform.position.x >= Mathf.Min(Start.x, End.x) &&
           gameObject.transform.position.z<=Mathf.Max(Start.z,End.z) &&
           gameObject.transform.position.z >= Mathf.Min(Start.z, End.z))
        {
            return true;
        }
        else 
        return false;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值