框选角色是许多游戏中都需要的功能,框选角色要先生成一个框,新建一个Image,添加一个Sprite,然后取消掉Fill Center选项:
这样一个空心的框就做好了:
接下来通过动态调节这个框的属性就可以实现框选效果:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CreateFrame : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Vector3 startPos;
public RectTransform rt;
Vector3 offset;
public List<Transform> objs = new List<Transform>();
private void Start()
{
offset = new Vector3(Screen.width / 2, Screen.height / 2, 0);
}
public void OnBeginDrag(PointerEventData eventData)
{
startPos = Input.mousePosition - offset;
rt.localPosition = startPos;
}
public void OnDrag(PointerEventData eventData)
{
Vector3 tempPos = Input.mousePosition - offset;
rt.sizeDelta = new Vector2(tempPos.x - startPos.x, startPos.y - tempPos.y);
}
public void OnEndDrag(PointerEventData eventData)
{
for (int i = 0; i < objs.Count; i++)
{
Vector3 temp = Camera.main.WorldToScreenPoint(objs[i].position) - offset;
if (temp.x > startPos.x && temp.x < (startPos.x + rt.sizeDelta.x) &&
temp.y < startPos.y && (temp.y > startPos.y - rt.sizeDelta.y))
{
Debug.Log("in");
}
}
rt.sizeDelta = Vector2.zero;
}
}
然后给角色挂上生成一个圆环的脚本,在角色脚下生成圆环:
public class CreateShpere : MonoBehaviour
{
int num = 20;
float angle;
float r1 = 0.3f;
float r2 = 0.5f;
private void Start()
{
angle = 2 * Mathf.PI / num;
VertexHelper vh = new VertexHelper();
for (int i = 0; i < num; i++)
{
float x1 = Mathf.Sin(i * angle) * r1;
float z1 = Mathf.Cos(i * angle) * r1;
vh.AddVert(new Vector3(x1, 0.1f, z1), Color.white, Vector2.zero);
float x2 = Mathf.Sin(i * angle) * r2;
float z2 = Mathf.Cos(i * angle) * r2;
vh.AddVert(new Vector3(x2, 0.1f, z2), Color.white, new Vector2(0, 1));
if (i == num - 1)
{
vh.AddTriangle(2 * i, 2 * i + 1, 1);
vh.AddTriangle(2 * i, 1, 0);
}
else
{
vh.AddTriangle(2 * i, 2 * i + 1, 2 * i + 3);
vh.AddTriangle(2 * i, 2 * i + 3, 2 * i + 2);
}
}
Mesh mesh = new Mesh();
vh.FillMesh(mesh);
GetComponent<MeshFilter>().mesh = mesh;
}
}
在选中角色时将圆环显示,否则隐藏:
for (int i = 0; i < objs.Count; i++)
{
Vector3 temp = Camera.main.WorldToScreenPoint(objs[i].position) - offset;
if (temp.x > startPos.x && temp.x < (startPos.x + rt.sizeDelta.x) &&
temp.y < startPos.y && (temp.y > startPos.y - rt.sizeDelta.y))
{
objs[i].GetComponent<Player>().Choose(true);
}
else
{
objs[i].GetComponent<Player>().Choose(false);
}
}
最后效果: