【问题标题】:Heritage, child variable not working遗产,子变量不起作用
【发布时间】:2018-01-15 22:27:09
【问题描述】:

Unity有这个问题,但我想我只是在c#方面做错了。

编辑

看起来通过编写代码并存储父类 A 的子类 B,并且说是 A 类类型,通过修改包含 B 类的 A 类类型的变量,我修改了某种混合类A/B 不代表我真正的 B 类脚本

我所做的是,在不同的预制件上有多个脚本。这些脚本中的每一个都代表一个项目,并且都有父级 Usable,这是一个我实际使用的类,就像一个接口,但将来会得到一些东西。

完整的WeaponLaserUsable 脚本如下

当玩家越过一个水滴时,我实例化包含这样的脚本的游戏对象(使用预制)

GameObject Item = Instantiate(droppedItem, transform.position, Quaternion.identity);
Item.transform.parent = transform;
usableItem = droppedItem.GetComponent<Usable>();
usableItem.OnUsed += ReleaseItem;

并像这样使用物品

if (usableItem != null)
    usableItem.Use(firePoint.position);

问题是,看起来我在使用 Use() 时调用的脚本是另一个版本。

我的意思是,如果我在脚本 WeaponLaser 的顶部设置 int fireCurrentShoot = 10; 然后在 Start 中输入代码,例如我会这样做 fireCurrentShoot = 2;

它将在脚本 WeaponLaser 内部工作,但是当我使用上面的代码调用它时

    if (usableItem != null)
    usableItem.Use(firePoint.position);

它会显示fireCurrentShoot = 10所以没有修改

结束编辑

你好,

我有一个不明白的遗产问题,我清理了我所有的班级,但我仍然找不到原因。

我有一个 A 类:

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

 public class Usable : MonoBehaviour
 {
     protected virtual void Start()
     {
     }

     protected virtual void Update()
     {
     }

     public virtual void Use(Vector3 pos)
     {
     }

     protected virtual void Used()
     {
     }
 }

还有一个B类

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

 public class WeaponLaser : Usable
 {
     const int SHOOT_AVAILABLE = 5;
     const float FIRE_COOLDOWN = 1;
     float fireCurrentCooldown = 0.0f;
     int fireCurrentShoot = 0;

     protected override void Start()
     {
        base.Start();
        Debug.Log("start");
        fireCurrentShoot = SHOOT_AVAILABLE;
        Debug.Log("fireCurrentShoot" + fireCurrentShoot);
     }

     protected override void Update()
     {
         Debug.Log(fireCurrentShoot); // value is = 5
         base.Update();
     }

     public override void Use(Vector3 shootPosition)
     {
         Debug.Log(fireCurrentShoot);// value is = 0
         base.Use(shootPosition);
         base.Used();
     }

     void FireCooldown()
     {

     }
 }

当我调用 Use 时,我的 Debug.Log 展位值为 0...但我希望有 fireCurrentShoot = 5

我这样称呼它 *:

    usableItem = droppedItem.GetComponent<Usable>();
usableItem.Use(firePoint.position);

为什么他等于0?

【问题讨论】:

  • 我怀疑问题出在继承上。似乎您在某个时候覆盖了该值,或者您只剩下初始值。你什么时候使用Start?我不明白你为什么期望有5 的值。初始值是0 为什么应该是5
  • 您没有调用Start - 所以fireCurrentShoot 的值不会更新为5。
  • 在Unity中,Start是引擎默认调用的,所以调用了,debug确实显示值@MongZhu
  • 我的猜测是某些东西正在创建另一个实例。添加一个显式的无参数构造函数并在其中放置一些日志记录。
  • 在设置值之前调用它时,启动方法中的 debug.log 怎么可能给出 5?你在你的例子中混合了两条线吗?

标签: c# unity3d


【解决方案1】:

您的继承似乎很好,所以问题可能在于您在 Unity 中使用这些对象的方式。这使得确定解决方案变得更加困难,但您可以尝试以下方法:

  • 确保调用了 Start:我认为你的情况就是这样,因为 你说你看到一个调试打印,但记住 Start 没有被调用 在编辑器中停用的对象上,因此某些值 你在start中设置的不会被初始化。

  • 在统一编辑器中使用唯一名称命名您的对象并在调试中添加名称

    Debug.Log(fireCurrentShoot + ", " + name);
    

    这应该可以帮助您确保看到您感兴趣的对象的值

  • 你也可以替换

    int fireCurrentShoot = 0;
    

    按属性:

    int _fireCurrentShoot = 0;
    private int fireCurrentShoot
    {
        get{ return _fireCurrentShoot;}
        set{ _fireCurrentShoot = value; Debug.log("fireCurrentShot set to " + _fireCurrentShoot);}
    }
    

    这将允许您在修改值时看到一条消息。你 也可以在setter上设置一个调试点来查看调用栈

编辑:

我想我明白了:你没有注册到实例化对象,而是注册到你的预制件

替换

usableItem = droppedItem.GetComponent<Usable>();

通过

usableItem = Item.GetComponent<Usable>();

【讨论】:

  • 你好,我没想过关于财产的事情,事实上它帮助了我。我认为我的失败在于我对统一对象所做的事情。我将用我发现的内容编辑我的主要问题
  • 我看到了你的编辑,但你确定你写的是什么吗?你说在 Start 你设置 fireCurrentShoot = 2 之后你看到值是 2...所以这似乎是想要的行为
  • 是的,再次抱歉......我很糟糕,我得到了帮助,因为我不清楚并且在我寻求帮助时犯了错误——基本上是的,基本脚本的价值是我从中得到的在代码之外(所以当我调用 Use 时),我在脚本中修改的值是我从内部得到的值。我希望他们是一样的。但我确实理解理解或找到这样的解决方案相当混乱,所以我想我会找到其他方法来做
  • 别抱歉,您提供的信息仍然比这里的许多人都多。话虽如此,我用我注意到的最后一件事编辑了我的答案,这可能会解决它。祝你好运
  • OMGOMG 一直以来,我正要重做所有事情,因为我知道这是一个小错误我永远找不到 xD 漂亮的眼睛,非常感谢你!
猜你喜欢
  • 2023-03-13
  • 2018-01-06
  • 2011-06-18
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 2018-01-30
相关资源
最近更新 更多