unity3d 玩家破折号不一致

ve7v8dk2  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(90)

我有一个代码,我与人工智能(或人工智能为我),使palyer冲上,下,右和左,当你在屏幕上滑动。它几乎像我预期的那样工作,但唯一的问题是玩家总是冲不同的距离,例如当我冲下来又冲起来时,我不是在和我开始的位置相同的位置。代码如下:

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

public class PlayerController : MonoBehaviour
{
    private Vector2 touchStartPos;
    private Rigidbody2D rb;
    public float dashSpeed = 10f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            touchStartPos = Input.GetTouch(0).position;
        }
        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended)
        {
            Vector2 touchEndPos = Input.GetTouch(0).position;
            Vector2 swipeDirection = touchEndPos - touchStartPos;
            if (swipeDirection.magnitude > 50f)
            {
                swipeDirection.Normalize();
                if (Mathf.Abs(swipeDirection.x) > Mathf.Abs(swipeDirection.y))
                {
                    swipeDirection.y = 0f;
                }
                else
                {
                    swipeDirection.x = 0f;
                }
                rb.velocity = swipeDirection * dashSpeed;
                StartCoroutine(DashCoroutine());
            }
        }
    }

    IEnumerator DashCoroutine()
    {
        yield return new WaitForSeconds(5 / dashSpeed);
        rb.velocity = Vector3.zero;
    }
}

所以我的问题基本上是我如何修复这个代码,使我总是破折号相同的距离,或者如果有任何更好的代码(我很肯定有)。(这是一个2D自上而下的游戏)

dwbf0jvd

dwbf0jvd1#

编辑:您可能会遇到另一个问题:
在移除其中一个轴值之前进行归一化

swipeDirection.Normalize();
if (Mathf.Abs(swipeDirection.x) > Mathf.Abs(swipeDirection.y))
    swipeDirection.y = 0f;
else
    swipeDirection.x = 0f;

考虑类似于
V =(1.64,0.(第三十八条)
标准化将给予(0。974191,0.225727),然后将其归零为

(0.974191,0.0)

但如果你的矢量是
V =(1.64,1.(第三十八条)
然后将其归一化为(0)。765153、0.643848),然后归零至

(0.765153,0.0)

您只需要一个方向,因此需要在将值归零后进行归一化。

if (Mathf.Abs(swipeDirection.x) > Mathf.Abs(swipeDirection.y))
    swipeDirection.y = 0f;
else
    swipeDirection.x = 0f;
swipeDirection.Normalize();

你也可能有问题的帧率依赖物理。如果你正在处理物理问题,你需要使用FixedUpdate,否则你所有的物理工作都将取决于你的帧率。您确实希望将输入工作保留在Update中。
像这样的东西会有用的

Vector3? newDashVelocity = null
void Update()
{
    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
    {
        touchStartPos = Input.GetTouch(0).position;
    }
    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Ended)
    {
        Vector2 touchEndPos = Input.GetTouch(0).position;
        Vector2 swipeDirection = touchEndPos - touchStartPos;
        if (swipeDirection.magnitude > 50f)
        {
            swipeDirection.Normalize();
            if (Mathf.Abs(swipeDirection.x) > Mathf.Abs(swipeDirection.y))
            {
                swipeDirection.y = 0f;
            }
            else
            {
                swipeDirection.x = 0f;
            }
            newDashVelocity = swipeDirection * dashSpeed;
           
        }
    }
}

void FixedUpdate()
{
    // if there is no new dash velocity, do nothing
    if(!newDashVelocity.HasValue)
        return;

    rb.velocity = newDashVelocity.Value;

    newDashVelocity = null; // reset this so we don't apply it twice
    StartCoroutine(DashCoroutine()); // begin the coroutine
}

这将把新的速度传递给固定更新,因此每次固定更新只应用一次
然后,对于您的协程,您还希望它尽可能地与固定更新绑定

IEnumerator DashCoroutine()
{
    var waitTime = 5.f / dashSpeed;
    float elapsedTime = 0;
    while(elapsedTime < waitTime)
    {
        elapsedTime += Time.FixedDeltaTime;
        yield return new WaitForFixedUpdate();
    }
    rb.velocity = Vector3.zero;
}

这应该使你的破折号最后确定数量的固定更新步骤,并保持它更可靠。

相关问题