目录
1.绘制框选框
这里是绘制选中框的一个效果,具体看代码注释
需要注意的是: 因为框选框需要4个顶点 所以LineRenderer里面手动设置为4 可以自行设置线的粗细 建议0.01
计算另外两个顶点的参考图
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 红警选中效果 /// </summary> public class Select : MonoBehaviour { //光线渲染器 private LineRenderer lineRenderer; //屏幕起始点 private Vector3 screenStartPoint; //屏幕结束点 private Vector3 screenEndPoint; // Start is called before the first frame update void Start() { //获取光线渲染器 lineRenderer = GetComponent<LineRenderer>(); } // Update is called once per frame void Update() { //鼠标左键点击 if (Input.GetMouseButtonDown(0)) { //左键点击的时候开启光线渲染器 lineRenderer.enabled = true; //屏幕起始点 screenStartPoint=Input.mousePosition; screenStartPoint.z = 1; } //鼠标左键持续按下 if (Input.GetMouseButton(0)) { //屏幕结束点 screenEndPoint = Input.mousePosition; screenEndPoint.z = 1; //另外两个顶点(一共是顶点,前边只获得了两个顶点,这里需要通过前边两个来计算另外两个) Vector3 point1 = new Vector3(screenEndPoint.x, screenStartPoint.y, 1); Vector3 point2 = new Vector3(screenStartPoint.x, screenEndPoint.y, 1); //开始绘制 lineRenderer.SetPosition(0,Camera.main.ScreenToWorldPoint(point1)); lineRenderer.SetPosition(1,Camera.main.ScreenToWorldPoint(screenStartPoint)); lineRenderer.SetPosition(2,Camera.main.ScreenToWorldPoint(point2)); lineRenderer.SetPosition(3,Camera.main.ScreenToWorldPoint(screenEndPoint)); } //鼠标左键抬起 if (Input.GetMouseButtonUp(0)) { //左键抬起的时候关闭光线渲染器 lineRenderer.enabled = false; } } }
注意: 到这里只是写了绘制框选框的代码
2.最终效果以及全部代码 逻辑
里面调用了人物脚本的设置特效函数 这个脚本就不展示啦,随便写一下就可以
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 红警选中效果 /// </summary> public class Select : MonoBehaviour { //光线渲染器 private LineRenderer lineRenderer; //屏幕起始点 private Vector3 screenStartPoint; //屏幕结束点 private Vector3 screenEndPoint; //世界坐标开始点 private Vector3 worldStartPoint; //世界坐标结束点 private Vector3 worldEndPoint; //Collider数组 private Collider[] boxColliders; //选中的人物 暂存数组 private List<GameObject> lists=new List<GameObject>(); // Start is called before the first frame update void Start() { //获取光线渲染器 lineRenderer = GetComponent<LineRenderer>(); } // Update is called once per frame void Update() { //鼠标左键点击 if (Input.GetMouseButtonDown(0)) { //左键点击的时候开启光线渲染器 lineRenderer.enabled = true; //屏幕起始点 screenStartPoint =Input.mousePosition; screenStartPoint.z = 1; //射线检测 获取世界坐标开始点 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out RaycastHit hit)) { //世界坐标开始点 worldStartPoint = hit.point; } } //鼠标左键持续按下 if (Input.GetMouseButton(0)) { //屏幕结束点 screenEndPoint = Input.mousePosition; screenEndPoint.z = 1; //另外两个顶点(一共是顶点,前边只获得了两个顶点,这里需要通过前边两个来计算另外两个) Vector3 point1 = new Vector3(screenEndPoint.x, screenStartPoint.y, 1); Vector3 point2 = new Vector3(screenStartPoint.x, screenEndPoint.y, 1); //开始绘制 lineRenderer.SetPosition(0,Camera.main.ScreenToWorldPoint(point1)); lineRenderer.SetPosition(1,Camera.main.ScreenToWorldPoint(screenStartPoint)); lineRenderer.SetPosition(2,Camera.main.ScreenToWorldPoint(point2)); lineRenderer.SetPosition(3,Camera.main.ScreenToWorldPoint(screenEndPoint)); } //鼠标左键抬起 if (Input.GetMouseButtonUp(0)) { //左键抬起的时候关闭光线渲染器 lineRenderer.enabled = false; //遍历 把上一次人物的选中特效关闭 并且清空集合 for (int i = 0; i < lists.Count; i++) { lists[i].gameObject.GetComponent<Objects>().SetSel(false); } lists.Clear(); //射线检测 获取世界坐标结束点 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit)) { //世界坐标结束点 worldEndPoint = hit.point; //框选盒子中心点 Vector3 center = new Vector3((worldEndPoint.x + worldStartPoint.x) * 0.5f, 1f, (worldEndPoint.y + worldStartPoint.y) * 0.5f); //框选框长宽高各一半 Vector3 halfExtents = new Vector3(Mathf.Abs(worldEndPoint.x - worldStartPoint.x) * 0.5f, 1f, Mathf.Abs(worldEndPoint.z - worldStartPoint.z) * 0.5f); //检测到的物理碰撞体BOX boxColliders = Physics.OverlapBox(center, halfExtents); //遍历 调用人物挂载的脚本来显示选中特效 for (int i = 0;i < boxColliders.Length;i++) { //把地面过滤掉 if (boxColliders[i].gameObject.name!= "Scene") { boxColliders[i].gameObject.GetComponent<Objects>().SetSel(true); //添加到暂存集合 lists.Add(boxColliders[i].gameObject); } } } } } }
科普一下Physics.OverlapBox:
Physics.OverlapBox是一个用于检测立方体范围内的物体碰撞的函数。它可以帮助您判断是否有其他物体与指定的立方体范围相交。
使用Physics.OverlapBox函数需要提供以下参数:
- center:立方体的中心点坐标。
- halfExtents:立方体长、宽、高各自一半的长度。
- orientation:立方体的旋转角度。
- layerMask:指定要进行碰撞检测的层级。
- queryTriggerInteraction:定义是否将触发器(Trigger)包括在碰撞检测范围内。
函数的返回值是一个Collider数组,包含与指定立方体范围碰撞的所有物体。