【问题标题】:How to loop through unity gameobjects如何循环通过统一游戏对象
【发布时间】:2020-06-18 10:47:27
【问题描述】:

我想制作一个循环遍历所有带有标签的游戏​​对象的脚本,Enemy 我从here修改了一个代码sn-p,结果出现2个错误。


Cannot Implicitly convert 'Unity.GameObject[]' to 'Unity.GameObject'

Error   CS1579  foreach statement cannot operate on variables of type 'GameObject' because 'GameObject' does not contain a public instance definition for 'GetEnumerator'

如果有人能告诉我为什么会发生这种情况或解决方案,我将不胜感激,在此先感谢! 这是我的代码:

void FixedUpdate()

{
    GameObject objects = GameObject.FindGameObjectsWithTag("Enemy");
    var objectCount = objects.Length;
    foreach (var obj in objects)
    {
        // Move the players accordingly
        //var rb = 
        Vector2 direction = (player.position - transform.position).normalized;
        obj.rigidbody.velocity = direction * moveSpeed;

    }
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    FindGameObjectsWithTag 作为名称提示返回一个GameObject[]

    为了获得附加的Rigidbody2D,请使用GetComponent<Rigidbody2D>

    应该是GameObject[] 或简单的var

    /*GameObject[]*/ var objects = GameObject.FindGameObjectsWithTag("Enemy");
    var objectCount = objects.Length;
    foreach (var obj in objects)
    {
        // Move the players accordingly
        var rb = obj.GetComponent<Rigidbody2D>()
        Vector2 direction = (player.position - transform.position).normalized;
        rb.velocity = direction * moveSpeed;
    }
    

    第二个错误只是一个后续错误,因为您将 objects 声明为 GameObject,实际上正如错误所说,没有 GetEnumerator 实现。


    一般来说,重复使用FindObjectsWithTag 并不是最好的选择。我宁愿使用包含所有现有实例的static 列表的模式,例如

    // Put this component on your enemy prefabs / objects
    public class EnemyController : MonoBehaviour
    {
        // every instance registers to and removes itself from here
        private static readonly HashSet<EnemyController> _instances = new HashSet<EnemyController>();
        
        // Readonly property, I would return a new HashSet so nobody on the outside can alter the content
        public static HashSet<EnemyController> Instances => new HashSet<EnemyController>(_instances);
    
        // If possible already drag the Rigidbody into this slot via the Inspector!
        [SerializedField] private Rigidbody2D rb;
    
        // public read-only access
        public Rigidbody2D Rb => rb;
    
        private void Awake()
        {
            if(!rb) rb = GetComponent<Rigidbody2D>();
            _instances.Add(this);
        }
    
    
        private void OnDestroy()
        {
            _instances.Remove(this);
        }
    }
    

    然后使用

    var enemies = EnemyControler.Instances;
    foreach (var enemy in enemies)
    {
        // Move the players accordingly
        Vector2 direction = (player.position - transform.position).normalized;
        enemy.Rb.velocity = direction * moveSpeed;
    }
    

    【讨论】:

      【解决方案2】:

      GameObject 类型声明更改为var

      或者把它改成GameObject[],因为FindGameObjectsWithTag返回一个GameObject的数组

      我也不会使用FindGameObjectsWithTag,它很慢。在更新方法中更是如此

      【讨论】:

      • 我将 GameObject 更改为 GameObject[] 但我仍然不知道如何访问该特定对象的刚体。
      • 你需要使用 GetComponent 来获取它,但它也很慢,创建一个包含敌人逻辑的域特定类型
      【解决方案3】:

      首先,将GameObject 更改为GameObject[],因为FindGameObjectsWithTag 返回一个GameObject 数组。注意不要将它与没有返回单个 GameObject 的 s 的 FindGameObjectWithTag 混淆

      其次,我认为最好有一个单独的 Enemy 脚​​本或类似的东西并将它们分配给每个敌人,而不是使用非常慢的 FindGameObjectsWithTag

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多