虚拟摇杆实现移动

一.首先点击UI创建两个Image,将Image的Source Image改成自己想要的Texture即可,然后在Canvas下创建一空物体,将两个Image放在空物体下作为他的子对象;

然后为可以拖动的Image编写脚本,脚本如下:(有注释,就不多说了)

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

public class JoyStick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler//需要注意继承的接口,接口内的方法需要实现
{

/// <summary>
/// 摇杆最大半径
/// 以像素为单位
/// </summary>
public float JoyStickRadius = 50;

/// <summary>
/// 摇杆重置所诉
/// </summary>
public float JoyStickResetSpeed = 5.0f;

/// <summary>
/// 当前物体的Transform组件
/// </summary>
private RectTransform selfTransform;

/// <summary>
/// 是否触摸了虚拟摇杆
/// </summary>
private bool isTouched = false;

/// <summary>
/// 虚拟摇杆的默认位置
/// </summary>
private Vector2 originPosition;

/// <summary>
/// 虚拟摇杆的移动方向
/// </summary>
private Vector2 touchedAxis;
public Vector2 TouchedAxis
{
    get
    {
        if (touchedAxis.magnitude < JoyStickRadius)
            return touchedAxis.normalized / JoyStickRadius;
        return touchedAxis.normalized;
    }
}

/// <summary>
/// 定义触摸开始事件委托 
/// </summary>
public delegate void JoyStickTouchBegin(Vector2 vec);

/// <summary>
/// 定义触摸过程事件委托 
/// </summary>
/// <param name="vec">虚拟摇杆的移动方向</param>
public delegate void JoyStickTouchMove(Vector2 vec);

/// <summary>
/// 定义触摸结束事件委托
/// </summary>
public delegate void JoyStickTouchEnd();

/// <summary>
/// 注册触摸开始事件
/// </summary>
public event JoyStickTouchBegin OnJoyStickTouchBegin;

/// <summary>
/// 注册触摸过程事件
/// </summary>
public event JoyStickTouchMove OnJoyStickTouchMove;

/// <summary>
/// 注册触摸结束事件
/// </summary>
public event JoyStickTouchEnd OnJoyStickTouchEnd;

void Start()
{
    //初始化虚拟摇杆的默认方向
    selfTransform = this.GetComponent<RectTransform>();
    originPosition = selfTransform.anchoredPosition;
}


public void OnPointerDown(PointerEventData eventData)
{
    isTouched = true;
    touchedAxis = GetJoyStickAxis(eventData);
    if (this.OnJoyStickTouchBegin != null)
        this.OnJoyStickTouchBegin(TouchedAxis);
}

public void OnPointerUp(PointerEventData eventData)
{
    isTouched = false;
    selfTransform.anchoredPosition = originPosition;
    touchedAxis = Vector2.zero;
    if (this.OnJoyStickTouchEnd != null)
        this.OnJoyStickTouchEnd();
}

public void OnDrag(PointerEventData eventData)
{
    touchedAxis = GetJoyStickAxis(eventData);
    if (this.OnJoyStickTouchMove != null)
        this.OnJoyStickTouchMove(TouchedAxis);
}


void Update()
{
    //当虚拟摇杆移动到最大半径时摇杆无法拖动
    //为了确保被控制物体可以继续移动
    //在这里手动触发OnJoyStickTouchMove事件
    if (isTouched && touchedAxis.magnitude >= JoyStickRadius)
    {
        if (this.OnJoyStickTouchMove != null)
            this.OnJoyStickTouchMove(TouchedAxis);
    }

    //松开虚拟摇杆后让虚拟摇杆回到默认位置
    if (selfTransform.anchoredPosition.magnitude > originPosition.magnitude)
        selfTransform.anchoredPosition -= TouchedAxis * Time.deltaTime * JoyStickResetSpeed;
}

/// <summary>
/// 返回虚拟摇杆的偏移量
/// </summary>
/// <returns>The joy stick axis.</returns>
/// <param name="eventData">Event data.</param>
private Vector2 GetJoyStickAxis(PointerEventData eventData)
{
    //获取手指位置的世界坐标
    Vector3 worldPosition;
    if (RectTransformUtility.ScreenPointToWorldPointInRectangle(selfTransform,
             eventData.position, eventData.pressEventCamera, out worldPosition))
        selfTransform.position = worldPosition;
    //获取摇杆的偏移量
    Vector2 touchAxis = selfTransform.anchoredPosition - originPosition;
    //摇杆偏移量限制
    if (touchAxis.magnitude >= JoyStickRadius)
    {
        touchAxis = touchAxis.normalized * JoyStickRadius;
        selfTransform.anchoredPosition = touchAxis;
    }
    return touchAxis;
}

}
二.接下来,就是拖拽p_w_picpath使物体能够移动了;

为该物体添加脚本:
using UnityEngine;
using System.Collections;

public class JoyStick3D : MonoBehaviour
{

private JoyStick js;

void Start()
{
    js = GameObject.FindObjectOfType<JoyStick>();
    js.OnJoyStickTouchBegin += OnJoyStickBegin;
    js.OnJoyStickTouchMove += OnJoyStickMove;
    js.OnJoyStickTouchEnd += OnJoyStickEnd;
}


void OnJoyStickBegin(Vector2 vec)
{
    Debug.Log("开始触摸虚拟摇杆");
}

void OnJoyStickMove(Vector2 vec)
{
    Debug.Log("正在移动虚拟摇杆");

    //设置角色朝向
    Quaternion q = Quaternion.LookRotation(new Vector3(vec.x, 0, vec.y));
    transform.rotation = q;

    //移动角色
    transform.Translate(Vector3.forward * 75f * Time.deltaTime);
}

void OnJoyStickEnd()
{
    Debug.Log("触摸移动摇杆结束");

 
}

void OnGUI()
{
    GUI.Label(new Rect(30, 30, 200, 30), "3D模式下的虚拟摇杆测试");
}

}
三.接着可以试着运行,可以看到物体可以随着p_w_picpath的拖动而移动,但是有不好的地方,就是拖拽的p_w_picpath超过半径所设置的半径JoyStickRadius时,p_w_picpath的位置就会固定在一个位置不动,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值