今天我们来谈,类似红警中框选游戏对象的模块
首先实现思路:
1.获取鼠标起始点的位置,并实时获取鼠标当前位置,从而绘制勾选框的UI
(这里在Canvas下放置了一个失活的Image,在拖拽鼠标时激活 并修改Image的大小
)
2.判断物体位置,是否在勾选范围内,如果要勾选的对象是3D物体则把物体坐标转为UI坐标
话不多说直接上代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 框选3D物体
/// </summary>
public class Broder : MonoBehaviour
{
/// <summary>
/// 鼠标起始位置,和当前位置
/// </summary>
Vector2 startPos, nowPos;
/// <summary>
/// 选中框
/// </summary>
public Image broder;
/// <summary>
/// UI上的选中范围
/// </summary>
private Rect selectRect;
/// <summary>
/// 可被选中的游戏对象数组
/// </summary>
private GameObject[] objs;
void Start()
{
objs= GameObject.FindGameObjectsWithTag("Respawn");
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
startPos= Input.mousePosition;
for (int i = 0; i < objs.Length; i++)
{
objs[i].GetComponent<MeshRenderer>().material.color = Color.white;
}
}
if (Input.GetMouseButton(0))
{
nowPos = Input.mousePosition;
Vector2 center=(startPos + nowPos) / 2;//勾选框的中心点
Vector2 size= new Vector2(Mathf.Abs(nowPos.x - startPos.x), Mathf.Abs(nowPos.y - startPos.y));
SetBroder(center,size);//Debug.Log(string.Format(center+" "+ size));
selectRect = new Rect(center - (size / 2), size);
SelectObj();
}
if (Input.GetMouseButtonUp(0))
{
broder.gameObject.SetActive(false);
}
}
private void SelectObj()
{
for (int i = 0; i < objs.Length; i++)
{
if (selectRect.Contains(Camera.main.WorldToScreenPoint(objs[i].transform.position)))
{
//todo:===Logic:
print(objs[i].name);
//这里选择修改颜色来展示效果
objs[i].GetComponent<MeshRenderer>().material.color= Color.red;
}
else
{
objs[i].GetComponent<MeshRenderer>().material.color = Color.white;
}
}
}
/// <summary>
/// 设置选中框
/// </summary>
private void SetBroder(Vector2 pos,Vector2 size)
{
broder.gameObject.SetActive(true);
broder.rectTransform.position = pos;
broder.rectTransform.sizeDelta = size;
}
}
代码中,要想求勾选框的位置,要让初始位置 startPos 加上 nowPos再除以2,这样得出的就是所沟壑的矩形的中心点(position);
修改图片大小,在Image(勾选框)的锚点一致时,它的sizeDelta属性相当于图片自身宽高
关于sizeDelta属性:(1条消息) Unity中sizeDelta的真正含义_Hello Bug.的博客-CSDN博客
Rect类中的Contains方法可以帮我们计算目标对象的position是否在矩形内
框选模块实现,感谢来访