실행 이미지

 

[실행 순서]

마우스 왼쪽 클릭  -> 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 설정 스크립트)

+ Recent posts