简体   繁体   English

如何在Unity 3d中跳过固定距离?

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

I have a Controller which moves my object diagonally. 我有一个控制器,可以对角移动对象。 The left arrow should move the player forward and to the left 45 degrees, and the right arrow the same to the right. 左箭头应将播放器向前和向左移动45度,右箭头应向右相同。 I would like to move the player relatively to its current position. 我想将播放器相对移动到当前位置。 Right now it moves relatively to the point(0,0,0). 现在它相对移动到点(0,0,0)。

My code: 我的代码:

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;
        }
    }
}

How can resolve this? 如何解决呢? Any ideas? 有任何想法吗? Thanks a lot! 非常感谢!

The short answer is: you hard-coded two locations you want to jump to: points (1, 1) and (-1, 1). 简短的答案是:您对要跳转到的两个位置进行了硬编码:点(1,1)和(-1,1)。 You should create new Vector each time you start jumping. 每次开始跳跃时,您都应该创建新的Vector。 Replace each 更换每个

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

with this line: 用这一行:

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

and it should work. 它应该工作。

While I'm on it, there are some other things I want to point: 在进行此操作时,我还需要指出其他一些事项:

  • There is a lot of floating point error after each jump. 每次跳转后都有很多浮点错误。 Notice that in your code v3T will never be equal to v3Dest (you never actually reach your destination), because you switch the moving flag earlier. 请注意,在代码中v3T 永远不会等于v3Dest (您永远不会真正到达目的地),因为您早先切换了moving标志。 You should explicitly set your position to v3Dest when the jump is over. 跳转结束后, v3Dest位置明确设置为v3Dest
  • You are checking jump timers etc. every frame. 您正在每帧检查跳跃计时器等。 A more elegent solution is to start a coroutine . 更为优雅的解决方案是启动协程
  • You use a sinusoid as your jump curve, which looks ok, but using a parabola would be conceptually more correct. 您可以使用正弦曲线作为跳跃曲线,看起来不错,但使用抛物线从概念上讲更正确。
  • Right now it is possible to start next jump mid-air (I'm not sure whether it is intended or not) 现在可以开始半空跳下(我不确定是否是故意的)

Here is some code you may use that avoids those problems: 您可以使用以下代码来避免这些问题:

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