Unity自定义摇杆实现

烈酒焚心 提交于 2019-12-03 14:09:01

Unity自定义摇杆

Unity利用自带的UGUI进行制作摇杆,并且利用事件来自定义注册具体的实现。
摇杆只要组成就是一个背景图片和一个中心的用来触摸的圆。
具体需要哪种事件,根据自己的逻辑来判断实现,不一定所有都需要。
文末会附演示工程文件。

摇杆的事件代码

public class JoyStick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler, IEndDragHandler
{
    public float outerCircleRadius = 50;//可以拖动的最大距离

    Transform thumb;//触摸球

    Vector2 thumb_start;

    Vector2 direction;//滑动方向

    public Action<Vector2> onJoystickDownEvent;     // 按下事件
    public Action onJoystickUpEvent;               // 抬起事件
    public Action<Vector2> onJoystickDragEvent;     // 滑动事件
    public Action<Vector2> onJoystickDragEndEvent;  // 滑动结束事件

    void Start()
    {
        thumb = transform.Find("Thumb");
        thumb_start = transform.position;
        //初始化起始位置为陀螺仪的位置  下边利用减法计算相对位置
    }

    /// <summary>
    /// 按下
    /// </summary>
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("按下");

        //thumb.gameObject.SetActive(true);
        thumb.transform.position = eventData.position;

        //if (onJoystickDownEvent != null)
        //    onJoystickDownEvent(eventData.position);

    }

    /// <summary>
    /// 抬起
    /// </summary>
    public void OnPointerUp(PointerEventData eventData)
    {
        thumb.transform.localPosition = Vector3.zero;
        //鼠标松开后 内圆 回到原点

        //thumb.gameObject.SetActive(false);

        if (onJoystickUpEvent != null)
        {
            Debug.Log("抬起");
            onJoystickUpEvent();
        }
    }

    /// <summary>
    /// 拖动事件
    /// </summary>
    /// <param name="eventData"></param>
    public void OnDrag(PointerEventData eventData)
    {
        Vector2 touchPos = eventData.position - thumb_start;
        direction = touchPos;
        if (Vector3.Distance(touchPos, Vector2.zero) < outerCircleRadius)
            thumb.transform.localPosition = touchPos;
        else
        {
            thumb.transform.localPosition = touchPos.normalized * outerCircleRadius;
        }

        if (onJoystickDragEvent != null)
            onJoystickDragEvent(direction);

    }

    public void OnEndDrag(PointerEventData eventData)
    {
        direction= eventData.position - thumb_start;

        Debug.Log("结束拖动");
    }
}

方块移动应用举例

using UnityEngine;
using System.Collections;
using System;

public class MoveController : MonoBehaviour {


    public JoyStick joystick;

    bool isRun;


    UnityEngine.AI.NavMeshAgent nav;

    float h, v;

    Vector3 moveVec;

    // Use this for initialization
    void Start () {

        nav = GetComponent<UnityEngine.AI.NavMeshAgent>();

        //这个是否获取到了
        //joystick = GetComponent<PlayerJoyStick>();

        //joystick.onJoystickDownEvent += OnJoystickDownEvent;
        joystick.onJoystickUpEvent += OnJoystickUpEvent;
        joystick.onJoystickDragEvent += OnJoystickDragEvent;
        //joystick.onJoystickDragEndEvent += OnJoystickDragEndEvent;
    }


    void OnDestroy()
    {
        //joystick.onJoystickDownEvent -= OnJoystickDownEvent;
        joystick.onJoystickUpEvent -= OnJoystickUpEvent;
        joystick.onJoystickDragEvent -= OnJoystickDragEvent;
        //joystick.onJoystickDragEndEvent -= OnJoystickDragEndEvent;
    }

    private void OnJoystickUpEvent()
    {
        //停止移动
        isRun = false;
        h = 0;
        v = 0;

        moveVec = new Vector3(h, 0, v).normalized;
    }

    /// <summary>
    /// 按下
    /// </summary>
    /// <param name="obj"></param>
    private void OnJoystickDownEvent(Vector2 obj)
    {
        //停止移动
        isRun = false;
        h = 0;
        v = 0;

        moveVec = new Vector3(h, 0, v).normalized;
    }

    /// <summary>
    /// 传入一个方向 向量
    /// </summary>
    /// <param name="obj"></param>
    private void OnJoystickDragEvent(Vector2 obj)
    {
        //开始移动
        isRun = true;
        h = obj.x;
        v = obj.y;

        moveVec = new Vector3(h, 0, v).normalized;
    }

    /// <summary>
    /// 拖动结束
    /// </summary>
    /// <param name="obj"></param>
    private void OnJoystickDragEndEvent(Vector2 obj)
    {

    }

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

        if ( isRun && (h != 0 || v != 0) )
        {
            // 根据摄像机方向 进行移动 和摄像机保持相对平行视角
            //moveVec = Quaternion.Euler(0, Camera.main.transform.eulerAngles.y, 0) * moveVec;
            nav.Move(moveVec * Time.deltaTime * 5);
            RotatePlayer();
        }
    }

    private void RotatePlayer()
    {
        //向量v围绕y轴旋转cameraAngle.y度
        //向量旋转到正前方
        //Vector3 vec = Quaternion.Euler(0, 0, 0) * moveVec;
        Vector3 vec =  moveVec;
        Debug.Log(vec.ToString());
        if (vec == Vector3.zero)
            return;
        //人物看向那个方向
        Quaternion look = Quaternion.LookRotation(vec);
        transform.rotation = Quaternion.Lerp(transform.rotation, look, Time.deltaTime * 100);
    }
}

其他应用思考

摇杆的其他应用,除了最基本的控制人物的移动,还有比如王者荣耀技术的摇杆释放操作,
愤怒的小鸟 弹射小鸟的操作,吃鸡手游中的查看视角功能等。具体的功能只需要更改对应的接口注册事件即可。

附带的演示案例

链接: https://pan.baidu.com/s/1IqPPWhUR6W5ywfDyrn5Z3Q 密码: iwdu

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!