FindObjectOfType 返回 null

2024-05-03

我遇到的问题是我捡起一个掉落的物品,为枪添加弹药。

使用所有方法和变量构建了一个 Gun 类。 构建了一个从 Gun 类派生的 Rifle 类 步枪工作完美,没有任何问题

我现在添加一个“拾取”系统,其中 x 数量的敌人会掉落拾取。

这是要拾取的物品的脚本

public class AddARAmmo : MonoBehaviour
{
    private Rifle rifle;
    private void Awake()
    {
        rifle = FindObjectOfType<Rifle>();
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == string.Format("Player"))
        {
           rifle.AddAmmo(30);
            Destroy(gameObject);
        }

    }
}

步枪和枪的脚本有点长,但这里是来自 Gun 基类的相关内容是公共抽象类......

public int bulletsInStock;
 public void AddAmmo(int ammoToAdd)
{
    bulletsInStock += ammoToAdd; 
    UpdateAmmo();// updates on screen Ammo
}
......

然后在步枪班

 public override void Modifiers() // This is where the guns starts are stored
{
    bulletSpeed = 2777f;
    bulletsInStock = 200;
    bulletsInMag = 30;
    bulletPoolSize = 40;
    desiredRPS = 15;
    muzzleFlashPoolSize = 10;
}

我收到一个未设置为实例的对象引用

步枪脚本位于游戏层次结构中的步枪上,因此应该可以找到它。 有人看出有什么问题吗?

这是完整的 Gun 脚本

public abstract class Gun : MonoBehaviour
{
    [SerializeField] protected GameObject muzzleFlash;// spawns on barrelEnd
    [SerializeField] protected Transform muzzleFlashFolder;
    [SerializeField] protected Transform bulletFolder;// is the parent of bullets
    [SerializeField] protected Transform barrelEnd;// Gameobject at the end of barrel
    [SerializeField] protected Rigidbody bullet; // The bullet Prefab
    [SerializeField] protected Text ammo; // OSD
    [SerializeField] protected Text weaponType; // OSD
    [HideInInspector] protected float bulletSpeed;
    [HideInInspector] public int bulletsInStock;
    [HideInInspector] protected int bulletsInMag;
    [HideInInspector] protected float desiredRPS;// Rounds Per Second
    [HideInInspector] protected List<Rigidbody> poolOfBullets; // Make pool for bullets
    [HideInInspector] protected int bulletPoolSize; // The size off the buletpool 10 works really well
    [HideInInspector] protected List<GameObject> muzzleFlashPool;// pool for muzzleflash
    [HideInInspector] protected int muzzleFlashPoolSize; // size of the muzzle pool
    [HideInInspector] protected int bulletsLeft; // In mag
    [HideInInspector] protected bool isReloading = false;
    [HideInInspector] protected float timeLeft;// for fire speed
    [HideInInspector] protected float fireSpeedTimer;
    [HideInInspector] protected Weapons weaponsScript;
    [HideInInspector] protected PlayerController playerController;
    protected void FixedUpdateStuff()
    {
        if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) > 0)
        {
            FireSpeedControl();// call the fire timer controller
        }
        if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) == 0)
        {
            timeLeft = 0f;
        }
        if (playerController.canMove && Input.GetKeyDown(KeyCode.R) && !isReloading)
        {
            Reload();
        }
        UpdateAmmoOnInput();
    }
    protected void UpdateStuff()
    {
        if (gameObject.activeInHierarchy)// when a gun become active it updates OSD
        {
            UpdateWeaponType();// With its Name
        }
    }
    protected void RPSFinder()//  finds the Rounds Per Second the gun will fire
    {
        fireSpeedTimer = (100 / desiredRPS) / 100;
        timeLeft = fireSpeedTimer;
    }

    protected void Fire()// Instatiates a clone of the desired bullet and fires it at bulletSpeed
    {
        if (!Empty())
        {
            Rigidbody bulletClones = GetPooledBullet();
            if (bulletClones != null)
            {

bulletClones.transform.SetPositionAndRotation(barrelEnd.position, barrelEnd.rotation);
                bulletClones.gameObject.SetActive(true);
            }
            GameObject muzzleFlashClone = GetMuzzleFlash();
            if (muzzleFlashClone != null)
            {
                muzzleFlashClone.transform.position = barrelEnd.position;
                muzzleFlashClone.gameObject.SetActive(true);
            }
            bulletClones.AddForce(-bulletClones.transform.up * bulletSpeed * .304f); //add the force in FPS * .304 = MPS
            bulletsLeft--;// the holder to know how many bullets are left in the magazine
            isReloading = false;// Gun cannot reload unless it has been fired
            UpdateAmmo();// Updates the on screen ammo count and the stock usage
            return;
        }
    }

    protected void Reload()
    {// this removes full magazine from the stock and the stock can still go negitive FIX FIX FIX FIX FIX FIX FIX
        if (bulletsInStock > 0)
        {
            isReloading = true;
            bulletsInStock -= bulletsInMag;
            bulletsLeft = bulletsInMag;
            UpdateAmmo();
        }
    }

    protected bool Empty()// Checks the magazine to see if there are bullets in it
    {
        if (bulletsLeft == 0)
            return true;
        else
            return false;
}

    protected void FireSpeedControl()// controls the RPS fired by the gun Controled by Update() Input
    {
        if (timeLeft > 0f)
        {
            timeLeft -= Time.deltaTime;
        }
        else if (timeLeft <= 0f)
        {
            Fire();
            timeLeft = fireSpeedTimer;
        }
    }

    protected Rigidbody GetPooledBullet()// retrieve a preInstatiated bullet from the pool to use when shooting
    {
        for (int i = 0; i < poolOfBullets.Count; i++)
        {
            if (!poolOfBullets[i].gameObject.activeInHierarchy)
            {
                return poolOfBullets[i];
            }
        }
        return null;
    }

    protected GameObject GetMuzzleFlash()
    {
        for (int i = 0; i < muzzleFlashPool.Count; i++)
        {
            if (!muzzleFlashPool[i].gameObject.activeInHierarchy)
            {
                return muzzleFlashPool[i];
            }
        }
        return null;
    }

    protected void UpdateAmmo()// Update the on screen ammo information
    {
        ammo.text = bulletsLeft + string.Format( " : ") + bulletsInStock;
    }

    protected abstract void UpdateWeaponType();

    protected void UpdateAmmoOnInput()
    {
        if (weaponsScript.updateAmmo)
        {
            UpdateAmmo();
            weaponsScript.updateAmmo = false;
        }
    }


    public abstract void Modifiers();

    protected void StartStuff()
    {
        Modifiers();// Call first to store indvidual gun stats
        playerController = FindObjectOfType<PlayerController>();
        weaponsScript = FindObjectOfType<Weapons>();
        poolOfBullets = new List<Rigidbody>();
        for (int i = 0; i < bulletPoolSize; i++)
        {
            Rigidbody bulletClone = (Rigidbody)Instantiate(bullet);
            bulletClone.gameObject.SetActive(false);// Builds the Inspector list 
            poolOfBullets.Add(bulletClone); //and populates the elements with clones
            bulletClone.transform.parent = bulletFolder.transform;
        }
        muzzleFlashPool = new List<GameObject>();
        for (int i = 0; i < muzzleFlashPoolSize; i++)
        {
            GameObject muzzleFlashClone = (GameObject)Instantiate(muzzleFlash);
            muzzleFlashClone.gameObject.SetActive(false);
            muzzleFlashPool.Add(muzzleFlashClone);
            muzzleFlashClone.transform.parent = muzzleFlashFolder.transform;
        }
            bulletsLeft = bulletsInMag;
            ammo.text = string.Format( " 0 : 0 ");
            RPSFinder();// Run last to set the RPS of the gun
        }
        public void AddAmmo(int ammoToAdd)
        {
            bulletsInStock += ammoToAdd;
            UpdateAmmo();
        }

    }
}

