게임 개발/C#

List 클래스를 LINQ로 정렬하기

FlowTree 2020. 7. 15. 09:39
반응형

콜라이더로 검출한 오브젝트들을 거리 순서에 따라 오름차순 정렬을 하고 싶었다.

게임오브젝트와 거리 변수를 담는 클래스를 선언하고 List로 선언하고 LINQ를 이용하여

오름차순으로 정렬하는데 성공했다.

 

하지만 LINQ로 정렬된 게임오브젝트만 따로 배열로 저장하려고 했지만 방법을 못 찾았다.

C# List 클래스 정렬 방법을 찾아서 그걸로 구현할 생각이다.

 

그래도 LINQ로 구현한 건 저장해야지

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq; //LINQ 사용

public class LightningStrike : MonoBehaviour
{
    public class Target
    {
        public GameObject targetGameobject { get; set;}
        public float targetDistance { get; set;}
    }

    List<Target> targets = new List<Target>();

    public float viewRadius;
    [Range(0, 360)]
    public float viewAngle;


    public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal)
    {
        if (!angleIsGlobal)
        {
            angleInDegrees += transform.eulerAngles.y;
        }
        return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad ));
    }

    public LayerMask targetMask;
    public LayerMask obstacleMask;
    public GameObject targeting; 
 
    public void FindTargets()
    {
        targets.Clear();
        Collider[] targetInViewRadius = Physics.OverlapSphere(transform.position, viewRadius, targetMask);
        for (int i = 0; i < targetInViewRadius.Length; i++) //ViewRadius 안에 있는 타겟의 개수 = 배열의 개수보다 i가 작을 때 for 실행
        {
            GameObject target = targetInViewRadius[i].gameObject; //타겟[i]의 위치
            Vector3 dirToTarget = (target.transform.position - transform.position).normalized; //vector3타입의 타겟의 방향 변수 선언 = 타겟의 방향벡터, 타겟의 position - 이 게임오브젝트의 position) normalized = 벡터 크기 정규화 = 단위벡터화

            // 전방 벡터와 타겟방향벡터의 크기가 시야각의 1/2이면 = 시야각 안에 타겟 존재
            if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2)
            {                    
                //Debug.Log(Vector3.Angle(dirToTarget, transform.forward));

                float dstToTarget = Vector3.Distance(transform.position, target.transform.position); //타겟과의 거리를 계산

                if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask)) //레이캐스트를 쐇는데 obstacleMask가 아닐 때 참이고 아래를 실행함
                {
                    targets.Add(new Target() { targetGameobject = target, targetDistance = dstToTarget });
                }
            }
        }

        foreach (Target atarget in targets)
        {
            Debug.Log(atarget.targetGameobject.name + atarget.targetDistance);
        }

        Debug.Log(targets.Count);

        //LINQ 오름차순 정렬, 오름차순으로 정리
        var result = from sortDistance in targets
                           //where 필터 필요없어서 안적었는데 잘 작동함
                           orderby sortDistance.targetDistance
                           select sortDistance;

        //LINQ로 오름차순 정렬한 값 result를 확인하려고 작성한 코드임
        foreach (Target aa in targetsQuery)
        {
            Debug.Log(aa.targetGameobject.name + aa.targetDistance);
        }
    }
}        

 

반응형