如何在Unity 2D中创建一致的破折号速度?

huangapple go评论91阅读模式
英文:

How can I create a consistent dash speed in Unity 2D?

问题

我已经在我的Unity2D顶视角游戏中的playerMovement脚本中实现了一个Dash功能。Dash基本上按照预期的方式运行,除了一个例外。当玩家对象与一个物体碰撞,然后进行Dash时,Dash变得非常缓慢。我怀疑这是因为物体阻止了玩家对象的移动,导致其速度为0。以下是与我的玩家移动相关的所有相关代码。

public class playerMovement : MonoBehaviour
{
    private Rigidbody2D playerRB;
    private float dashForce = 75f;

    public float playerSpeed = 175f;

    void Start()
    {
        playerRB = GetComponent<Rigidbody2D>(); // 获取使用此脚本的对象的刚体。
        position = transform.position; // 获取此对象的位置。
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) dash();
    }

    void FixedUpdate()
    {
        playerInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        playerInput.Normalize();
        playerRB.AddForce(playerInput * playerSpeed); // 玩家移动
    }

    void dash()
    {
        // 在Dash期间禁用与敌人和敌人子弹的碰撞
        gameObject.layer = LayerMask.NameToLayer("dashIgnore");

        StartCoroutine(enableCollisionsAfterDelay(0.2f)); // 根据Dash持续时间需要调整延迟
        Vector2 dashDirection = playerRB.velocity.normalized; // 将当前归一化速度存储为Dash方向

        dashTrail.emitting = true; // 启用拖尾
        playerRB.AddForce(dashDirection * dashForce, ForceMode2D.Impulse);
    }

    IEnumerator enableCollisionsAfterDelay(float delay)
    {
        yield return new WaitForSeconds(delay);

        // 在Dash后启用与敌人和敌人子弹的碰撞
        gameObject.layer = LayerMask.NameToLayer("Player");

        dashTrail.emitting = false; // 禁用拖尾
    }
}

我尝试过的一些解决方案是在Dash函数中使用Rigidbody2D.velocity而不是Rigidbody2D.AddForce方法,但是这产生了相同的错误,并且Dash运动效果不太满意,所以我恢复了以前的代码。我还考虑过尝试计算玩家从移动到静止时速度的差异,以尝试获得一致的Dash速度,而不考虑玩家的移动速度。我的尝试产生了一些不利的结果,所以我放弃了这个想法,尽管我认为这将是解决我的问题的最佳方法。

感谢任何帮助、想法或建议!

英文:

I have implemented a Dash Function, into the playerMovement script of my Unity2D top-down game. The dash works pretty much as intended with one exception. When the Player object collides with an object, by traveling in the objects direction, and then dashes. The dash becomes extremely slow. I suspect this is because the object blocks the movement of the Player object causing its velocity to equal 0. This is all of the relevant code to my Player's movement.

public class playerMovement : MonoBehaviour
{
    private Rigidbody2D playerRB;
    private float dashForce = 75f;

    public float playerSpeed = 175f;

    void Start()
    {
        playerRB = GetComponent&lt;Rigidbody2D&gt;(); // Grab rigidbody of object using this script.
        position = transform.position; // Get position of this object.
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) dash();
    }

    void FixedUpdate()
    {
        playerInput = new Vector2(Input.GetAxis(&quot;Horizontal&quot;), Input.GetAxis(&quot;Vertical&quot;));
        playerInput.Normalize();
        playerRB.AddForce(playerInput * playerSpeed); // Player movement
    }

    void dash()
    {
        // Disable collisions with enemies and enemy bullets during the dash
        gameObject.layer = LayerMask.NameToLayer(&quot;dashIgnore&quot;);

        StartCoroutine(enableCollisionsAfterDelay(0.2f)); // Adjust the delay as needed for the dash duration
        Vector2 dashDirection = playerRB.velocity.normalized; // Store the current normalized velocity as the dash direction

        dashTrail.emitting = true; // enabling trail
        playerRB.AddForce(dashDirection * dashForce, ForceMode2D.Impulse);
    }

    IEnumerator enableCollisionsAfterDelay(float delay)
    {
        yield return new WaitForSeconds(delay);

        // Enable collisions with enemies and enemy bullets after the dash
        gameObject.layer = LayerMask.NameToLayer(&quot;Player&quot;);

        dashTrail.emitting = false; // disabling trail
    }
}

