虚拟摇杆制作

本文介绍如何使用Unity创建一个响应式的虚拟摇杆控制系统,包括摇杆的UI搭建、交互逻辑编写及角色控制代码。该系统支持触摸开始、移动和结束等事件,并能够根据触摸位置调整角色的方向与速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先找两张图,一个做摇杆背景图,一个做摇杆键,(绿色图为背景,红色为摇杆)


在unity中建立空物体和两个UI》image,将两个image存在空物体下,成为子物体。

(红摇杆image的位置要和空物体一样)

开始放代码(1.代码挂给摇杆)

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

usingUnityEngine.EventSystems;

 

public class JoyStick :MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler

{

    /// <summary>

    /// 摇杆最大半径

    /// 以像素为单位

    /// </summary>

    public float JoyStickRadius = 50;

    /// <summary>

    /// 摇杆重置所诉

    /// </summary>

    public float JoyStickResetSpeed = 3.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 voidJoyStickTouchBegin(Vector2 vec);

    /// <summary>

    /// 定义触摸过程事件委托

    /// </summary>

    /// <param name="vec">虚拟摇杆的移动方向</param>

    public delegate voidJoyStickTouchMove(Vector2 vec);

    /// <summary>

    /// 定义触摸结束事件委托

    /// </summary>

    public delegate void JoyStickTouchEnd();

    /// <summary>

    /// 注册触摸开始事件

    /// </summary>

    public event JoyStickTouchBeginOnJoyStickTouchBegin;

    /// <summary>

    /// 注册触摸过程事件

    /// </summary>

    public event JoyStickTouchMoveOnJoyStickTouchMove;

    /// <summary>

    /// 注册触摸结束事件

    /// </summary>

    public event JoyStickTouchEndOnJoyStickTouchEnd;

    void Start()

    {

        //初始化虚拟摇杆的默认方向

        selfTransform =this.GetComponent<RectTransform>();

        originPosition =selfTransform.anchoredPosition;

    }

    public void OnPointerDown(PointerEventDataeventData)

    {

        isTouched = true;

        touchedAxis =GetJoyStickAxis(eventData);

        if (this.OnJoyStickTouchBegin != null)

           this.OnJoyStickTouchBegin(TouchedAxis);

    }

    public void OnPointerUp(PointerEventDataeventData)

    {

        isTouched = false;

        selfTransform.anchoredPosition =originPosition;

        touchedAxis = Vector2.zero;

        if (this.OnJoyStickTouchEnd != null)

            this.OnJoyStickTouchEnd();

    }

    public void OnDrag(PointerEventDataeventData)

    {

        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 stickaxis.</returns>

    /// <paramname="eventData">Event data.</param>

    private Vector2GetJoyStickAxis(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;

    }

}

 

放代码(2.代码挂给要被摇杆控制的物体)

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);

       //animation.CrossFade("Run");

       transform.GetComponent<Animation>().CrossFade("Run");

    }

    void OnJoyStickEnd()

    {

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

        //播放默认待机动画

        //animation.CrossFade("Walk");

       transform.GetComponent<Animation>().CrossFade("Bind Pose");

    }

   

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值