Arcana Affinity
Arcana Affinity

Reputation: 307

Trying to get the GameObject by distance in a List

private GameObject m_PC;
private GameObject m_target;

private List<GameObject> m_targetList = new List<GameObject>();

private void Awake()
{
    m_PC = GameObject.Find("PlayerCharacter");
}

private void GetInitialTarget()
{
    if (m_targetList.Count >= 2)
    {
        foreach (GameObject item in m_targetList)
        {
            float dist = Vector3.Distance(m_PC.transform.position, item.transform.position);

            Debug.Log(item + " : " + dist);
        }

        m_targetList.Sort();
    }
    else if (m_targetList.Count == 1)
    {
        m_target = m_targetList[0];
    }
}

private void OnTriggerEnter(Collider other)
{
    if (other.gameObject.tag == "Check")
    {
        GameObject targetGO = other.transform.gameObject;

        m_targetList.Add(targetGO);
    }
}

Here I'm trying to collect all the GameObjects with tag inside the Collider this object has. What I wanted to do next was to compare each item collected by a factor; the distance between m_PC here to store in variable m_target. Aaaand, that's pretty much where I'm stuck at the moment.

first I thought I'd be wrong to use List here and use Dictionary instead to achieve that distance would become the TValue for each GameObject with tag this collider finds, but then I wasn't so sure I was going the right direction. Later, I wanted to add another factor to this by another prioritization like GameObject A being a trash NPC and B being a boss NPC but I think that can wait. I did try to absorb IComparable and IComparer thinking that's what I needed, but not really getting there by myself.

// I've tried replacing List to Dictionary having GameObject as TKey and float(distance) as TValue, but there I am stuck how to get the GameObject out for m_target To have according to TValue of distance.

Upvotes: 2

Views: 983

Answers (1)

Linq is amazing here.

m_targetList.Sort(
    (x, y) => Vector3.Distance(m_PC.transform.position, x.transform.position)
                .CompareTo(Vector3.Distance(m_PC.transform.position, y.transform.position))
);

Essentially what this is is a lambda function that compares two objects in the list and returns a comparison value (1, 0, or -1) that is used to sort the list in ascending order (y.CompareTo(x) will sort in descending order).

There's all kinds of LINQ operations, such as "find me any items that match this criteria" and provide a lambda expression that evaluates on that criteria, say...

Find me all enemies that are more than 5 units above the player

m_targetList.FindAll(x => Vector3.Distance(m_PC.transform.position, x.transform.position).y > 5)

Upvotes: 2

Related Questions