简体   繁体   English

如何避免播放器跳过物体?

[英]How can I avoid my player from jumping through objects?

When my player jumps in front of an object it will just jump right through it and I don't know how to fix it. 当我的播放器跳到某个物体的前面时,它会直接跳过该物体,而我不知道如何解决。 I know it is because I am using transform to move my player but this has been the easiest way for it to jump so I don't want to change that. 我知道这是因为我正在使用transform来移动播放器,但这是它跳转的最简单方法,所以我不想更改它。 Here is my code to move my player: 这是我用来移动播放器的代码:

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

Your problem is that you are applying a transform on the player position - you really need to calculate a route from the current position to the destination implied by the transformation, and then do collision detection on every intermediate point. 您的问题是您要在玩家位置上应用转换-您确实需要计算转换所隐含的从当前位置到目的地的路线,然后在每个中间点进行碰撞检测。

This is a problem with many examples on the web, but googling Unity Collision Detection will suggest a lot of examples. 这是网络上许多示例的问题,但是使用Google Unity Collision Detection会发现很多示例。

Since this is a GameObject with Rigidbody attached to it, and you want to detect collision while moving it, you must use the MovePosition and MoveRotation functions instead of moving its transform component directly. 由于这是一个附加了RigidbodyMovePosition ,并且您想在移动它时检测碰撞,因此必须使用MovePositionMoveRotation函数,而不是直接移动其transform组件。

So, code such as transform.position = newPos + up; 因此,诸如transform.position = newPos + up;等代码transform.position = newPos + up; and transform.rotation = Quaternion.Euler (0, 180, 0); transform.rotation = Quaternion.Euler (0, 180, 0); must changed to rigidbody.MovePosition(newPos + up); 必须更改为rigidbody.MovePosition(newPos + up); and rigidbody.MoveRotation(Quaternion.Euler(0, 180, 0)); rigidbody.MoveRotation(Quaternion.Euler(0, 180, 0)); .

Enable Rigidbody Interpolation to move the GameObject smoothly. 启用“ Rigidbody插值”可平滑移动GameObject。 Also, isKinematic must be true/enabled or else, using MovePosition and MoveRotation will be useless just like moving Rigidbody by transform.position ... 另外, 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM