首页 > 解决方案 > 移动统一 2d 时玩家口吃

问题描述

每当玩家使用它的喷气背包或有很大的速度时,玩家都会结结巴巴。我尝试使用插值和其他类似的东西,但唯一的结果是更加口吃。如果有人知道口吃的原因是什么,请告诉我,如果你愿意,甚至可以解释你的答案:)

这就是我所说的玩家口吃的意思: https ://www.youtube.com/watch?v=k6q3vvQtwjM

这是我的播放器代码:

using UnityEngine;
using UnityEngine.SceneManagement;

public class Player : MonoBehaviour
{
    //basic variables
    [SerializeField]
    private float speed = 5f;

    [SerializeField]
    private float Jumpforce = 5f;

    [SerializeField]
    private float JetPackForce = 5f;

    [SerializeField]
    public bool canUseJetpack = true;

    [SerializeField]
    private Rigidbody2D rb;

    [SerializeField]
    private Animator animator;
  
    private bool isFacingRight = true;

    //runs when game starts
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    //runs every frame
    void Update()
    {
        //applies force thus making player to move left or right
        var move = Input.GetAxis("Horizontal");
        transform.position = transform.position + new Vector3(move * speed * Time.deltaTime, 0, 0);

        //changes player animation state
        animator.SetFloat("Speed", Mathf.Abs(move));

        //flip the player if facing right or left
        if (move < 0 && isFacingRight)
        {
            flip();
        }
        else if (move > 0 && !isFacingRight)
        {
            flip();
        }

        //checks if the space key is pressed and that the player velocity on the y axis is smaller than 0.001
        if(Input.GetKeyDown("space") && Mathf.Abs(rb.velocity.y) < 0.001f)
        {
            //adds force from below the player thus making the player jump
            rb.AddForce(new Vector2(0, Jumpforce), ForceMode2D.Impulse);
        }

        //checks for the key 'Q' to be pressed and that there is enough fuel in the jetpack
        if (Input.GetKey(KeyCode.Q) && canUseJetpack == true) 
        {
            //ads force from below the player thus making the player fly using its jetpack
            rb.AddForce(Vector2.up * JetPackForce);
            //decreases the fuel in the jetpack
            JetpackBar.instance.UseFuel(0.1f);
            //makes the player run the using jetpack animation
            animator.SetBool("UsingJetpack", true);
        }
        else
        {
            //if the player isn't using the jetpack, switch to the idle animation or the run animation depending if the player is moving or not
            animator.SetBool("UsingJetpack", false);
        }

        //checks if the player health is less than 0
        if (HealthBar.instance.currentHealth <= 0)
        {
            //if so, restart the game
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }
    }

    //checks if someting collided with the player
    private void OnCollisionEnter2D(Collision2D collision)
    {
        //if the thing collided with the player has a tag of 'Enemy'
        if (collision.gameObject.CompareTag("Enemy"))
        {
            //then, make the player take damage
            HealthBar.instance.takeDamage(25);
        }
    }

    //flip the player
    void flip()
    {
        isFacingRight = !isFacingRight;
        transform.Rotate(0f, 180f, 0f);
    }
}

感谢:D

标签: c#unity3d

解决方案


首先,每当处理刚体时,您都不想使用Transform组件来移动对象。您宁愿只通过Rigidbody/Rigidbody2D组件移动它!

然后是一个普遍的问题。您可以根据输入来移动对象,也可以使用物理和力。两者同时发生是不可能的,因为两者transform.position或实际上的“正确”Rigidbody2D.MovePosition都会推翻力量,因此这两个系统一直在发生冲突。

因此我宁愿简单地velocity直接覆盖例如

void Update()
{
    // Store the current velocity
    var velocity = rb.velocity;

    var move = Input.GetAxis("Horizontal");

    // Only overwrite the X component
    // We don't need Time.deltaTime since a velocity already
    // moves the object over time
    velocity.x = move * speed;

    animator.SetFloat("Speed", Mathf.Abs(move));

    if (move < 0 && isFacingRight)
    {
        flip();
    }
    else if (move > 0 && !isFacingRight)
    {
        flip();
    }

    if(Input.GetKeyDown("space") && Mathf.Abs(rb.velocity.y) < 0.001f)
    {
        // simply overwrite the Y velocity
        // You'll have to adjust that value of course
        // and might want to rename it ;)
        velocity.y = Jumpforce;
    }

    if (Input.GetKey(KeyCode.Q) && canUseJetpack) 
    {
        // Here we want to use Time.deltaTime since the jetpack
        // shall increase the Y velocity over time
        // again you'll have to adjust/rename that value
        velocity.y += JetPackForce * Time.deltaTime;
        
        // Also adjust this value!
        // To be frame-rate independent you want to use Time.deltaTime here
        JetpackBar.instance.UseFuel(0.1f * Time.deltaTime);
      
        animator.SetBool("UsingJetpack", true);
    }
    else
    {
        animator.SetBool("UsingJetpack", false);
    }

    // After having calculated all changes in the velocity now set it again
    rb.velocity = velocity;

    if (HealthBar.instance.currentHealth <= 0)
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

推荐阅读