[Unity实战]一个简单的unity手写摇杆[入门级][手写demo][开箱可用]

1.摇杆是什么

固定移动摇杆的意思指固定一个摇杆的贴图,操作模式和以前一样,以点击的第一个点为游戏杆中心滑动。玩家在进入游戏后打开设置页面,接着选择操作设置,然后找到界面中的“固定移动摇杆”选项就可以开启或者关闭了。
摇杆一般所说的摇杆指设计为街机游戏,飞行模拟类等游戏使用的摇杆。一般用于拳皇、街霸等格斗游戏。绝大多数是直接采用飞机飞行控制杆作为原型去设计的,可以说具有很强的仿真度,游戏摇杆利用前后左右拨动摇杆去进行方向上的调整,直接影响着飞行游戏中的飞行状态。
在这里插入图片描述

2.常见的unity摇杆插件

Unity3D EasyTouch 初步使用教程(详细)

3.如何做一个简单摇杆(代码)

基类:

/****************************************************
    文件:BaseTouch.cs
	功能:基类
*****************************************************/
using UnityEngine;
using System;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class BaseTouch : MonoBehaviour 
{
    protected T GetOrAddComponect<T>(GameObject go) where T : Component
    {
        T t = go.GetComponent<T>();
        if (t == null)
        {
            t = go.AddComponent<T>();
        }

        return t;
    }
    
    protected void OnClickDown(GameObject go, Action<PointerEventData> cb)
    {
        TouchListener listener = GetOrAddComponect<TouchListener>(go);
        listener.onClickDown = cb;
    }

    protected void OnClickUp(GameObject go, Action<PointerEventData> cb)
    {
        TouchListener listener = GetOrAddComponect<TouchListener>(go);
        listener.onClickUp = cb;
    }

    protected void OnDrag(GameObject go, Action<PointerEventData> cb)
    {
        TouchListener listener = GetOrAddComponect<TouchListener>(go);
        listener.onDrag = cb;
    }
    
    protected void SetActive(Image img, bool state = true) {
        img.transform.gameObject.SetActive(state);
    }
}
    
    

监听类:

/****************************************************
    文件:TouchListener.cs
	功能:UI事件监听插件
*****************************************************/

using System;
using UnityEngine;
using UnityEngine.EventSystems;

public class TouchListener : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler {
    /// <summary>
    /// 触摸区域宽度
    /// </summary>
    [Range(400, 800)] 
    public int touchAreaWidth = 600;
    /// <summary>
    /// 触摸区域高度
    /// </summary>
    [Range(330, 660)] 
    public int touchAreaHeight = 550;
    
    public Action<PointerEventData> onClickDown;
    public Action<PointerEventData> onClickUp;
    public Action<PointerEventData> onDrag;


    public void OnPointerDown(PointerEventData eventData) {
        if (onClickDown != null) {
            onClickDown(eventData);
        }
    }
    public void OnPointerUp(PointerEventData eventData) {
        if (onClickUp != null) {
            onClickUp(eventData);
        }
    }
    public void OnDrag(PointerEventData eventData) {
        if (onDrag != null) {
            onDrag(eventData);
        }
    }

    public void Awake()
    {
        RectTransform rt = gameObject.GetComponent<RectTransform>();
        rt.sizeDelta = new Vector2(touchAreaWidth,touchAreaHeight);
    }
}

动作控制类:

/****************************************************
    文件:PlayerController.cs
	功能:角色控制器
*****************************************************/

using System;
using UnityEngine;

public class PlayerController : MonoBehaviour {
    private Transform camTrans;
    private Vector3 camOffset;
    private CharacterController ctrl;
    private bool isMove = false;
    private Vector2 dir = Vector2.zero;

    private int MoveSpeed = 6;
    public Vector2 Dir {
        get {
            return dir;
        }

        set {
            if (value == Vector2.zero) {
                isMove = false;
            }
            else {
                isMove = true;
            }
            dir = value;
        }
    }

    private void Awake()
    {
        camTrans = Camera.main.transform;
        camOffset = transform.position - camTrans.position;
        ctrl = gameObject.GetComponent<CharacterController>();
    }

    private void Update() {
        #region Input
        /*
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");

        Vector2 _dir = new Vector2(h, v).normalized;
        if (_dir != Vector2.zero) {
            Dir = _dir;
            SetBlend(Constants.BlendWalk);
        }
        else {
            Dir = Vector2.zero;
            SetBlend(Constants.BlendIdle);
        }
        */
        #endregion

        if (isMove) {
            //设置方向
            SetDir();
            //产生移动
            SetMove();
            //相机跟随
            SetCam();
        }
    }

    private void SetDir() {
        float angle = Vector2.SignedAngle(Dir, new Vector2(0, 1)) + camTrans.eulerAngles.y;
        Vector3 eulerAngles = new Vector3(0, angle, 0);
        transform.localEulerAngles = eulerAngles;
    }

    private void SetMove() {
        ctrl.Move(transform.forward * Time.deltaTime * MoveSpeed);
    }

    private void SetCam() {
        if (camTrans != null) {
            camTrans.position = transform.position - camOffset;
        }
    }
}

Demo类:

/****************************************************
    文件:MyTouch.cs
	功能:触摸功能
*****************************************************/

using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class TouchDemo : BaseTouch
{
	
	private Image imgTouch;
	private Image imgDirBg;
	private Image imgDirPoint;
	
	private int ScreenStandardHeight = 1920;
	/// <summary>
	/// 触摸OPDis
	/// </summary>
	[Range(150, 500)] 
	public int ScreenOPDis = 300;
	

	private GameObject box;
	private void Awake()
	{
		imgTouch = GameObject.Find("2D/imgTouch").GetComponent<Image>();
		imgDirBg = GameObject.Find("2D/imgTouch/imgDirBg").GetComponent<Image>();
		imgDirPoint = GameObject.Find("2D/imgTouch/imgDirBg").GetComponent<Image>();
		box = GameObject.Find("/3D/box");
	}

	private PlayerController _controller; 
	private void Start()
	{
		pointDis = Screen.height * 1.0f / ScreenStandardHeight * ScreenOPDis;
		defaultPos = imgDirBg.transform.position;
		RegisterTouchEvents();
		_controller = box.GetComponent<PlayerController>();
	}

	private float pointDis;
	private Vector2 startPos = Vector2.zero;
	private Vector2 defaultPos = Vector2.zero;

	private void RegisterTouchEvents()
	{
		OnClickDown(imgTouch.gameObject, (PointerEventData evt) => {
			startPos = evt.position;
			SetActive(imgDirPoint,true);
			imgDirBg.transform.position = evt.position;
		});
		
		OnClickUp(imgTouch.gameObject, (PointerEventData evt) => {
			imgDirBg.transform.position = defaultPos;
			SetActive(imgDirPoint, false);
			imgDirPoint.transform.localPosition = Vector2.zero;
			
			_controller.Dir = Vector2.zero;
		});
		
		OnDrag(imgTouch.gameObject, (PointerEventData evt) => {
			Vector2 dir = evt.position - startPos;
			float len = dir.magnitude;
			if (len > pointDis) {
				Vector2 clampDir = Vector2.ClampMagnitude(dir, pointDis);
				imgDirPoint.transform.position = startPos + clampDir;
			}
			else {
				imgDirPoint.transform.position = evt.position;
			}
			
			_controller.Dir = dir.normalized;
		});
	}
}

4.效果展示

在这里插入图片描述

5.github

github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值