摇杆控制人物移动
- 一、UI搭建
- 二、3d模型搭建
- 三、脚本
- JoyStickBar.cs
- PlayerController.cs
- 工程在我资源里名字叫Joystickbar.unitypackage [连接](https://download.csdn.net/download/qq_42194657/12043019?spm=1001.2014.3001.5503)
一、UI搭建
JoyStickBar是图片背景
JoyStickPoint是图中心的拖拽物体
JoystickPointer是空物体为Image方向位移
Image是箭头
JoyStickRadiu是提供拖拽物体与背景图的距离,也就是背景图(大圆)的半径,将其位置移动到背景图的最左边缘
二、3d模型搭建
三、脚本
JoyStickBar.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class JoyStickBar : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler {
/// <summary>
/// 最大半径
/// </summary>
public float maxRadius;
/// <summary>
/// 计算中的半径
/// </summary>
public float radius;
/// <summary>
/// 原始位置
/// </summary>
private Vector2 originalPos;
/// <summary>
/// 遥杆中心位置
/// </summary>
public Transform joystickradius;
/// <summary>
/// 箭头指针方向
/// </summary>
public Transform joystickpointer;
#region 方向控制访问器
/// <summary>
/// 水平方向
/// </summary>
private float horizontal = 0;
/// <summary>
/// 垂直方向
/// </summary>
private float vertical = 0;
/// <summary>
/// 水平方向属性访问器
/// </summary>
public float Horizontal
{
get { return horizontal; }
}
/// <summary>
/// 垂直方向属性访问器
/// </summary>
public float Vertical
{
get { return vertical; }
}
#endregion
private void Start()
{
if (!joystickradius) return;
originalPos = transform.position;
maxRadius = - joystickradius.localPosition.x;
ShowPointer(false);
}
#region 方向受力
/// <summary>
/// 各个方向上的受力
/// </summary>
private void DirPotency()
{
horizontal = transform.localPosition.x;
vertical = transform.localPosition.y;
}
#endregion
#region 继承接口事件逻辑处理
/// <summary>
/// 开始拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnBeginDrag(PointerEventData eventData)
{
ShowPointer(true);
}
/// <summary>
/// 拖拽中
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData)
{
//偏移量
Vector2 dir = eventData.position - originalPos;
//Vector2 dir = new Vector2 (Input.mousePosition.x, Input.mousePosition.y) - originalPos;
//获取向量长度
float distance = Vector3.Magnitude(dir);
//获取当前
radius = Mathf.Clamp(distance,0,maxRadius);
//位置赋值
transform.position = dir.normalized * radius + originalPos;
//方向受力度量
DirPotency();
//角度转换
CalculateAngle(dir.normalized);
}
/// <summary>
/// 结束拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData)
{
transform.position = originalPos;
//当前半径
radius = 0;
//方向受力度量
DirPotency();
ShowPointer(false);
}
#endregion
#region 指针逻辑
/// <summary>
/// 角度转换
/// </summary>
public void CalculateAngle(Vector2 dir)
{
if (!joystickpointer) return;
float dot = Vector2.Dot(Vector2.up, dir);
float angle = Vector2.Angle(Vector2.up,dir);
joystickpointer.rotation = Quaternion.Euler(new Vector3(0, 0, -(dir.x>0?angle:-angle)));
}
/// <summary>
/// 显示隐藏指针
/// </summary>
/// <param name="isshow"></param>
public void ShowPointer(bool isshow)
{
joystickpointer.gameObject.SetActive(isshow);
}
#endregion
}
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
/// <summary>
/// 摇杆
/// </summary>
public JoyStickBar joy;
/// <summary>
/// 旋转速度
/// </summary>
public float rotatespeed = 10f;
/// <summary>
/// 移动速度
/// </summary>
public float moveSpeed = 5f;
// Update is called once per frame
void Update () {
float hor = joy.Horizontal;
float ver = joy.Vertical;
Vector3 dir = new Vector3(hor,0,ver);
if (dir != Vector3.zero)
{
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * rotatespeed);
transform.Translate(Vector3.right * Time.deltaTime * moveSpeed * (joy.radius / joy.maxRadius));
}
}
}