这是完整的步枪脚本

public class Rifle : Gun
{
    //All variables are stored in the "Gun" Script 
    //Copy this onto guns 

    void Start()
    {
        StartStuff();
    }
    private void FixedUpdate()
    {
        FixedUpdateStuff();
    }

    void Update()
    {
        UpdateStuff();
    }

    public override void Modifiers() // This is where the guns starts are stored
    {
        bulletSpeed = 2777f;
        bulletsInStock = 200;
        bulletsInMag = 30;
        bulletPoolSize = 40;
        desiredRPS = 15;
        muzzleFlashPoolSize = 10;
    }

    protected override void UpdateWeaponType()
    {
        weaponType.text = string.Format("Assault Rifle");
    }


}

FindObjectOfType 可能返回 null 的原因有以下三个:

假设要查找的脚本名称是Rifle:

And FindObjectOfType<Rifle>()正在返回null.

1.The GameObject the Rifle script is attached to is in-active. You must make sure that the GameObject is active. enter image description here

2.The Rifle is not attached to any GameObject at-all. Make sure that the Rifle script is attached to a GameObject.enter image description here.

无论脚本是启用还是禁用,只要它附加的游戏对象处于活动状态,它就应该找到它。看#1.

3.加载新场景时:

当您使用以下功能触发场景加载时SceneManager.LoadScene and Application.LoadLevel, FindObjectOfType在场景加载完成之前将无法找到任何内容。

See here https://stackoverflow.com/q/39801130/3785314了解如何检查场景何时完成加载。


如果您仍然遇到不应该出现的问题,只需找到 GameObject 然后获取Rifle来自它的组件。假设游戏对象的名称是"Rifle" too.