Some of the solutions I have tried were to use Rigidbody2D.velocity for the dash function instead of the RigidBody2D.AddForce method, however, this produced the same bug with a less satisfying dash movement so I reverted to my previous code. I also considered trying to calculate the difference in velocity from when the player was moving and still, to try and have a consistent dash speed regardless of the players movement speed. My attempts at this produced some unfavorable results so I scrapped the idea, although I think this would be the best solution to my problem.

Any help, ideas, or recommendations are appreciated!
Thanks!

**Edit: After more Debugging I've deduced the problem is caused by the Rigidbody.velocity equalling zero when the dash is used. This causes the dash to no longer function.

答案1

得分: 0

我很高兴地说,我能够相对容易地解决这个问题。经过一些调试,我发现Unity的碰撞检测在初始碰撞后会多次更新玩家的位置。由于我的移动依赖于玩家的运动,我认为冲刺力是与我的玩家运动力方向相反的,因此导致了减速效果。

我的解决方案相当简单。
首先,我创建了两个新变量,lastVector和threshold。

private Rigidbody2D playerRB;
private float dashForce = 75f;
public float playerSpeed = 175f;
private Vector2 lastVector;
private float threshold = 0.1f;

void Start()
{
    playerRB = GetComponent&lt;Rigidbody2D&gt;(); // 获取该脚本所附加的对象的刚体组件。
    lastVector = playerRB.velocity;
    position = transform.position; // 获取该对象的位置。
}

这个想法是保存玩家的最后速度,并忽略任何速度变化的幅度大于或等于阈值的情况。我通过在我的FixedUpdate()中添加了一行新代码来实现这一点。
注意:根据@ComaneanuMugurel的建议,将玩家输入代码移到了Update()中。

void FixedUpdate()
{
    if ((playerRB.velocity - lastVector).magnitude &gt;= threshold) lastVector = playerRB.velocity;
    playerRB.AddForce(playerInput * playerSpeed); // 应用玩家移动力
}

最后,在存储了玩家先前速度之后,我只是在我的dash()函数中替换了变量。这样它只使用玩家的上一个向量。

void dash()
{
    // 在冲刺期间禁用与敌人和敌人子弹的碰撞
    gameObject.layer = LayerMask.NameToLayer("dashIgnore");

    StartCoroutine(enableCollisionsAfterDelay(0.2f)); // 根据冲刺持续时间需要调整延迟
    Vector2 dashDirection = lastVector.normalized; // 将当前归一化速度存储为冲刺方向

    dashTrail.emitting = true; // 启用拖尾效果
    playerRB.AddForce(dashDirection * dashForce, ForceMode2D.Impulse);
}

如果有人对我的解决方案有任何问题,请随时提问!

英文:

I am glad to say I was able to solve this one relatively easily. After some debugging, I found that Unity collision detection continues to update the player's position several times after the initial collision. Since my movement relies on the player's motion I believe the dash force was working in the opposite direction of my player's movement force, thereby causing a slowing effect.

My solution to this was quite simple.
I started by creating two new variables, lastVector and threshold.

private Rigidbody2D playerRB;
private float dashForce = 75f;

public float playerSpeed = 175f;

private Vector2 lastVector;
private float threshold = 0.1f;

void Start()
{
    playerRB = GetComponent&lt;Rigidbody2D&gt;(); // Grab rigidbody of object using this script.
    lastVector = playerRB.velocity;
    position = transform.position; // Get position of this object.
}

The idea behind this was to save the player's last velocity and ignore any changes in velocity with a magnitude greater than or equal to the threshold. The way I did this was by adding a new line to my FixedUpdate().
Note: Moved player input code to Update() as recommended by @ComaneanuMugurel.

void FixedUpdate()
{
    if ((playerRB.velocity - lastVector).magnitude &gt;= threshold) lastVector = playerRB.velocity;
    playerRB.AddForce(playerInput * playerSpeed); // Apply player movement forces
}

Finally, after storing the player's previous velocity, I just replaced the variable within my dash() function. This way it only uses the player's last vector.

void dash()
{
    // Disable collisions with enemies and enemy bullets during the dash
    gameObject.layer = LayerMask.NameToLayer(&quot;dashIgnore&quot;);

    StartCoroutine(enableCollisionsAfterDelay(0.2f)); // Adjust the delay as needed for the dash duration
    Vector2 dashDirection = lastVector.normalized; // Store the current normalized velocity as the dash direction

    dashTrail.emitting = true; // enabling trail
    playerRB.AddForce(dashDirection * dashForce, ForceMode2D.Impulse);
}

If anybody has any questions about my solution feel free to ask!

huangapple
  • 本文由 发表于 2023年7月18日 15:26:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76710394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定