如何忽略列表中缺少的组件?

时间:2019-04-29 16:53:03

标签: c# unity3d

我有用于随身携带相机的相机脚本。但是当玩家被Destroy(gameObject);摧毁时-相机卡死了。这是因为列表中缺少元素。

missing elements

如何忽略这些缺失的元素?

如何从列表中删除我被销毁的目标?

但是第二个问题很难解释。 我有脚本,在此脚本中,我导入了目标列表。但是此脚本不起作用。它不会从列表中删除目标。

    // PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float hp1 = 7;
    public float damage2 = 4;
    private CamMove s1;


    void Start()
    {
        s1 = GetComponent<CamMove>();
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Bullet2")
        {
            hp1 -= damage2;
        }
    }

    void FixedUpdate()
    {
        if (hp1 <= 0) // death
        {
            s1.targets.Remove(GameObject.FindWithTag("Player1body").transform); // trying to remove target from list 
            Destroy(gameObject); // then desrtoy main object
        }
    } // also I added tag "Player1body" in Unity to my prefab
} 

2 个答案:

答案 0 :(得分:0)

您的专线

s1.targets.Remove(GameObject.FindWithTag("Player1body").transform);

始终会删除整个场景中标签为"Player1body"的对象的第一次遇到-而不是您实际要删除的对象(请参阅GameObject.FindWithTag)。


在继续操作之前先检出How to remove all the null elements inside a generic list in one go?,以删除空白(null)条目

float GetGreatestDistance() 
{ 
    // removes all empty entries from the list
    targets.RemoveAll(item => item == null);

    // should check now if there is any entry available
    if(targets.Count == 0) return 0;

    var bounds = new Bounds(targets[0].position, Vector3.zero);

    for(var i = 1; i < targets.Count; i++) 
    { 
        bounds.Encapsulate(target.position); 
    } 

    return Mathf.Max(bounds.size.x, bounds.size.y); 
}

但是,如果要在列表中保留空(null)元素,但是跳过它们,只会变得稍微复杂一点:

float GetGreatestDistance() 
{ 
    // should check now if there is any entry available
    if(targets.Count == 0) return 0;

    Bounds bounds;

    // start loop at 0
    for(var i = 0; i < targets.Count; i++) 
    { 
        // skip if empty
        if(targets[i] == null) continue;

        // only for the first not empty entry do
        if(bounds == null)
        { 
            bounds = new Bounds(targets[i].position, Vector3.zero);
        }
        else
        {
            bounds.Encapsulate(target.position);
        } 
    } 

    // check if bounds was set
    return bounds == null ? 0 : Mathf.Max(bounds.size.x, bounds.size.y); 
}

答案 1 :(得分:0)

向列表targets所在的脚本中添加一个函数,并编写此函数private void OnDestroy(){}。那是一个标准的统一函数,当棋被销毁时会被调用。在该函数内编写targets.Remove(*gameobject to destroy*);