You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何正确生成继承MonoBehaviour的子弹投射物游戏对象?

问题解答

第二次实现是否正确

你的第二次实现仍然不正确。核心原因是:所有继承自MonoBehaviour的类都不允许直接使用new关键字实例化,Unity的组件必须挂载在GameObject对象上,才能正常触发Awake/Start/Update等生命周期函数,手动new出来的MonoBehaviour实例没有对应的GameObject载体,既无法挂载到场景,也无法正常运行逻辑。

正确实现方案

步骤1:制作子弹预制体

首先在Unity场景中创建一个空GameObject,按需求完成以下配置:

  • 挂载Bullet脚本
  • 挂载Rigidbody组件,调整重力、质量等物理参数
  • 添加子弹模型、碰撞体等必要资源
  • 将配置完成的GameObject拖入Project面板,制作成子弹预制体,删除场景中的临时对象

步骤2:修改Gun类引用预制体

在Gun类中添加公共字段引用子弹预制体:

public class Gun : MonoBehaviour
{
    // 新增字段,用于在Inspector面板赋值子弹预制体
    public Bullet bulletPrefab;
    // 其余原有代码保持不变
}

回到Unity编辑器,将步骤1制作的子弹预制体拖入Gun组件的bulletPrefab字段完成赋值。

步骤3:修改子弹生成逻辑

将performShoot方法中的子弹生成逻辑替换为以下代码:

public void performShoot()
{
    if (canShoot())
    {
        shotCoolDown = FRAMES_BETWEEN_SHOTS;
        // 实例化子弹预制体,生成位置/旋转和枪口保持一致
        Bullet bullet = Instantiate(bulletPrefab, transform.position, transform.rotation)
            .setLoft(LOFT)
            .setWobble(WOBBLE)
            .setInitialVel(INITIAL_VEL)
            .setDirectionOffset(internalRecoil.getRecoil());
    }
}

可选优化(解决时序问题)

如果出现参数未赋值就执行子弹初始逻辑的问题,是因为默认状态下预制体实例化后会立刻执行Start方法,可能早于参数赋值的时机。可以做如下调整:

  1. 删除Bullet类中的Start方法,新增公开初始化方法:
public class Bullet : MonoBehaviour
{
    // 原有代码保持不变
    public void Init()
    {
        transform.Rotate(initialDirectionOffset); 
        rigidbody.AddForce(initialVel*transform.forward);
        rigidbody.AddForce(loft*transform.up);
    }
}
  1. 完成子弹参数赋值后手动调用初始化方法:
Bullet bullet = Instantiate(bulletPrefab, transform.position, transform.rotation)
    .setLoft(LOFT)
    .setWobble(WOBBLE)
    .setInitialVel(INITIAL_VEL)
    .setDirectionOffset(internalRecoil.getRecoil());
bullet.Init();

内容的提问来源于stack exchange,提问作者Jake Gergen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:54:04