簡體   English   中英

如何在Unity 3d中跳過固定距離?

[英]How do I jump a fix distance in Unity 3d?

我有一個控制器,可以對角移動對象。 左箭頭應將播放器向前和向左移動45度,右箭頭應向右相同。 我想將播放器相對移動到當前位置。 現在它相對移動到點(0,0,0)。

我的代碼:

public class JollyJumper : MonoBehaviour {

protected CharacterController control;
    public float fTime = 1.5f;      // Hop time
    public float fRange = 5.0f;     // Max dist from origin
    public float fHopHeight = 2.0f; // Height of hop

    private Vector3 v3Dest;
    private Vector3 v3Last;
    private float fTimer = 0.0f;
    private bool moving = false;
    private int number= 0;
    private Vector2 direction;

    public virtual void Start () {

        control = GetComponent<CharacterController>();

        if(!control){

            Debug.LogError("No Character Controller");
            enabled=false;

        }

    }


    void Update () {

       if (fTimer >= fTime&& moving) {
        var playerObject = GameObject.Find("Player");
        v3Last = playerObject.transform.position;
        Debug.Log(v3Last);
        v3Dest = direction *fRange;
        //v3Dest = newVector* fRange + v3Last;

         v3Dest.z = v3Dest.y;
         v3Dest.y = 0.0f;
         fTimer = 0.0f;
        moving = false;
       }

        if(Input.GetKeyDown(KeyCode.LeftArrow)){
            moving = true;
            direction = new Vector2(1.0f, 1.0f);
            number++;
        }

        if(Input.GetKeyDown(KeyCode.RightArrow)){
            moving = true;
            direction = new Vector2(-1.0f, 1.0f);
            number++;
        }
        if(moving){
       Vector3 v3T = Vector3.Lerp (v3Last, v3Dest, fTimer / fTime);
       v3T.y = Mathf.Sin (fTimer/fTime * Mathf.PI) * fHopHeight;
       control.transform.position = v3T;
       fTimer += Time.deltaTime;
        }
    }
}

如何解決呢? 有任何想法嗎? 非常感謝!

簡短的答案是:您對要跳轉到的兩個位置進行了硬編碼:點(1,1)和(-1,1)。 每次開始跳躍時,您都應該創建新的Vector。 更換每個

direction = new Vector2(1.0f, 1.0f);

用這一行:

v3Dest = transform.position + new Vector3(1.0f, 0, 1) * fRange;

它應該工作。

在進行此操作時,我還需要指出其他一些事項:

  • 每次跳轉后都有很多浮點錯誤。 請注意,在代碼中v3T 永遠不會等於v3Dest (您永遠不會真正到達目的地),因為您早先切換了moving標志。 跳轉結束后, v3Dest位置明確設置為v3Dest
  • 您正在每幀檢查跳躍計時器等。 更為優雅的解決方案是啟動協程
  • 您可以使用正弦曲線作為跳躍曲線,看起來不錯,但使用拋物線從概念上講更正確。
  • 現在可以開始半空跳下(我不確定是否是故意的)

您可以使用以下代碼來避免這些問題:

using System.Collections;
using UnityEngine;

public class Jumper : MonoBehaviour
{
#region Set in editor;

public float jumpDuration = 0.5f;
public float jumpDistance = 3;

#endregion Set in editor;

private bool jumping = false;
private float jumpStartVelocityY;

private void Start()
{
    // For a given distance and jump duration
    // there is only one possible movement curve.
    // We are executing Y axis movement separately,
    // so we need to know a starting velocity.
    jumpStartVelocityY = -jumpDuration * Physics.gravity.y / 2;
}

private void Update()
{
    if (jumping)
    {
        return;
    }
    else if (Input.GetKeyDown(KeyCode.LeftArrow))
    {
        // Warning: this will actually move jumpDistance forward
        // and jumpDistance to the side.
        // If you want to move jumpDistance diagonally, use:
        // Vector3 forwardAndLeft = (transform.forward - transform.right).normalized * jumpDistance;
        Vector3 forwardAndLeft = (transform.forward - transform.right) * jumpDistance;
        StartCoroutine(Jump(forwardAndLeft));
    }
    else if (Input.GetKeyDown(KeyCode.RightArrow))
    {
        Vector3 forwardAndRight = (transform.forward + transform.right) * jumpDistance;
        StartCoroutine(Jump(forwardAndRight));
    }
}

private IEnumerator Jump(Vector3 direction)
{
    jumping = true;
    Vector3 startPoint = transform.position;
    Vector3 targetPoint = startPoint + direction;
    float time = 0;
    float jumpProgress = 0;
    float velocityY = jumpStartVelocityY;
    float height = startPoint.y;

    while (jumping)
    {
        jumpProgress = time / jumpDuration;

        if (jumpProgress > 1)
        {
            jumping = false;
            jumpProgress = 1;
        }

        Vector3 currentPos = Vector3.Lerp(startPoint, targetPoint, jumpProgress);
        currentPos.y = height;
        transform.position = currentPos;

        //Wait until next frame.
        yield return null;

        height += velocityY * Time.deltaTime;
        velocityY += Time.deltaTime * Physics.gravity.y;
        time += Time.deltaTime;
    }

    transform.position = targetPoint;
    yield break;
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM