实现类似红警和星际争霸的框选功能
发表于2017-09-30
这里我们来实现类似红警和星际争霸的框选功能
实现画线
using UnityEngine; public class DrawRect : MonoBehaviour { bool drawing = false; private Material rectMat; private Color rectColor = Color.green; private Vector2 startPosition = Vector2.zero; private Vector2 endPosition = Vector2.zero; void Start() { rectMat = new Material( Shader.Find( "Lines/Colored_Blended" ) ); } void Update() { if (Input.GetMouseButtonDown(0)) { drawing = true; startPosition = Input.mousePosition; // 设置开始位置 CubeManager.Instance.BeginDraw(); } else if ( Input.GetMouseButtonUp( 0 ) ) { drawing = false; CubeManager.Instance.EndDraw(); } } void OnPostRender() // 该方法为系统函数,需将此脚本挂载到Camera下才能执行。 { if ( drawing ) { GL.PushMatrix(); if ( !rectMat ) return; endPosition = Input.mousePosition; // 设置结束位置 CubeManager.Instance.Drawing( startPosition, endPosition ); rectMat.SetPass( 0 ); GL.LoadPixelMatrix(); GL.Begin( GL.QUADS ); GL.Color( new Color( rectColor.r, rectColor.g, rectColor.b, 0.1f ) ); GL.Vertex3( startPosition.x, startPosition.y, 0 ); GL.Vertex3( endPosition.x, startPosition.y, 0 ); GL.Vertex3( endPosition.x, endPosition.y, 0 ); GL.Vertex3( startPosition.x, endPosition.y, 0 ); GL.End(); GL.Begin( GL.LINES ); GL.Color( rectColor ); GL.Vertex3( startPosition.x, startPosition.y, 0 ); GL.Vertex3( endPosition.x, startPosition.y, 0 ); GL.Vertex3( endPosition.x, startPosition.y, 0 ); GL.Vertex3( endPosition.x, endPosition.y, 0 ); GL.Vertex3( endPosition.x, endPosition.y, 0 ); GL.Vertex3( startPosition.x, endPosition.y, 0 ); GL.Vertex3( startPosition.x, endPosition.y, 0 ); GL.Vertex3( startPosition.x, startPosition.y, 0 ); GL.End(); GL.PopMatrix(); } } }
生成物体,实现框选
using UnityEngine; using System.Collections; using System.Collections.Generic; public class CubeManager : MonoBehaviour { private static CubeManager instance; public static CubeManager Instance { get { return instance; } } public GameObject prefab; public int count = 10; private Material originMat; private Material outlineMat; private List<MeshRenderer> meshRendererList; void Awake() { instance = this; } // Use this for initialization void Start () { meshRendererList = new List<MeshRenderer>(); // 创建物体 for ( int i = 0; i < count; i ) { GameObject go = GameObject.Instantiate( prefab ) as GameObject; go.name = (i 1).ToString(); go.transform.parent = transform; go.transform.position = new Vector3( Random.Range( -6, 7 ), 0, Random.Range( -4, 5 ) ); meshRendererList.Add( go.GetComponent<MeshRenderer>() ); } originMat = meshRendererList[0].material; // 获取描边shader outlineMat = new Material( Shader.Find( "Outlined/Diffuse" ) ); outlineMat.color = originMat.color; outlineMat.SetColor( "Outline Color", Color.green ); } public void BeginDraw() { var item = meshRendererList.GetEnumerator(); while ( item.MoveNext() ) { item.Current.material = originMat; } } public void Drawing( Vector2 point1, Vector2 point2 ) { Vector3 p1 = Vector3.zero; Vector3 p2 = Vector3.zero; if ( point1.x > point2.x ) { p1.x = point2.x; p2.x = point1.x; } else { p1.x = point1.x; p2.x = point2.x; } if ( point1.y > point2.y ) { p1.y = point2.y; p2.y = point1.y; } else { p1.y = point1.y; p2.y = point2.y; } var item = meshRendererList.GetEnumerator(); while ( item.MoveNext() ) { Vector3 position = Camera.main.WorldToScreenPoint( item.Current.transform.position ); if ( position.x > p1.x && position.y > p1.y && position.x < p2.x && position.y < p2.y ) { item.Current.material = outlineMat; } else { item.Current.material = originMat; } } } public void EndDraw() { } }
项目使用版本:Unity5.3.6 GitHub下载地址: