【问题标题】:How to ignore missing components in list?如何忽略列表中缺少的组件?
【发布时间】:2019-09-18 08:05:18
【问题描述】:

我有相机脚本,可以随玩家移动相机。但是当玩家被Destroy(gameObject); 摧毁时 - 相机卡住了。这是因为我在列表中缺少元素。

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

如何从列表中删除我被破坏的目标?

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

    // 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
} 

【问题讨论】:

  • 我们需要你的 Cam Move 脚本
  • How to remove all the null elements inside a generic list in one go? 的可能重复项或在列表中迭代的任何位置,如果您想在列表中保留空 (null) 条目但跳过它,只需执行 if(element == null) continue; 即可
  • float GetGreatestDistance() { var bounds = new Bounds(targets[0].position, Vector3.zero); for (int i = 0; i &lt; targets.Count; i++) { bounds.Encapsulate(targets[i].position); } return Mathf.Max(bounds.size.x, bounds.size.y); }
  • 一些cammove代码
  • @derHugo 我应该在哪里使用它,element 是什么?

标签: c# unity3d


【解决方案1】:

你的线路

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); 
}

【讨论】:

  • 很好,很好的答案,但是第二个脚本中的item 是什么? targets.RemoveAll(item =&gt; item == null);
  • 这是lambda expressionitem 就像 foreach(var item in targets) 中的迭代器。
  • targets.RemoveAll(item => item == null);效果很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
  • 2015-09-22
  • 1970-01-01
相关资源
最近更新 更多