查找并 return 个最近的带有标签 Unity 的游戏对象

Find and return nearest gameObject with tag, Unity

我正在尝试制作一款游戏,您必须合并 2 个游戏对象才能获得下一个游戏对象。首先,我尝试这样当游戏对象被释放并且它正在接触另一个游戏对象时,它会删除这两个游戏对象,然后实例化下一个。但这并不是很有效,因为触发器“覆盖”了彼此或其他一些奇怪的东西。所以我想我可以检测到碰撞,这样每个接触触发器的游戏对象都会添加到列表中,然后在退出时删除。我不想弄清楚的是如何计算游戏对象之间的距离,如果它们足够近(合并阈值)那么它们都会被破坏并且下一个游戏对象被实例化,但我不太清楚如何获得这个距离计算并返回什么游戏对象。所以所有的帮助将不胜感激! (不要遗漏任何细节,因为我是初学者) 谢谢!

这是我目前得到的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Merging : MonoBehaviour
{
    List<GameObject> NearGameobjects = new List<GameObject>();


    void Start()
    { 
    }

    void Update()
    {
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag == gameObject.tag)
        {
            Debug.Log("Enter!");
            NearGameobjects.Add(col.gameObject);
        }
    }


    void OnTriggerExit2D(Collider2D col)
    {
        if (col.gameObject.tag == gameObject.tag)
        {
            Debug.Log("Exit!");
            NearGameobjects.Remove(col.gameObject);
            
        }
    }
}

如果您打算使用该列表并将所有对象添加到该列表中,您可以使用 for each 循环并检查您的主要对象与列表中所有其他对象之间的距离,如果它更接近添加到壁橱对象

    public class NewBehaviourScript : MonoBehaviour {
    List<GameObject> NearGameobjects = new List<GameObject>();
    GameObject closetsObject;
    private float oldDistance = 9999;


    private void Something()
    {
        foreach (GameObject g in NearGameobjects)
        {
            float dist = Vector3.Distance(this.gameObject.transform.position, g.transform.position);
            if (dist < oldDistance)
            {
                closetsObject = g;
                oldDistance = dist;
            }
        }
    }

}

对于任何想知道的人来说,由于 CubeCrafter360,这是完美运行的全部代码!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;

public class Merging : MonoBehaviour
{
    List<GameObject> NearGameobjects = new List<GameObject>();
    GameObject closetsObject;
    private float oldDistance = 9999;
    public GameObject NextPF;
    public float mergingThreshold = 0.3f;


    void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject.tag == gameObject.tag)
        {
            Debug.Log("Enter!");
            NearGameobjects.Add(col.gameObject);
        }
    }


    void OnTriggerExit2D(Collider2D col)
    {
        if (col.gameObject.tag == gameObject.tag)
        {
            Debug.Log("Exit!");
            NearGameobjects.Remove(col.gameObject);

        }
    }
    
    public void CheckNearest()
    {
        foreach (GameObject g in NearGameobjects)
        {
            float dist = Vector3.Distance(this.gameObject.transform.position, g.transform.position);
            if (dist < oldDistance)
            {
                closetsObject = g;
                oldDistance = dist;
  
            }
        }
        if (Vector3.Distance(this.gameObject.transform.position, closetsObject.transform.position) < mergingThreshold)
        {
            Destroy(gameObject);
            Destroy(closetsObject);
            Instantiate(NextPF, transform.position, Quaternion.identity);
        }
    }



}

And then i just called the function in my movement script:

private void OnMouseUp()
    {
        GetComponent<Merging>().CheckNearest();
    }

您可以使用 Linq OrderBy:

按距离排序列表
using SystemLinq;

...

public void CheckNearest()
{
    if(NearGameobjects.Count == 0) return;

    // This orders the list so the closest object will be the very first entry
    var sorted = NearGameobjects.OrderBy(obj => (col.transform.position - transform.position).sqrMagnitude);

    // currently closest
    var closest = sorted.First();

    if (Vector3.Distance(this.gameObject.transform.position, closest.transform.position) < mergingThreshold)
    {
        Destroy(gameObject);
        Destroy(closetsObject);
        Instantiate(NextPF, transform.position, Quaternion.identity);
    }
}

private void OnTriggerEnter2D(Collider2D col)
{
    // Rather use CompareTag
    if (col.CompareTag(tag))
    {
        Debug.Log("Enter!");
        NearGameobjects.Add(col.gameObject);
    }
}

private void OnTriggerExit2D(Collider2D col)
{
    if (col.CompareTag(tag))
    {
        Debug.Log("Exit!");
        NearGameobjects.Remove(col.gameObject);
    }
}