摇杆控制人物移动
- 一、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));
        }
    }
}



















