unity 第三人称人物移动(包含摇杆移动)

简单记录一下之前做的人物移动,包括摇杆和键盘的切换

首先是摇杆的代码,单例类代码就不贴了,随便写个单例就行,界面长这样,注意JoyStickerBG的设置一定要和图片上一样,如果出问题的话大概就是布局和锚点(pivot)的问题,JoySticker脚本挂在sticker上就行,设置一下limit的长度,一般是父物体长宽的一半

 

 

using UnityEngine;
using UnityEngine.EventSystems;
public class JoySticker : MonoSingleton<JoySticker>, IDragHandler, IBeginDragHandler, IEndDragHandler
{
    /// <summary>
    /// 限制摇杆的移动范围
    /// </summary>
    public float limit;
    /// <summary>
    /// 摇杆所在位置的向量
    /// </summary>
    public Vector2 dir;
    /// <summary>
    /// 摇杆向量的模
    /// </summary>
    public float mo;

    public RectTransform rect;
    public RectTransform parentRect;

    protected override void Awake()
    {
        base.Awake();
        rect = transform.GetComponent<RectTransform>();
        parentRect = transform.parent.GetComponent<RectTransform>();
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        LimitSticker(eventData);
    }

    public void OnDrag(PointerEventData eventData)
    {
        LimitSticker(eventData);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        //松开摇杆时重置摇杆的位置
        rect.anchoredPosition = Vector3.zero;
        Debug.Log("OnEndDrag " + rect.anchoredPosition);
        dir = Vector2.zero;
        mo = 0;
    }

    public void LimitSticker(PointerEventData eventData)
    {
        //鼠标位置减去摇杆父物体的位置,这里一定要用RectTransform的anchoredPosition,不然canvas的renderMode会影响效果
        //得到摇杆相对于自身anchoredPosition的零点的位置(这一步是最重要的也是最坑的)
        //eventData.position - parentRect.anchoredPosition 这两个相减就是摇杆的位置,如果点到摇杆的中心的话这个值应该接近0
        Vector3 offset = eventData.position - parentRect.anchoredPosition;
        Debug.Log(parentRect.anchoredPosition);
        //对摇杆的localPosition进行限制,限制摇杆的位置向量长度
        rect.anchoredPosition = Vector3.ClampMagnitude(offset, limit);
        //设置摇杆的向量
        dir = transform.localPosition / limit;
        mo = dir.magnitude;
    }
}

然后是人物移动的代码

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    /// <summary>
    /// 移动速度
    /// </summary>
    public float moveSpeed = 1;
    /// <summary>
    /// 摇杆移动死区
    /// </summary>
    public float moveDeathAre = 0.2f;
    /// <summary>
    /// 旋转速度
    /// </summary>
    public float rotateSpeed = 5;
    /// <summary>
    /// 动画组件
    /// </summary>
    Animator ani;
    /// <summary>
    /// 是否为摇杆移动
    /// </summary>
    public bool isJoySticker;
    /// <summary>
    /// 移动的方向
    /// </summary>
    Vector3 dir;
    /// <summary>
    /// 摄像机自身的方向
    /// </summary>
    Vector3 cameraRealDir;
    /// <summary>
    /// 真实的摄像机方向(去除角度影响)
    /// </summary>
    Vector3 realDir;

    public CharacterController cc;
    void Start()
    {
        ani = GetComponent<Animator>();
        cc = GetComponent<CharacterController>();
    }
    void Update()
    {
        MoveType();
    }
    
    /// <summary>
    /// 选择操作类型进行移动
    /// </summary>
    public void MoveType()
    {
        //如果不是摇杆移动,则通过键盘输入的值移动
        if (!isJoySticker)
        {
            dir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            Move(dir.x, dir.z, dir.magnitude);
        }
        else
        {
            Move(JoySticker.Instance.dir.x, JoySticker.Instance.dir.y, JoySticker.Instance.mo);
        }
        if (dir.x != 0 || dir.z != 0)
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(realDir), Time.deltaTime * rotateSpeed);
        }
    }

    /// <summary>
    /// 控制移动的方法
    /// </summary>
    /// <param name="dirX"></param>
    /// <param name="dirY"></param>
    /// <param name="mo"></param>
    public void Move(float dirX, float dirY, float mo) 
    {
        dir = new Vector3(dirX, 0, dirY);
        cameraRealDir = Camera.main.transform.TransformDirection(dir);
        realDir = new Vector3(cameraRealDir.x, 0, cameraRealDir.z).normalized;
        if (mo >= moveDeathAre)
        {
            cc.SimpleMove(realDir * moveSpeed * Time.deltaTime * mo);
            ani.SetFloat("isWalk", mo);
        }
        else
        {
            ani.SetFloat("isWalk", 0);
        }
    }
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值