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