设计特定的网格运动

时间:2014-07-02 21:18:11

标签: unity3d game-physics 2d-games

我想要实现的是播放器按住鼠标按钮

在图块上(任何网格元素,与玩家完全或水平对齐),玩家将朝向该图块移动,可能的方向是左,右,上,下。

目前我的代码在按下鼠标按钮时不起作用,我认为它与光线投射有关。

我想要实现的第二件事是,当玩家在网格中移动时,如果玩家决定改变方向,他将能够,无论是否正好相反,或者他是否决定突然转弯左/右

(我设法在不使用isMoving布尔条件的情况下实现了它,只是在相反的方向,但是我添加了它,因为当玩家在移动时点击它会减慢他的速度)

现在移动时移动没有变化。

using UnityEngine;
using Holoville.HOTween;
using System.Collections;

public class Player : MonoBehaviour {

    public float speed = 100f;
    private Vector3 startPos;
    private Vector3 endPos;
    private float startTime;
    private float journeyLength;
    private tile currentTile;
    private tile tileToMove;
    private float angleToTurn = 0f;
    private bool isMoving = false;
    public static Player use;

    void Awake()
    {
        use = this;
    }

    void Start () {

        startPos = endPos = transform.position;
        tileToMove = currentTile = fieldGenerator.use.tilesList[0];
    }

    // Update is called once per frame
    void Update () {

        MovePlayer();

        float distCovered = (Time.time - startTime) * speed;
        float fracJourney = distCovered / journeyLength;

        if (!startPos.Equals(endPos))
            transform.position = Vector3.Lerp(startPos, endPos, fracJourney);

        if (transform.position == endPos)
        {
            isMoving = false;
        }
    }

    void MovePlayer()
    {
        Ray ray;
        RaycastHit hit;

        if (Input.GetMouseButtonDown(0) && !isMoving)
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            for (int i = 0; i < fieldGenerator.use.tilesList.Count; i++)
            {
                if (fieldGenerator.use.tilesList[i].selfObject.collider.Raycast(ray, out hit, float.PositiveInfinity))
                {
                    if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x < transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y)
                    {
                        angleToTurn = -180f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    }
                    else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x > transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y)
                    {
                        angleToTurn = 0;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    }
                    else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y < transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x)
                    {
                        angleToTurn = -90f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    }
                    else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y > transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x)
                    {
                        angleToTurn = 90f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    }

                    startTime = Time.time;
                    startPos = transform.position;
                    endPos = tileToMove.selfObject.transform.position;
                    journeyLength = Vector3.Distance(startPos, endPos);
                    transform.eulerAngles = new Vector3(0f, 0f, angleToTurn);
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

不确定您正在使用瓷砖和光线投射做什么,但这是我如何做到的。为格式化道歉,这就是我的工作方式。

编辑:好的,鉴于你说'网格'运动,我认为瓷砖彼此是等距的。 GetMouseButtonDown也改为GetMouseButton。这意味着每次更新都会拍摄一条光线,您可能希望这些更新能够提高效率。

using UnityEngine;
using Holoville.HOTween;
using System.Collections;

public class Player : MonoBehaviour {

    public float speed          = 100.0f;
    private float delta         = 0.0f;
    private float distance      = 1.0f;
    private Vector3 startPos;
    private Vector3 endPos;
    private tile currentTile;
    private tile tileToMove;
    private float angleToTurn   = 0f;
    private bool isMoving       = false;
    public static Player use;

    void Awake() {
        use = this;
    }

    void Start () {
        startPos = endPos = transform.position;
        tileToMove = currentTile = fieldGenerator.use.tilesList[0];
    }

    // Update is called once per frame
    void Update () {
        GetInput();
        MovePlayer();
    }

    void MovePlayer() {
        if ( isMoving ) {
            if ( delta < 1 ) {
                // Distance independant movement.
                delta += ( speed/distance ) * Time.deltaTime;
                transform.position = Vector3.Lerp(startPos, endPos, delta);
            } else {
                isMoving = false;
            }
        }
    }

    void GetInput() {
        Ray ray;
        RaycastHit hit;

        if ( Input.GetMouseButton(0) ) {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            for (int i = 0; i < fieldGenerator.use.tilesList.Count; i++) {
                if ( fieldGenerator.use.tilesList[i].selfObject.collider.Raycast( ray, out hit, float.PositiveInfinity ) ) {
                    if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x < transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y) {
                        angleToTurn = -180f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    } else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x > transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y) {
                        angleToTurn = 0;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    } else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y < transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x) {
                        angleToTurn = -90f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    } else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y > transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x) {
                        angleToTurn = 90f;
                        tileToMove = fieldGenerator.use.tilesList[i];
                        isMoving = true;
                    }

                    isMoving    = true;
                    delta           = 0f;
                    startPos        = transform.position;
                    endPos      = tileToMove.selfObject.transform.position;
                    distance        = Vector3.Distance( startPos, endPos );
                    transform.eulerAngles = new Vector3(0f, 0f, angleToTurn);
                }
            }
        }
    }
}