【问题标题】:How does one go about making a triple shot effect that rotates in accordance to where the player is aiming?如何制作根据玩家瞄准的位置旋转的三连击效果?
【发布时间】:2023-03-07 14:40:01
【问题描述】:

我正在开发一个自上而下的射击游戏项目。我在创建三连发效果时遇到问题,玩家会射出 3 发子弹。这些子弹会以与玩家瞄准的相同角度相互平行。

上面的例子显示了玩家的两个射击角度,一个向左,一个向上。

目前的问题是我几乎不知道我将如何尝试这样做,因为我的数学很差。我的第一次尝试很糟糕,如下所示。

https://gyazo.com/c5be55ce07f7e81ad1786cd91ecc37ad

我在以前的数学书籍中对此进行了研究,我得出的结论是我需要专注于三角学(特别是 sin 和 cos)。我只是不知道我将如何实现三连击效果的逻辑。

这是第一次尝试的代码:

public class TripleShot : CoreWeaponPart
    {
        public enum FireType { Spread, Row }
        public FireType fireType;
        public override Bullet[] FirePattern(PlayerController owner, Weapon mainWeapon)
        {
            Bullet[] bullets = new Bullet[3 + mainWeapon.fireAmount];
            for (int i = 0; i < bullets.Length; i++)
            {
                Bullet bullet = ObjectPooler.GetPooledObject<Bullet>(true); //Get an available bullet from the pool of bullets.
                bullet.Damage = mainWeapon.damage;
                bullet.Lifespan = mainWeapon.bulletLifespan;
                bullet.Owner = owner;

                switch (fireType)
                {
                    case FireType.Spread: //Create a spread effect for the tripleshot.
                        bullet.transform.position = owner.barrelPos.position;
                        bullet.transform.rotation = (owner.barrelPos.rotation * Quaternion.Euler(0, -29.5f, 0)) * Quaternion.Euler(0, 15f * (i + 1f + mainWeapon.fireSpread), 0);
                        break;

                    case FireType.Row: //Create a parallel effect for the tripleshot (current problem).

                        bullet.transform.position = owner.barrelPos.position - (transform.forward + new Vector3(5 + mainWeapon.fireSpread, 0, 0)) + (new Vector3(5 * (i + 1f + mainWeapon.fireSpread), 0, 0));
                        bullet.transform.rotation = owner.barrelPos.rotation;
                        break;

                }


                bullet.Direction = bullet.transform.forward.normalized * mainWeapon.bulletVelocity;

                bullet.SetActive(true);

                bullets[i] = bullet;
            }

            return bullets;
        }
    }
    

【问题讨论】:

  • 你需要画一个直角三角形,其中 3 个边是 1) 墙 2) 从射手到墙的线 3) 子弹行进的线。您会得到子弹击中墙壁的角度,即 90 - 发射角度子弹。当子弹击中墙壁时,它会以与击中墙壁相同的角度从墙壁反弹。因此,如果子弹以 30 度角击中墙壁,则会以 30 度角以相反方向(180 - 30 = 150)从墙壁反弹。
  • 好主意,但这并不是我真正想要的。我试图弄清楚如何根据玩家的目标以正确的旋转方式平行射击 3 颗子弹。

标签: c# unity3d math


【解决方案1】:

您不需要为此使用三角函数。相反,请使用转换为您完成工作。

首先,添加一个maxParallelSpread 术语,这样您就可以在发射大量子弹时防止子弹从荒谬的距离发射。

然后,您可以定义parallelSpread,子弹到枪管左侧或右侧的距离为Mathf.Min(maxParallelSpread, (bullets.Length-1) * mainWeapon.fireSpread)。然后每个子弹沿着那个距离定位在这个部分:(float)i/(bullets.Length-1)

您可以使用Mathf.Lerp(-parallelSpread, parallelSpread, (float)i/(bullets.Length-1)) 计算子弹从枪管位置沿transform.right 移动的距离。

总共:

public class TripleShot : CoreWeaponPart
{
    public enum FireType { Spread, Row }
    public FireType fireType;
    public maxParallelSpread = 5f;

    public override Bullet[] FirePattern(PlayerController owner, Weapon mainWeapon)
    {
        Bullet[] bullets = new Bullet[3 + mainWeapon.fireAmount];
        float parallelSpread = Mathf.Min(maxParallelWidth, (bullets.Length-1) 
                * mainWeapon.fireSpread);
        for (int i = 0; i < bullets.Length; i++)
        {
            //Get an available bullet from the pool of bullets.
            Bullet bullet = ObjectPooler.GetPooledObject<Bullet>(true); 

            bullet.Damage = mainWeapon.damage;
            bullet.Lifespan = mainWeapon.bulletLifespan;
            bullet.Owner = owner;

            switch (fireType)
            {
                case FireType.Spread: //Create a spread effect for the tripleshot.
                    bullet.transform.position = owner.barrelPos.position;
                    bullet.transform.rotation = ( owner.barrelPos.rotation 
                            * Quaternion.Euler(0, -29.5f, 0)) 
                            * Quaternion.Euler(0, 15f * (i + 1f 
                            + mainWeapon.fireSpread), 0);
                    break;

                case FireType.Row: //Create a parallel effect for the tripleshot
                    float bulletRightness = Mathf.Lerp(-parallelSpread, 
                            parallelSpread, (float)i/(bullets.Length-1));
                    bullet.transform.position = owner.barrelPos.position 
                            + transform.right * bulletRightness;
                    bullet.transform.rotation = owner.barrelPos.rotation;
                    break;

            }


            bullet.Direction = bullet.transform.forward.normalized 
                    * mainWeapon.bulletVelocity;

            bullet.SetActive(true);

            bullets[i] = bullet;
        }

        return bullets;
    }
}

您可以通过乘以一个适合您需要的常数来调整mainWeapon.fireSpread 产生parallelSpread 的扩散程度。例如,如果您需要将其传播两倍,则将其乘以 2f:

        float parallelSpread = Mathf.Min(maxParallelWidth, (bullets.Length-1) 
                * 2f * mainWeapon.fireSpread);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多