【问题标题】:Class instance null after instantiation实例化后的类实例为空
【发布时间】:2019-06-24 18:29:21
【问题描述】:

更新:正如下面的 cmets 中提到的,定位 target_manager; (在 MakeAbility 中)为空。这似乎是问题的根源,但为什么它是空的?

============

在下面的代码中,我创建了 PartAttack 类的一个实例,然后为我的目标管理器分配了引用。

第一个调试日志返回 PartAttack。第二个返回 null。

public Targeting target_manager(在第一个脚本中)在检查器中分配给带有 Targeting 脚本的游戏对象。

我做错了什么?为什么这没有正确分配目标管理器?

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

public class MakeAbility : MonoBehaviour
{
    public BlockScriptableObject block;

    public IDictionary<string, IAbility> abilities_parts = new Dictionary<string, IAbility>();


    public Targeting target_manager;
    public PartAttack part_attack = new PartAttack();

    private void Start()
    {
        part_attack.block_attack_damage = block.attack_damage;
        part_attack.target_manager = target_manager;
        Debug.Log(part_attack);
        Debug.Log(part_attack.target_manager);

        abilities_parts.Add("part_attack", part_attack);

    }

}

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


[System.Serializable]
public class PartAttack: IAbility
{
    public Targeting target_manager;

    public void Use()
    {

    }

}


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

public class Targeting : MonoBehaviour
{
    public int max_targets = 3;
    public string current_target = null;
    public List<Combatant> list_of_targetable = new List <Combatant>();

    public BlockScriptableObject block; // The abilityblock

    public GameObject target_clickfield_char1;
    public Combatant character_slot_1;

}

【问题讨论】:

  • public Targeting target_manager 在检查器中分配给带有 Targeting 脚本的游戏对象。
  • public Targeting target_manager;(在 MakeAbility 中)和 public Targeting target_manager;(在 PartAttack 中)不是同一个对象。
  • 最初是这样,但我不是将 PartAttack target_manager 设置为与另一个实例相同的实例吗?
  • public Targeting target_manager;(在 MakeAbility 中)是否为非空?
  • 您不会使用 new 或构造函数创建 MonoBehaviour 类型的实例。创建新实例的唯一方法是使用 gameObjectReference.AddComponent() 将其添加到现有游戏对象!你不是说已经在 Inspector 中引用了相应的 GameObject 吗?那你为什么用public Targeting target_manager = new Targeting();(这是不允许的)呢?

标签: c# unity3d


【解决方案1】:

TargetManager 似乎没有在任何地方实例化。

【讨论】:

    【解决方案2】:

    您需要将 TargetManager 设置为内存分配。这是通过实例化完成的。

    您可以为聚合类创建一个构造函数,通过实例化变量来分配此内存,或者您可以在主函数中将 target_manager 设置为一些新的内存分配。

    public Targeting target_manager = new Targeting();
    

    C# 速度很快。而且我们不能指望在声明指针之后这么快就看到实例化的对象。我知道系统中的其他地方有一个游戏对象最终会分配它,但是对于您的调试脚本,这还没有发生。

    如果你打算总是有一些东西,你需要将它分配给构造函数内的一个空对象。特别是如果您编写的代码行在声明其存在后将立即访问它。不要依赖存在于不同对象中的其他代码。对计算机来说,代码很遥远。

    这不会影响您以后的分配,因为重新分配不会破坏任何东西,它只会在其他地方分配更多内存。

    如果您担心内存泄漏,请在重新声明之前处理对象。

    【讨论】:

    • 不幸的是,添加您提到的特定行并没有改变任何结果。我将它单独添加到每个类中,并将其添加到两个类中。第一个调试仍然是 PartAttack,第二个仍然是 null。虽然答案很有趣,但它本身就非常容易理解和有趣。
    • 正因为如此,我要说,我们需要查看更多代码来提供帮助。
    • 我现在正在添加定位类。一个想法出现了,这可能是由于不同的实例化规则而不是来自单一行为吗?
    • 您不能使用new 或构造函数创建MonoBehaviour 类型的实例。创建新实例的唯一方法是使用 gameObjectReference.AddComponent&lt;YourType&gt;()! 将其添加到现有 GameObject!
    猜你喜欢
    • 2012-06-21
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多