unity3d 在Unity中,玩家的移动速度不会被加到第一发子弹上

7nbnzgx9  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(187)

我想在统一2D自上而下的射手。我希望它,所以当你按住鼠标左键的球员火一系列的子弹,直到你用完弹药。球员的移动速度减慢,而射击和球员的移动速度应该增加到子弹的移动速度。由于某种原因,球员的移动速度只适用于子弹后,第一颗子弹被解雇。第一颗子弹似乎总是保持稍微快一点的“冲刺”移动速度。
武器脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Weapon : MonoBehaviour
{
    private GameObject bulletPrefab;
    private Transform firePoint;
    private PlayerControls player;
    public float fireForce = 10f;
    private bool cooldown = false;
    private int bullets;
    public int bulletDamage;
    public int maxAmmo;
    public float fireRate = 0.5f;
    public float reloadRate = 2.5f;
    public bool noAmmo = false;
    public float walkSpeed = 2f;
    private float timeSinceLastShot = 0f;

    void Update()
    {
        // increase time since last shot
        timeSinceLastShot += Time.deltaTime;
        // if left-click is held down
        if (Input.GetMouseButton(0))
        {
            // if enough time has passed since last shot
            if (timeSinceLastShot >= fireRate && noAmmo == false)
            {
                player.moveSpeed = walkSpeed;
                bullets -= 1;
                cooldown = true;
                if (bullets <= 0)
                {
                    noAmmo = true;
                    player.moveSpeed = player.baseSpeed;
                }
                // instantiate a bullet
                GameObject bullet = Instantiate(bulletPrefab, firePoint.transform.position, Quaternion.identity);
                bullet.GetComponent<Bullet>().bulletDamage = bulletDamage;
                // add player movement speed to bullet's speed
                bullet.GetComponent<Rigidbody2D>().velocity = player.GetComponent<Rigidbody2D>().velocity;
                bullet.GetComponent<Rigidbody2D>().AddForce(transform.up * fireForce, ForceMode2D.Impulse);

                // reset time since last shot
                timeSinceLastShot = 0f;
            }
        }
        // if left-click is not held down
        else
        {
            cooldown = false;
            // restore player movement speed
            player.moveSpeed = player.baseSpeed;
        }
    }

    public void FillMag()
    {
        bullets = maxAmmo;
        noAmmo = false;
    }
}

播放器控件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControls : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float baseSpeed = 5f;
    public int health;
    public Weapon weapon;
    private Rigidbody2D rb;
    Vector2 mousePosition;
    Vector2 moveDirection;
    public float walkSpeed = 2f;

    void Update()
    {

        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        moveDirection = new Vector2(moveX, moveY).normalized;
        mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        rb.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
        Vector2 aimDirection = mousePosition - rb.position;
        float aimAngle = Mathf.Atan2(aimDirection.y, aimDirection.x) * Mathf.Rad2Deg - 90f;
        rb.rotation = aimAngle;
    }
}

玩家正在从左向右移动。Player firing
根据Unity的生命周期,输入只在Update方法被调用之前被计算,但是物理在FixedUpdate方法期间被应用。这是导致我的问题的原因吗?我试着将一些计算移到FixedUpdate和LateUpdate中,但是似乎没有任何区别。
任何帮助都是感激的。我已经用头撞了好几天了。我是个成熟的人,所以请随意解释,就像我5岁一样。

66bbxpm5

66bbxpm51#

因此,您的代码存在两个问题:
1.如果您没有按住鼠标左键,而是多次单击:

  • Update()中的else语句会立即将播放器设置回基本速度,如果你打算按住鼠标,这并不重要。

1.有两件事同时发生

  • 首先,在武器更新()中设置玩家移动速度
  • 同时,你在玩家更新()中计算玩家速度,但是在你把速度正确地放到你的武器上之前,玩家更新速度需要时间。

因此,我建议您使用IEnumerator来延迟fire操作。

public class Weapon : MonoBehaviour
{
    void FixedUpdate()
    {
        // increase time since last shot
        timeSinceLastShot += Time.deltaTime;
        // if left-click is held down
        if (Input.GetMouseButton(0))
        {
            // if enough time has passed since last shot
            if (timeSinceLastShot >= fireRate && noAmmo == false)
            {
                //player.moveSpeed = walkSpeed;
                StopAllCoroutines();
                StartCoroutine(SetSpeed());
                bullets -= 1;
                cooldown = true;
                if (bullets <= 0)
                {
                    noAmmo = true;
                    player.moveSpeed = player.baseSpeed;
                }
                // instantiate a bullet

                StartCoroutine(FireBulelt());
                // reset time since last shot
                timeSinceLastShot = 0f;
            }
        }
        // if left-click is not held down
    }

    IEnumerator SetSpeed()
    {
        player.moveSpeed = walkSpeed;
        yield return new WaitForSeconds(0.5f);
        cooldown = false;
        // restore player movement speed
        player.moveSpeed = player.baseSpeed;
        yield return null;
    }

    IEnumerator FireBulelt()
    {
        yield return new WaitForSeconds(0.05f);

        GameObject bullet = Instantiate(bulletPrefab, player.transform.position, Quaternion.identity);
        print("  player.GetComponent<Rigidbody2D>().velocit " + player.GetComponent<Rigidbody2D>().velocity);

        // add player movement speed to bullet's speed
        Rigidbody2D bulletRB = bullet.GetComponent<Rigidbody2D>();
        print(" bulletRB.velocit " + bulletRB.velocity);
        bulletRB.velocity = player.GetComponent<Rigidbody2D>().velocity;
        print(" after bulletRB.velocit " + bulletRB.velocity);

        bulletRB.AddForce(transform.up * fireForce, ForceMode2D.Impulse);
    }
}

您应该像我一样添加print(),以便在调试时跟踪代码行为。

相关问题