C# 访问自定义类的IEnumerable时出现NullReferenceException 球门

C# 访问自定义类的IEnumerable时出现NullReferenceException 球门,c#,linq,ienumerable,boids,C#,Linq,Ienumerable,Boids,我正在使用Unity设计一个系统。我通过在蜂群进入对撞机时向蜂群列表添加一个boid来处理感知半径。为了找到每个boid的力,我需要遍历swarm列表,访问boid类,并检索速度和位置 问题 来自每个swarm实体的Boid类被添加到一个新列表中,并传递给物理控制器。然而,在第96行抛出了一个NullReferenceException,我不明白为什么该变量会为null。据我所知,使用foreach访问填充的枚举表时应该包含变量 NullReferenceException:对象引用未设置为对象

我正在使用Unity设计一个系统。我通过在蜂群进入对撞机时向蜂群列表添加一个boid来处理感知半径。为了找到每个boid的力,我需要遍历swarm列表,访问boid类,并检索速度和位置

问题 来自每个swarm实体的Boid类被添加到一个新列表中,并传递给物理控制器。然而,在第96行抛出了一个NullReferenceException,我不明白为什么该变量会为null。据我所知,使用foreach访问填充的枚举表时应该包含变量

NullReferenceException:对象引用未设置为对象的实例 Boid.Alignment System.Collections.Generic.IEnumerable`1[T]Boid位于Assets/Scripts/Boid.cs:96 更新地址:Assets/Scripts/Boid.cs:42

在测试之后,它似乎是在访问新BOID列表的任何部分时抛出的

为什么我的新列表不包含任何数据?有没有更好的方法在3D空间中处理BOID的2D实现?有什么资源可以让我更好地理解Linq吗

另外,我对使用Linq系统非常陌生,这段代码大部分来自和

密码 背景图片 证明boid类具有要读取的数据 统一环境与Boid.cs附件 统一体部件 游戏运行时,每个博伊德会找到两个蜂群伙伴

原来我分配的是空数据,因为第40行的GetComponent函数找到了Boid的主体,而Boid没有附加Boid脚本。使用GetComponentChildren搜索时,将填充数组并给出值

老一套:

IEnumerable boids=swarm.Selecto=>o.GetComponent.ToList

新线:


IEnumerable boids=swarm.Selecto=>o.getComponentChildren.ToList

检查Boid.cs第96行。这就是错误发生的地方,但我不明白为什么。@Sove67从异常堆栈跟踪来看,当您将变量Boid传递给AlignmentBOID;时,错误出现在更新方法中;。在这一行上设置一个断点,并检查IEnumerable boids=swarm.Selecto=>o.GetComponent.ToList的前一行的boids是否为null@RyanWilson I在Alignmentboids之前添加了if boids==null{Debug.LogNo Data Attached;},但没有调用它。这是否回答了您的问题?你也检查过身体不为空吗?
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Boid : MonoBehaviour
{
// Global Variables
public Boid_Settings settings;

// Local Variables
public Rigidbody body;
public Vector2 acceleration;
public Vector2 velocity
{
    get
    { return new Vector2(body.velocity.x, body.velocity.z); }
    set
    { body.velocity = new Vector3(value.x, body.velocity.y, value.y); }
}
public Vector2 position
{
    get
    { return new Vector2(transform.position.x, transform.position.z); }
}
public List<GameObject> swarm = new List<GameObject>();
public List<GameObject> targets = new List<GameObject>();


// Functions
private void Start()
{
    float angle = Random.Range(0, 2 * Mathf.PI);
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
    velocity = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
}

private void Update()
{
    IEnumerable<Boid> boids = swarm.Select(o => o.GetComponent<Boid>()).ToList(); //Line 40

    Vector2 alignment = Alignment(boids); //LINE 42
    Vector2 separation = Separation(boids);
    Vector2 cohesion = Cohesion(boids);

    acceleration = settings.alignmentWeight * alignment + settings.cohesionWeight * cohesion + settings.seperationWeight * separation;

    UpdatePhysics();
}

// Entity Awareness Assignment
private void OnTriggerEnter(Collider collider)
{
    if (collider.CompareTag("Zombie"))
    { swarm.Add(collider.gameObject); }
    else if (collider.CompareTag("Player") || collider.CompareTag("Lure"))
    { targets.Add(collider.gameObject); }
}

private void OnTriggerExit(Collider collider)
{
    if (collider.CompareTag("Zombie"))
    { swarm.Remove(collider.gameObject); }
    else if (collider.CompareTag("Player") || collider.CompareTag("Lure"))
    {
        targets.Remove(collider.gameObject);
        StartCoroutine(LingerTarget(collider.gameObject));
    }
}

IEnumerator LingerTarget(GameObject target)
{
    targets.Add(target);
    yield return new WaitForSeconds(settings.lingerTime);
    targets.Remove(target);
}


// Core Boid Logic
public void UpdatePhysics()
{
    // Apply the acceleration, and then limit the speed to the maximum.
    Vector2 UncappedVelocity = velocity + acceleration;
    velocity = ApplyLimit(UncappedVelocity, settings.maxSpeed);

    float angle = Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg;
    body.transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}

private Vector2 Alignment(IEnumerable<Boid> boids)
{
    Vector2 velocity = Vector2.zero;
    if (!boids.Any()) return velocity;

    foreach (Boid boid in boids)
    { velocity += boid.velocity; } //LINE 96
    velocity /= boids.Count();

    Vector2 steer = Steer(velocity.normalized * settings.maxSpeed);
    return steer;
}

private Vector2 Cohesion(IEnumerable<Boid> boids)
{
    if (!boids.Any()) return Vector2.zero;

    Vector2 sumPositions = Vector2.zero;
    foreach (Boid boid in boids)
    { sumPositions += boid.position; }
    Vector2 average = sumPositions / boids.Count();
    Vector2 direction = average - position;

    Vector2 steer = Steer(direction.normalized * settings.maxSpeed);
    return steer;
}

private Vector2 Separation(IEnumerable<Boid> boids)
{
    Vector2 direction = Vector2.zero;
    boids = boids.Where(o => Vector3.Distance(o.transform.position, position) <= settings.avoidanceRadius);
    if (!boids.Any()) return direction;

    foreach (Boid boid in boids)
    {
        Vector2 difference = position - boid.position;
        direction += difference.normalized / difference.magnitude;
    }
    direction /= boids.Count();

    Vector2 steer = Steer(direction.normalized * settings.maxSpeed);
    return steer;
}

private Vector2 Steer(Vector2 desired)
{
    Vector2 steer = desired - velocity;
    steer = ApplyLimit(steer, settings.maxSteerForce);

    return steer;
}

// Calculation Helpers
private Vector2 ApplyLimit(Vector2 baseVector, float limit)
{
    if (baseVector.sqrMagnitude > limit * limit)
    { baseVector = baseVector.normalized * limit; }
    return baseVector;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CreateAssetMenu]
public class Boid_Settings : ScriptableObject
{
// Boid
public float maxSpeed = 5;
public float avoidanceRadius = 1;
public float maxSteerForce = 3;

public float lingerTime = 2.5f;
public float alignmentWeight = 1;
public float cohesionWeight = 1;
public float seperationWeight = 1;
public float targetWeight = 1;

// Spawner
public float awarenessRadius = 2.5f;
}