Unity-摇杆控制控制角色移动

创建摇杆

1:创建摇杆的点击区域
2:创建摇杆底座
3:创建摇杆的杆
4:书写摇杆逻辑

/*当前脚本挂载在摇杆活动区域*/
using UnityEngine;
using UnityEngine.EventSystems;

public class Rocker : MonoBehaviour, IPointerDownHandler,IPointerUpHandler,IBeginDragHandler,IDragHandler,IEndDragHandler {
    // 摇杆的底座,摇杆的棍子
    GameObject rockerBase,rockerStick;
    // 初始位置
    Vector2 initPos;    
    // 摇杆拖动限制范围
    float astrict;
    // 摇杆拖动后获得的向量
    public static Vector3 moveDirection;

    void Start() {
        // 获得摇杆底座
        rockerBase = GameObject.Find("RockerBase");
        // 获得摇杆的棍子
        rockerStick = GameObject.Find("Rocker");
        // 将摇杆的初始位置记录下来,用于拖动结束后还原初始位置
        initPos = rockerBase.GetComponent<RectTransform>().position;
        // 限制范围
        astrict = 80;
    }
    
    // 检测鼠标书否按下
    public void OnPointerDown(PointerEventData eventData) {
        // 设置摇杆的位置为当前鼠标点击的位置
        rockerBase.transform.position = eventData.position;
    }

    // 检测鼠标抬起
    public void OnPointerUp(PointerEventData eventData) {
        // 摇杆底座回到指定位置
        rockerBase.GetComponent<RectTransform>().position = initPos;
        // 摇杆回到指定位置
        rockerStick.GetComponent<RectTransform>().localPosition = Vector2.zero; 
    }

    // 开始拖动
    public void OnBeginDrag(PointerEventData eventData) {
        // 当前摇杆底座的位置
        Vector2 temp = rockerBase.GetComponent<RectTransform>().position;
        // 当前摇杆的相对位置
        rockerStick.GetComponent<RectTransform>().localPosition = Vector3.ClampMagnitude(eventData.position - temp, astrict);
        // 通过摇杆获得的移动方向
        moveDirection = (rockerStick.transform.position - rockerBase.transform.position).normalized;
    }

    // 拖动中
    public void OnDrag(PointerEventData eventData) {
        // 当前摇杆底座的位置
        Vector2 temp = rockerBase.GetComponent<RectTransform>().position;
        // 当前摇杆的相对位置
        rockerStick.GetComponent<RectTransform>().localPosition = Vector3.ClampMagnitude(eventData.position - temp, astrict);
        // 通过摇杆获得的移动方向
        moveDirection = (rockerStick.transform.position - rockerBase.transform.position).normalized;
    }

    // 结束拖动
    public void OnEndDrag(PointerEventData eventData) {        
        // 拖动结束还原摇杆位置
        rockerBase.GetComponent<RectTransform>().position = initPos;
        // 还原摇杆棍子的位置
        rockerStick.GetComponent<RectTransform>().localPosition = Vector2.zero;
        // 通过摇杆获得的移动方向
        moveDirection = Vector3.zero;
    }
}

拖动摇杆获得角色移动的向量

角色移动

1:将要移动的角色拖入场景
2:在游戏物体上添加CharacterController,用于控制角色移动
3:在游戏物体上添加Animator,控制角色动画的播放
4:创建一个动画控制器
5:将待机和跑步拖入新创建的动画控制器,并通过融合树将二者进行融合,并更改二者的跳转条件名称
6:代码逻辑

/*控制角色移动*/
using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    // 角色的CC控制器
    CharacterController cc;
    // 角色动画控制器
    Animator ani;
    // 角色移动速度
    float speed;
    // 角色旋转速度
    float rotationSpeed;
    void Start()
    {
        // 获得自身上的CC控制器组件
        cc = GetComponent<CharacterController>();
        // 获得自身动画控制器组件
        ani = GetComponent<Animator>();
        speed = 500;
        rotationSpeed = 50;
    }
    
    void Update()
        {
        // 将摇杆获得向量进行转换
        var dir = new Vector3(Rocker.moveDirection.x, 0, Rocker.moveDirection.y);
        // 角色动画控制
        ani.SetFloat("Speed", (dir*speed).magnitude);        
        // 防止键盘没有输出的时候模型突然转向到初始方向
        if (dir.x != 0 || dir.z != 0) {
            // 将相对坐标转换成世界空间下的坐标
            Vector3 worldSpaceDir = Camera.main.transform.TransformDirection(dir);
            // 将Y轴的向量屏蔽掉
            Vector3 realMoveDir = new Vector3(worldSpaceDir.x, 0, worldSpaceDir.z);
            // 将向量归一化,防止Y轴占比较大
            realMoveDir = realMoveDir.normalized;
            // 角色控制器的移动速度 
            cc.SimpleMove(realMoveDir * speed * Time.deltaTime);
            // 通过四元数的线性插值改变游戏物体的旋转,防止瞬间转向
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(realMoveDir), Time.deltaTime * rotationSpeed);
        }
    }
}

相机跟踪
1>代码逻辑

/*相机组件,用于相机跟踪角色,仅限于角色不会销毁*/
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    // 相机当角色的相对向量
    public Vector3 offset;
    // 角色位置组件
    public Transform target;

    void Start()
    {
        // 通过标签找到要追踪的游戏物体
        target = GameObject.FindGameObjectWithTag("Player").transform;
    }

    void Update()
    {
        // 设置相机位置
        transform.position = target.position + offset;
    }
}
posted @   坞中客  阅读(1351)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示