【问题标题】:How to shoot particle like projectile?如何射出像弹丸一样的粒子?
【发布时间】:2018-08-31 01:22:38
【问题描述】:

我做了一个坦克,点击鼠标就可以发射球。

我的 C# 脚本:

 GameObject prefab;

 // Use this for initialization
 void Start () {
     prefab = Resources.Load("projectile") as GameObject;
 }

 // Update is called once per frame
 void Update() {
     if (Input.GetMouseButtonDown(0))
     {
         GameObject projectile = Instantiate(prefab) as GameObject;
         projectile.transform.position = transform.position + Camera.main.transform.forward * 2;
         Rigidbody rb = projectile.GetComponent<Rigidbody>();
         rb.velocity = Camera.main.transform.forward * 40;
     }   

 }

在这个脚本中,我正在拍摄一个名为 projectile 的网格。但我想拍摄粒子球而不是网格。我已经尝试将脚本上的particle 更改为Orbparticle,但没有生成任何对象。我做错了什么?

【问题讨论】:

    标签: unity3d particles


    【解决方案1】:

    没有生成对象,因为您可能没有名为 Orbparticle 的资源。检查运行脚本时是否有任何错误。如果Resources.Load 没有通过你给它的路径找到你想要的对象,它会给出null,这可能是没有生成对象的原因。

    如果您想拍摄粒子而不是网格,那么您需要将prefab 设置为您提前准备好的具有所需粒子系统的游戏对象。我建议不要为此使用 Resources.Load。

    1。使用 Resources.Load。

    将您的代码更改为此,以便在找不到资源时提醒您:

    GameObject prefab;
    
    // Use this for initialization
    void Start () {
        string name = "OrbParticle";
        prefab = Resources.Load<GameObject>(name);
        if (prefab == null) {
            Debug.Error("Resource with name " + name + " could not be found!");
        }
    }
    
    // Update is called once per frame
    void Update() {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject projectile = Instantiate(prefab) as GameObject;
            projectile.transform.position = transform.position + Camera.main.transform.forward * 2;
            Rigidbody rb = projectile.GetComponent<Rigidbody>();
            rb.velocity = Camera.main.transform.forward * 40;
        }   
    }
    

    现在,为了使其工作,您需要一个名为“OrbParticle”的预制件或您将变量 name 设置为的任何字符串。 Resources.Load 在诸如Assets/Resources 之类的路径中查找项目。因此,您必须将“OrbParticle”预制件放在该资源文件夹中。除非您有使用 Resources.Load 的特定原因,否则我强烈建议您使用解决方案 2。

    2。放弃 Resources.Load 并直接使用 Prefab。

    将您的代码更改为:

    public GameObject prefab;
    
    // Update is called once per frame
    void Update() {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject projectile = Instantiate(prefab) as GameObject;
            projectile.transform.position = transform.position + Camera.main.transform.forward * 2;
            Rigidbody rb = projectile.GetComponent<Rigidbody>();
             rb.velocity = Camera.main.transform.forward * 40;
        }   
    }
    

    然后这样做:

    1. 创建一个新的空游戏对象。
    2. 将粒子系统附加到游戏对象。
    3. 制作新的预制资产。
    4. 将新创建的游戏对象拖放到预制资产中。
    5. 将预制件拖放到 Monobehaviour 中的 prefab 字段中(进行拍摄的对象。它将在 Inspector 中具有预制字段。这就是我们将 prefab 设置为公共字段的原因)。李>

    如果您仍然遇到问题,请查看 Unity 的层次结构,看看是否根本没有创建任何对象。可能是它正在实例化一个游戏对象,但游戏对象由于某种原因是不可见的,或者没有在您期望的位置实例化。

    【讨论】:

    • 不要吹毛求疵,但是你的方法2也容易出错,因为弹丸可能没有刚体,你可以在rb.velocity =...之前添加一个空检查以防止可能的空错误,或者你如果您将 prefab 设为 Rigidbody 而不是 GameObject,并使用 Instantiate(prefab.gameObject) 实例化它仍然是一个非常可靠的答案,则可以完全消除此要求。
    • @Eddge 这是一个很好的做法,但我没有添加该检查,因为我认为它与问题无关。我考虑了抛射物是否可以仅仅因为它没有刚体并且由于无法设置其速度而被卡在相机的原点而变得不可见。但后来我注意到他们专门将生成点设置在相机的前向矢量前面 2 个单位,因此该对象很可能会被明显卡住。我想拥有高质量的代码总是相关的。总的来说,我们需要来自 SHRIMP 的 Unity 控制台日志。
    • 确实,但我只是指出 RB 是另一种可能是 null 错误,因为它可能由于 null 错误而中止了该函数,我有一个 spawn 方法这样做一次。正如您所说,拥有控制台日志将非常有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多