GameObject.Find("Rifle").GetComponent<Rifle>();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FindObjectOfType 返回 null 的相关文章

  • 将运算符 << 添加到 std::vector

    我想添加operator lt lt to std vector
  • 为什么这个 Web api 控制器不并发?

    我有一个 Web API 控制器 里面有以下方法 public string Tester Thread Sleep 2000 return OK 当我调用它 10 次 使用 Fiddler 时 我预计所有 10 次调用都会在大约 2 秒后
  • 如何在 VC++ CString 中验证有效的整数和浮点数

    有人可以告诉我一种有效的方法来验证 CString 对象中存在的数字是有效整数还是浮点数吗 Use tcstol http msdn microsoft com en us library w4z2wdyc aspx and tcstod
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 循环遍历 C 结构中的元素以提取单个元素的值和数据类型

    我有一个要求 我有一个 C 语言的大结构 由大约 30 多个不同数据类型的不同元素组成 typedef struct type1 element1 type2 element2 type3 element3 type2 element4 1
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • 语音识别编程问题入门

    所以 你们可能都看过 钢铁侠 其中托尼与一个名为贾维斯的人工智能系统进行交互 演示剪辑here http www youtube com watch v Go8zsh1Ev6Y 抱歉 这是广告 我非常熟悉 C C 和 Visual Basi
  • 如何使用 ASP.NET Core 获取其他用户的声明

    我仍在学习 ASP NET Core 的身份 我正在进行基于声明的令牌授权 大多数示例都是关于 当前 登录用户的 就我而言 我的 RPC 服务正在接收身份数据库中某个用户的用户名和密码 我需要 验证是否存在具有此类凭据的用户 获取该用户的所
  • 如何使用 x64 运行 cl?

    我遇到了和这里同样的问题致命错误 C1034 windows h 未设置包含路径 https stackoverflow com questions 931652 fatal error c1034 windows h no include
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 在 C# 中为父窗体中的子窗体控件添加事件处理程序

    我有两种形式 一种是带有按钮和文本框的父表单 单击该按钮时 将打开一个对话框 该子窗体又包含一个文本框和一个按钮 现在我想要的是 每当子表单文本框中的文本更改时 父表单文本框中的文本会自动更改 为了获得这个 我所做的是 Form3 f3 n
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 将二变量 std::function 转换为单变量 std::function

    我有一个函数 它获取两个值 x 和 y 并返回结果 std function lt double double double gt mult double x double y return x y 现在我想得到一个常量 y 的单变量函数
  • 将 Word 转换为 PDF - 禁用“保存”对话框

    我有一个用 C 编写的 Word 到 PDF 转换器 除了一件事之外 它工作得很好 有时 在某些 Word 文件上 后台会出现一条消息保存源文件中的更改 gt 是 否 取消 但我没有对源文件进行任何更改 我只想从 Word 文件创建 PDF
  • 如何最好地以编程方式将 `__attribute__ ((unused))` 应用于这些自动生成的对象?

    In my makefile我有以下目标 它将文本 HTML 资源 编译 为unsigned char数组使用xxd i http linuxcommand org man pages xxd1 html 我将结果包装在匿名命名空间和标头保
  • 模板类中的无效数据类型生成编译时错误?

    我正在使用 C 创建一个字符串类 我希望该类仅接受数据类型 char 和 wchar t 并且我希望编译器在编译时使用 error 捕获任何无效数据类型 我不喜欢使用assert 我怎样才能做到这一点 您可以使用静态断言 促进提供一个 ht
  • 如何解压 msgpack 文件?

    我正在将 msgpack 编码的数据写入文件 在编写时 我只是使用 C API 的 fbuffer 如 我为示例删除了所有错误处理 FILE fp fopen filename ab msgpack packer pk msgpack pa
  • 为什么空循环使用如此多的处理器时间?

    如果我的代码中有一个空的 while 循环 例如 while true 它将把处理器的使用率提高到大约 25 但是 如果我执行以下操作 while true Sleep 1 它只会使用大约1 那么这是为什么呢 更新 感谢所有精彩的回复 但我

