Player移动控制

2019-04-24  本文已影响0人  小黑Unity_齐xc

要求

1、支持手机端手指触屏滑动,控制物体移动;
2、不能超出屏幕边界(左、上、右、下)

知识点

1、手指输入,当前使用Input来实现(也可用EsayTouch5实现)

//获取水平、垂直方向增量,范围(-1~1),对应键盘的wasd按键或上下左右按键操作;
Input.GetAxis ("Vertical")
Input.GetAxis ("Horizontal")

//获取鼠标增量,当前帧和上一帧鼠标移动的距离,移动设备触摸也可使用,范围不局限于(-1~1)
Input.GetAxis ("Mouse X")
Input.GetAxis ("Mouse Y")

所以在移动设备上通过手指移动物体,我们应先获得鼠标增量值,然后用于设置物体的移动。

使用控制器和键盘输入时此值范围在-1到1之间。
如果坐标轴设置为鼠标运动增量,鼠标增量乘以坐标轴灵敏度的范围将不是-1到1 ;

2、获取移动设备屏幕宽高,以及左上右下边界位置:

因为游戏是2D模式,且摄像机的选择了正交投影Orthographic
我们可以直接通过摄像机获得设备宽高和边界信息:

//获取主摄像机
Camera cam = Camera.main;
//高度为摄像机正交投影大小的两倍
height = 2f * cam.orthographicSize;
//宽度为高度乘以摄像机视角的宽高比(即移动设备屏幕的宽高比)
width = height * cam.aspect;

//当前摄像机位置为(0,0),下面是计算屏幕边界距离中心点的位置
left = -width / 2;
right = width / 2;
top = height / 2;
bottom = -height / 2;

3、物体的移动方式选择

2D游戏中,物体使用了rigidbody2D,我们不应通过Transform去控制物体的移动(因性能太低);
应通过rigidbody2D来控制物体的移动,如:

rigidbody.velocity = new Vector2 (h * speed, v * speed);

代码实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainMove : MonoBehaviour
{
    public float speed = 5f;

    private Rigidbody2D rigidbody;
    private float velocity_zero = 0;

    private float width;
    private float height;
    private float left;
    private float right;
    private float top;
    private float bottom;

    void Awake ()
    {
        rigidbody = GetComponent<Rigidbody2D> ();
        rigidbody.velocity = new Vector2 (velocity_zero, velocity_zero);

        Camera cam = Camera.main;
        height = 2f * cam.orthographicSize;
        width = height * cam.aspect;

        left = -width / 2;
        right = width / 2;
        top = height / 2;
        bottom = -height / 2;
    }

    bool isTouch = false;
    float h;
    float v;

    void Update ()
    {
        if (h != 0 || v != 0) {
            isTouch = true;
        } else {
            isTouch = false;
        }
        h = Input.GetAxis ("Mouse X");
        v = Input.GetAxis ("Mouse Y");

        Debug.Log ("h:" + h + "  v:" + v);

        if (isTouch) {
            if (Mathf.Abs (h) > 0.01f || Mathf.Abs (v) > 0.01f) {
                if (isWidthBoundary (h)) {
                    rigidbody.velocity = new Vector2 (velocity_zero, v * speed);
                } else if (isHeightBoundary (v)) {
                    rigidbody.velocity = new Vector2 (h * speed, velocity_zero);
                } else {
                    rigidbody.velocity = new Vector2 (h * speed, v * speed);
                }
                Debug.Log (rigidbody.velocity);
            } else {
                rigidbody.velocity = new Vector2 (velocity_zero, velocity_zero);
            }
        }
    }

    bool isWidthBoundary (float h)
    {
        //在left与right之间,返回false
        //在left左边,手势为正方向,返回false
        //在right右边,手势为反方向,返回false
        if (transform.position.x > left && transform.position.x < right) {
            return false;
        }
        if (transform.position.x < left && h > 0) {
            return false;
        }
        if (transform.position.x > right && h < 0) {
            return false;
        }
        return true;
    }

    bool isHeightBoundary (float v)
    {
        //在top与right之间,返回false
        //在top上边,手势为正方向,返回false
        //在bottom下边,手势为反方向,返回false
        if (transform.position.y > bottom && transform.position.y < top) {
            return false;
        }
        if (transform.position.y > top && v < 0) {
            return false;
        }
        if (transform.position.y < bottom && v > 0) {
            return false;
        }
        return true;
    }
}

效果图

a.gif
上一篇下一篇

猜你喜欢

热点阅读