我该如何避免玩家跳过物体?

本文关键字:玩家 何避免 | 更新日期: 2023-09-27 18:04:30

当我的玩家跳到一个对象前面时,它会直接跳过它,我不知道如何修复它。我知道这是因为我正在使用transform来移动我的玩家,但这是让它跳跃的最简单方法,所以我不想改变它。下面是我移动播放器的代码:

using UnityEngine;
using System.Collections;
public class MovePlayer : MonoBehaviour
{   
    private Vector3 newPos;
    private Vector3 up = new Vector3 (0, .3f, 0);
    private bool jumping = false;
    public Rigidbody rigidbody;
    void Start(){
        rigidbody = GetComponent<Rigidbody> ();
    }
    void Update(){
        rigidbody.freezeRotation = true;
        if (!jumping) {
            if (Input.GetKeyDown (KeyCode.UpArrow)) {
                newPos = Vector3.forward + transform.position;
                transform.rotation = Quaternion.Euler (0, 0, 0);
                transform.position = (newPos);
                transform.position = newPos + up;               
            } 
            if (Input.GetKeyDown (KeyCode.DownArrow)) {
                newPos = Vector3.back + transform.position;
                transform.rotation = Quaternion.Euler (0, 180, 0);
                transform.position = (newPos);
                transform.position = newPos + up;
            }
            if (Input.GetKeyDown (KeyCode.RightArrow)) {
                newPos = Vector3.right + transform.position;
                transform.rotation = Quaternion.Euler (0, 90, 0);
                transform.position = (newPos);
                transform.position = newPos + up;
            }
            if (Input.GetKeyDown (KeyCode.LeftArrow)) {
                newPos = Vector3.left + transform.position;
                transform.rotation = Quaternion.Euler (0, -90, 0);
                transform.position = (newPos);
                transform.position = newPos + up;
            }               
        }
    }
    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.CompareTag ("Ground")) 
            jumping = false;
    }
    void OnCollisionExit(Collision other)
    {
        if (other.gameObject.CompareTag("Ground"))
            jumping = true;
    }
}

我该如何避免玩家跳过物体?

你的问题是你正在对玩家位置应用变换——你真的需要计算从当前位置到变换隐含的目的地的路线,然后在每个中间点做碰撞检测。

这是一个问题,在网络上的许多例子,但谷歌Unity碰撞检测会建议很多的例子。

因为这是一个带有Rigidbody的GameObject,并且你想在移动它时检测碰撞,你必须使用MovePositionMoveRotation函数而不是直接移动它的transform组件。

因此,代码如transform.position = newPos + up;transform.rotation = Quaternion.Euler (0, 180, 0);必须更改为rigidbody.MovePosition(newPos + up);rigidbody.MoveRotation(Quaternion.Euler(0, 180, 0));

启用Rigidbody插值平滑移动游戏对象。此外,isKinematic必须是true/enabled,否则,使用MovePositionMoveRotation将是无用的,就像用transform.position移动Rigidbody一样…

public class MovePlayer : MonoBehaviour
{
    private Vector3 newPos;
    private Vector3 up = new Vector3(0, .3f, 0);
    private bool jumping = false;
    public Rigidbody rigidbody;
    void Start()
    {
        rigidbody = GetComponent<Rigidbody>();
    }
    void Update()
    {
        rigidbody.freezeRotation = true;
        if (!jumping)
        {
            if (Input.GetKeyDown(KeyCode.UpArrow))
            {
                newPos = Vector3.forward + transform.position;
                rigidbody.MoveRotation(Quaternion.Euler(0, 0, 0));
                rigidbody.MovePosition(newPos);
                rigidbody.MovePosition(newPos + up);
            }
            if (Input.GetKeyDown(KeyCode.DownArrow))
            {
                newPos = Vector3.back + transform.position;
                rigidbody.MoveRotation(Quaternion.Euler(0, 180, 0));
                rigidbody.MovePosition(newPos);
                rigidbody.MovePosition(newPos + up);
            }
            if (Input.GetKeyDown(KeyCode.RightArrow))
            {
                newPos = Vector3.right + transform.position;
                rigidbody.MoveRotation(Quaternion.Euler(0, 90, 0));
                rigidbody.MovePosition(newPos);
                rigidbody.MovePosition(newPos + up);
            }
            if (Input.GetKeyDown(KeyCode.LeftArrow))
            {
                newPos = Vector3.left + transform.position;
                rigidbody.MoveRotation(Quaternion.Euler(0, -90, 0));
                rigidbody.MovePosition(newPos);
                rigidbody.MovePosition(newPos + up);
            }
        }
    }
    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.CompareTag("Ground"))
            jumping = false;
    }
    void OnCollisionExit(Collision other)
    {
        if (other.gameObject.CompareTag("Ground"))
            jumping = true;
    }
}