先找两张图,一个做摇杆背景图,一个做摇杆键,(绿色图为背景,红色为摇杆)
在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");
}
}