粒子在错误的地方产生

The particles spawn on the wrong place

我正在用 Unity 制作一个游戏,您可以在其中砍伐树木,我想让它在您击中树的地方产生粒子。此时粒子会在玩家所在的位置生成,这是因为脚本在玩家身上。但是我怎样才能在正确的地方产生粒子呢? (我撞树的地方)解决起来可能并不难,但我想不通。我当前的 C# 代码如下。

 public class ChopTree : MonoBehaviour
     {
         public int damage = 25;
         public Camera FPSCamera;
         public float hitRange = 2.5f;
         private TreeScript Tree;
     
         // Particles
         public GameObject particles;
     
         void Update()
         {
             Ray ray = FPSCamera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));
             RaycastHit hitInfo;
     
             if(Input.GetKeyDown(KeyCode.Mouse0))
             {
                 if(Physics.Raycast(ray, out hitInfo, hitRange))
                 {
                     // The tag must be set on an object like a tree
                     if(hitInfo.collider.tag == "Tree" && isEquipped == true)
                     {
                         Tree = hitInfo.collider.GetComponentInParent<TreeScript>();
                         StartCoroutine(DamageTree());
                         StartCoroutine(ParticleShow());
                     }
                 }
             }
         }
     
         private IEnumerator DamageTree()
         {
             // After 0.3 seconds the tree will lose HP
             yield return new WaitForSeconds(0.3f);

             Tree.health -= damage;
         }
     
         private IEnumerator ParticleShow()
         {
             // After 0.3 second the particles show up
             yield return new WaitForSeconds(0.3f);

             Instantiate(particles, transform.position, transform.rotation);
         }
     }

如果您通过点击屏幕来砍树,那么您可以在“命中”对象所在的位置生成它,但是,如果您尝试实例化粒子来代替命中对象,那么它将是树的起源,因此,您可以将树的碰撞器添加到树的表面并使其成为不同的对象(您也可以将其设为子对象)。所以这种方式不是很顺利,但是你可以通过这种方式在树的表面创建粒子。

此外,如果你正在用角色切碎它,那么你可以将启用 onTrigger 的碰撞器添加到树中,当你触发时,你会在触发对象所在的位置产生一个粒子。

嗯而不是

Instantiate(particles, transform.position, transform.rotation);

确保你使用像

这样的命中树位置
Instantiate(particles, Tree.transform.position, transform.rotation);

实际上我个人会将两个协程合并在一起并传入相应的树:

private IEnumerator ChopTree(TreeScript tree)
{
    // After 0.3 seconds the tree will lose HP
    yield return new WaitForSeconds(0.3f);

    Instantiate(particles, tree.transform.position, transform.rotation);
    tree.health -= damage;
}

然后

void Update()
{
    var ray = FPSCamera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));
 
     if(Input.GetKeyDown(KeyCode.Mouse0))
     {
         if(Physics.Raycast(ray, out var hitInfo, hitRange))
         {
             // The tag must be set on an object like a tree
             if(hitInfo.collider.CompareTag("Tree") && isEquipped)
             {
                 var tree = hitInfo.collider.GetComponentInParent<TreeScript>();
                 if(tree) 
                 {
                     StartCoroutine(ChopTree(tree));
                 }
             }
         }
     }
}