[실행 순서]
마우스 왼쪽 클릭 -> Shift + 마우스 왼쪽클릭 -> 드래그로 오브젝트 다중 선택
** 선택한 영역이 오브젝트가 아닌 땅바닥(null)이라면 선택이 해제된다 **
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SelectGO : MonoBehaviour
{
[SerializeField] GameObject indicator;
private Camera mainCamera;
public LayerMask enemyLayer;
private Vector2 startMousePosition;
private Vector2 endMousePosition;
private bool isDragging = false;
private Larva[] larvasArray;
private List<Larva> larvasList;
void Start()
{
mainCamera = Camera.main;
larvasArray = FindObjectsOfType<Larva>();
larvasList = larvasArray.ToList();
StartCoroutine("SelectLarva");
StartCoroutine("DrawingRectangle");
}
IEnumerator SelectLarva()
{
while (true)
{
if (Input.GetMouseButtonDown(0))
{
startMousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
isDragging = true;
}
if (Input.GetMouseButtonUp(0))
{
endMousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
isDragging = false;
if (Vector2.Distance(startMousePosition, endMousePosition) > 0.1f)
{
SelectLarvasInRectangle(startMousePosition, endMousePosition);
}
else
{
ProcessSingleSelection(endMousePosition);
}
}
yield return null;
}
}
IEnumerator DrawingRectangle()
{
while (true)
{
if (Input.GetMouseButtonDown(0))
{
startMousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
isDragging = true;
}
// 마우스 버튼을 누르고 있는 동안에만 현재 마우스 위치를 추적
if (Input.GetMouseButton(0) && isDragging)
{
// 마우스의 현재 위치를 endMousePosition으로 지속적으로 업데이트
endMousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
}
if (Input.GetMouseButtonUp(0))
{
isDragging = false;
}
// 드래그 중이라면 실시간으로 사각형 그리기
if (isDragging)
{
DrawSelectionRectangle(startMousePosition, endMousePosition);
}
yield return null;
}
}
IEnumerator MoveIndicator(Vector3 position)
{
indicator.SetActive(true);
indicator.transform.position = position;
yield return new WaitForSeconds(0.5f);
indicator.SetActive(false);
}
void ProcessSingleSelection(Vector2 position)
{
Collider2D clickedCollider = Physics2D.OverlapPoint(position, enemyLayer);
if (clickedCollider != null)
{
bool isShift = Input.GetKey(KeyCode.LeftShift);
if (!isShift)
{
foreach (var larva in larvasList)
{
larva.ChangeTargetPoint(false);
}
}
clickedCollider.gameObject.GetComponent<Larva>().ChangeTargetPoint(true);
}
else
{
foreach (var larva in larvasList)
{
larva.ChangeTargetPoint(false);
}
MoveIndicator(position);
}
}
void SelectLarvasInRectangle(Vector2 startPoint, Vector2 endPoint)
{
Vector2 center = (startPoint + endPoint) / 2;
Vector2 size = new Vector2(Mathf.Abs(startPoint.x - endPoint.x), Mathf.Abs(startPoint.y - endPoint.y));
Collider2D[] hitColliders = Physics2D.OverlapBoxAll(center, size, 0, enemyLayer);
foreach (var hitCollider in hitColliders)
{
Larva larva = hitCollider.GetComponent<Larva>();
if (larva != null)
{
larva.ChangeTargetPoint(true);
}
else
{
larva.ChangeTargetPoint(false);
}
}
}
void DrawSelectionRectangle(Vector2 startPoint, Vector2 endPoint)
{
// 사각형의 네 모서리 계산
Vector3 bottomLeft = new Vector3(Mathf.Min(startPoint.x, endPoint.x), Mathf.Min(startPoint.y, endPoint.y), 0);
Vector3 topLeft = new Vector3(Mathf.Min(startPoint.x, endPoint.x), Mathf.Max(startPoint.y, endPoint.y), 0);
Vector3 topRight = new Vector3(Mathf.Max(startPoint.x, endPoint.x), Mathf.Max(startPoint.y, endPoint.y), 0);
Vector3 bottomRight = new Vector3(Mathf.Max(startPoint.x, endPoint.x), Mathf.Min(startPoint.y, endPoint.y), 0);
// 네 모서리를 잇는 선 그리기
Debug.DrawLine(bottomLeft, topLeft, Color.green);
Debug.DrawLine(topLeft, topRight, Color.green);
Debug.DrawLine(topRight, bottomRight, Color.green);
Debug.DrawLine(bottomRight, bottomLeft, Color.green);
}
}
SelectGo.cs (마우스를 이용한 Select 설정)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Larva : MonoBehaviour
{
[SerializeField] GameObject targetPoint;
private bool isActive = false;
void Start()
{
StartCoroutine("SelectLarva");
}
IEnumerator SelectLarva()
{
while (true)
{
this.targetPoint.SetActive(isActive);
yield return null;
}
}
public void ChangeTargetPoint(bool state)
{
this.isActive = state;
}
}
Larva.cs (TargetPoint 설정 스크립트)
'산대특 > 게임 플랫폼 응용 프로그래밍' 카테고리의 다른 글
A* 알고리즘 구현해보기 (2) - 출발 지점에서 목표 지점까지 경로 구하기 (0) | 2024.03.03 |
---|---|
A* 알고리즘 구현해보기 (1) - 이동 불가 노드와 이동 가능 노드 구별하기 (0) | 2024.03.03 |
화면을 클릭할때까지 기다리다가 2초마다 "대기중" 이라고 출력하고, 화면을 클릭하면 "완료" 라고 출력하기 (0) | 2024.02.29 |
코루틴 안에서 코루틴 실행하기 (0) | 2024.02.29 |
탱크 시즈모드 Splash 공격 구현하기 (0) | 2024.02.29 |