随机推荐

  • 您无权执行该操作

    我有一个时间触发的脚本 可以定期从外部源检索内容并用它更新 Google 网站页面 根据this https developers google com apps script guides triggers installable res
  • 应用程序在后台时远程推送通知 swift 3

    我有一个可以接收远程推送通知的应用程序 我已经实施了didReceiveRemoteNotification这样 func application application UIApplication didReceiveRemoteNoti
  • 包括 Oracle 中的等效项

    在 SQL Server 中你可以这样写 create index indx on T1 A B INCLUDE C D E 有没有办法在 Oracle 中做同样的事情 Refs http msdn microsoft com en us
  • 建议一种每分钟更新时间的方法

    我有一个完整的ajax应用程序 我正在使用下面的代码每分钟更新一次时间 但如果我保持浏览器打开超过 10 分钟 浏览器就会变得无响应 缓慢 建议更好的代码 function tick var d new Date var time padN
  • 如果数据表的主键是两列,您可以使用 DataTable.Contains(object key) 吗?

    如果是这样怎么办 要按主键选择 您应该使用以下之一 DataTable Rows Find Object 如果你的 PK 是一列 DataTable Rows Find Object 如果您有超过 1 列作为主键 对于类型化 DataSet
  • 键值观察和 NSButton 状态

    我试图观察复选框状态 并在复选框状态更改时在应用程序中进行适当的更改 在使用复选框管理窗口的窗口管理器中 我有以下观察者设置 void awakeFromNib myCheckBox addObserver self forKeyPath
  • 如何重定向 Groovy 脚本的输出?

    我想知道是否有任何方法可以更改我从 Java 代码执行的 groovy 脚本的默认输出 System out 这是Java代码 public void exec File file OutputStream output throws Ex
  • 从 Firestore 数组中按键/值删除项目

    我在 Firestore 中有一个数组 其结构如下 palettes 0 date 2019 05 01 name First Palette palette array 1 date 2019 05 02 name Palette 2 p
  • Django Migrate int() 的无效文字

    Django 1 7 Python 2 7 我已经制作了 sqlite 数据库 并在管理页面中向数据库添加了一些记录 然后我改变了我的模型 添加了一个外键 然后我 manage makemigrationsdjango询问了之前记录中的默认
  • 无法从超时获得自动化扩展:从渲染器接收消息超时

    使用 Selenium Webdriver C 我时不时会收到下一个错误 System InvalidOperationException 未知错误 无法从超时获取自动化扩展 从渲染器接收消息超时 3 959 会话信息 chrome 37
  • 点分隔的字符串资源名称有什么用?

    我使用 Snake style 来命名字符串资源 在某人的代码中 我发现了另一种带有点的符号 我无法找到关于这个主题的任何单词
  • 如何在 Windows 7 中配置 cabal?

    我已经在Windows 7中安装了Haskell Platform 2012 我在控制台中编写cabal update我收到消息说有新版本的阴谋集团 我写的cabal install cabal install 安装完成后 它告诉我 cab
  • 如何删除 TextBlock 周围的多余空间

    我为我的 TextBlock 设置了以下内容
  • 将嘈杂的硬币重塑为圆形

    我正在使用 JavaCV OpenCV 包装器 进行硬币检测 但是当硬币连接时我遇到了一些问题 如果我尝试侵蚀它们以分离这些硬币 它们就会失去圆形形状 如果我尝试计算每个硬币内部的像素 可能会出现问题 因此某些硬币可能会被误算为更大的硬币
  • SQL Server 2008 FileStream 与普通文件

    我正在创建一个像 youtube 这样的应用程序来存储视频 我需要一些建议 我应该使用 SQL Server FileStream 来存储视频文件 还是应该将它们存储在硬盘上的某个位置并将路径记录为 SQL Server 内的 varcha
  • 将第一行粘贴到列表中的列名称

    我有 68 个数据文件 全部具有相同的标识符 但具有不同的指示符 我将这些单独的文件转换为一个列表 其中每个数据框作为一个单独的元素 每个数据框的第一行是年份 我想将其粘贴到列名称中 我希望能够用 分隔它 例如 现在列名称为 Arbeits
  • 在 WPF 中向上/向下移动 ListBoxItem

    我创建了一个包含文件名的列表框 我想为用户提供一个选项 可以使用上 下按钮并使用拖放来上下移动文件名 任何人都知道如何实现此功能 XAML 代码
  • 如何续订过期的 ClickOnce 证书?

    我需要对一年多没有碰过的 ClickOnce 应用程序进行一些更改 因此证书已过期 我读过 使用新证书发布将使应用程序失败 因为它将使用不同的密钥进行签名 因此我认为我需要使用相同的证书但不知道如何更新它 如果您正在寻求快速解决方案 那么您
  • 如何将数字 010 转换为字符串“010”

    在控制台中执行一些随机表达式时 我发现 010 返回8 甚至 011 0100 都通过考虑八进制数字系统返回结果 如果我想转换一个数字 我该怎么做010到一个字符串 010 不仅为了010但对于每个相似的数字 我设法找到了一种类似的解释he
  • FindObjectOfType 返回 null

    我遇到的问题是我捡起一个掉落的物品 为枪添加弹药 使用所有方法和变量构建了一个 Gun 类 构建了一个从 Gun 类派生的 Rifle 类 步枪工作完美 没有任何问题 我现在添加一个 拾取 系统 其中 x 数量的敌人会掉落拾取 这是要拾取的