效果如图:
选中前:
选中后:
具体操作:
(1).先创建角色在地图
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
public List<GameObject> list = new List<GameObject>();
public BoLingMaps boLingMaps;
private void Awake()
{
}
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < 10; i++)
{
GameObject player = GameObject.Instantiate(Resources.Load<GameObject>("player/player_" + i));
player.transform.position = boLingMaps.verticesPositions[Random.Range(0, boLingMaps.verticesPositions.Count)];
player.transform.localScale = Vector3.one*3;
GameObject circle = GameObject.Instantiate(Resources.Load<GameObject>("Circle"),player.transform);
circle.transform.Rotate(Vector3.left * 90);
circle.SetActive(false);
list.Add(player);
}
}
// Update is called once per frame
void Update()
{
}
}
(2).创建脚下圆环用来实现选中效果,将下面的脚本挂载在空对象上生成Resources文件夹下的预制体
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
[RequireComponent(typeof(MeshFilter),typeof(MeshCollider),typeof(MeshRenderer))]
public class CreateYuan : MonoBehaviour
{
private void Start()
{
//创建网格
Mesh mesh = new Mesh();
VertexHelper vh = new VertexHelper();
float r = 1;
float r1 = 2;
int num = 30;
float ang = 2 * Mathf.PI / (float)num;
for (int i = 0; i < num + 1; i++)
{
float x = Mathf.Sin(i * ang) * r;
float y = Mathf.Cos(i * ang) * r;
float uvx = (float)i / (float)num;
vh.AddVert(new Vector3(x, y, 0), Color.white, new Vector2(uvx, 0));
float x1 = Mathf.Sin(i * ang) * r1;
float y1 = Mathf.Cos(i * ang) * r1;
vh.AddVert(new Vector3(x1, y1, 0), Color.white, new Vector2(uvx, 1));
if (i < num)
{
vh.AddTriangle(i * 2, i * 2 + 1, (i + 1) * 2 + 1);
vh.AddTriangle(i * 2, (i + 1) * 2 + 1, (i + 1) * 2);
vh.AddTriangle(i * 2, (i + 1) * 2 + 1, i * 2 + 1);
vh.AddTriangle(i * 2, (i + 1) * 2, (i + 1) * 2 + 1);
}
}
vh.FillMesh(mesh);
GetComponent<MeshFilter>().mesh = mesh;
GetComponent<MeshCollider>().sharedMesh = mesh;
Material material = new Material(Shader.Find("UI/Default"));
material.color=Color.red;
GetComponent<MeshRenderer>().material = material;
}
}
(3).如图创建一个框的UI并挂载框选后处理逻辑的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class DrawBox : MonoBehaviour
{
public PlayerManager playerManager;
Camera cam;//相机
// Start is called before the first frame update
void Start()
{
cam = Camera.main;
}
Vector3 startpos;//初始点位置
bool isDrag = false;//是否拖拽中
Rect rect;//框的矩形
List<GameObject> players = new List<GameObject>();//选中的人物集合
// Update is called once per frame
void Update()
{
//按下左键时确定初始点
if (Input.GetMouseButtonDown(0))
{
startpos = Input.mousePosition;
isDrag = true;
}
//拖拽
if (isDrag)
{
//通过两点坐标确定宽高
float w = Mathf.Abs(startpos.x - Input.mousePosition.x);
float h = Mathf.Abs(startpos.y - Input.mousePosition.y);
//赋值UI宽高
GetComponent<RectTransform>().sizeDelta = new Vector2(w, h);
//计算锚点在中心的框坐标
float x = startpos.x < Input.mousePosition.x ? startpos.x + w / 2 : Input.mousePosition.x + w / 2;
float y = startpos.y < Input.mousePosition.y ? startpos.y + h / 2 : Input.mousePosition.y + h / 2;
GetComponent<RectTransform>().anchoredPosition = new Vector2(x - Screen.width / 2, y - Screen.height / 2);
//计算选人用矩形框(锚点在左下角)
rect = new Rect(x - w / 2, y - h / 2, w, h);
}
//松手
if (Input.GetMouseButtonUp(0))
{
//清理之前选中人物数据
foreach (var item in players)
{
item.transform.Find("Circle(Clone)").gameObject.SetActive(false);
}
players.Clear();
//循环所有人物判断是否被框选
foreach (var item in playerManager.list)
{
//将人物坐标转换成屏幕坐标
Vector3 pos = cam.WorldToScreenPoint(item.transform.position);
Debug.Log("rect:" + rect + "pos:" + pos);
//判断转换后的坐标是否在矩形内
if (rect.Contains(pos))
{
players.Add(item);
item.transform.Find("Circle(Clone)").gameObject.SetActive(true);
}
}
//将框隐藏
GetComponent<RectTransform>().sizeDelta = Vector2.zero;
isDrag = false;
}
//点击右键导航移动
if (Input.GetMouseButtonDown(1))
{
//射线
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
//半径为1画圆
float r = 1;
float ang = (Mathf.PI * 2) / players.Count;
for (int i = 0; i < players.Count; i++)
{
float x = Mathf.Sin(i * ang) * r;
float z = Mathf.Cos(i * ang) * r;
//人物以点击位置为圆心导航
players[i].GetComponent<NavMeshAgent>().SetDestination(hit.point + new Vector3(x, 0, z));
}
}
}
}
}