Создание области выбора
Во многих стратегических играх используется механизм выделения области на карте мышью. Объекты внутри этой области активируются и становятся доступны для взаимодействия. Мы реализуем подобный функционал, создав куб, который будет представлять область выбора. При нажатии мыши создаётся куб. При перемещении мыши куб увеличивается, формируя область. При отпускании мыши куб исчезает, а объекты внутри активируются.
Создадим куб и удалим компонент Box Collider. Переименуем куб в Selection Cube.
Скрипт SelectController
Создадим C# скрипт SelectController с полями:
- public GameObject cube: ссылка на префаб куба.
- private Camera cam: ссылка на основную камеру.
- public LayerMask layer: слой, с которым взаимодействует луч.
- private GameObject cubeSelection: ссылка на созданный экземпляр куба.
- private List<GameObject> players = new List<GameObject>();: список выбранных объектов.
В методе Start получим компонент камеры:
void Start()
{
cam = Camera.main;
}
В Update отслеживаем нажатие и отпускание правой кнопки мыши:
void Update()
{
if (Input.GetMouseButtonDown(1))
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layer))
{
GameObject cubeInstance = Instantiate(cube, new Vector3(hit.point.x, 1, hit.point.z), Quaternion.identity);
cubeSelection = cubeInstance;
players.Clear(); // Очищаем список при каждом новом выборе
}
}
else if (Input.GetMouseButtonUp(1) && cubeSelection != null)
{
SelectObjects();
Destroy(cubeSelection);
cubeSelection = null;
}
else if (Input.GetMouseButton(1) && cubeSelection != null)
{
UpdateCubeScale();
}
}
Увеличение и позиционирование куба
Для увеличения куба в одном направлении создадим пустой объект Selection Cube Parent и сделаем Selection Cube его дочерним объектом. Смещение центра куба позволит увеличивать его в одном направлении. Смещаем дочерний объект по оси x на 0.5 и по оси z на -0.5.
Метод UpdateCubeScale:
void UpdateCubeScale()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hitDrag;
if (Physics.Raycast(ray, out hitDrag, Mathf.Infinity, layer))
{
float xScale = Mathf.Abs(cubeSelection.transform.position.x - hitDrag.point.x);
float zScale = Mathf.Abs(cubeSelection.transform.position.z - hitDrag.point.z);
cubeSelection.transform.localScale = new Vector3(xScale * 2, 1, zScale * 2);
}
}
Удалим тени у куба и изменим материал на прозрачный белый.
Выбор объектов и метод SelectObjects
Добавим слой Player к игровым объектам (машинкам). Метод SelectObjects выполняет выбор объектов внутри куба:
void SelectObjects()
{
RaycastHit[] hits = Physics.BoxCastAll(cubeSelection.transform.position, cubeSelection.transform.localScale / 2, Vector3.zero, Quaternion.identity, 0, layer);
foreach (RaycastHit hit in hits)
{
players.Add(hit.transform.gameObject);
}
}
Добавим Box Collider к машинкам, возможно, увеличив его размер. В LayerMask основной камеры укажем слой Player.
Мы реализовали функционал выбора игровых объектов с помощью динамически создаваемой области в виде куба. Механизм корректно работает независимо от направления движения мыши. Объекты внутри области добавляются в список для дальнейшего управления. Создадим папку Prefabs и поместим туда префаб куба. Установим ссылку на префаб в поле cube и слой ground в поле layer.