首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Unity3D控制人物移动的多种方法

Unity3D控制人物移动的多种方法

作者头像
心疼你的一切
发布2026-01-20 14:16:17
发布2026-01-20 14:16:17
1780
举报
文章被收录于专栏:人工智能人工智能

👉前言

人物移动代码综合记录一下(因为有很多种).所以简单记录一下 大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 欢迎点赞评论哦. 下面就让我们进入正文吧 !

👉一、人物移动之键盘移动

所谓键盘移动就是我们常玩游戏的操作 wasd来进行移动

👉1-1、代码如下

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerToKeyPad : MonoBehaviour
{
    public GameObject Player;
    public float m_speed = 5f;

    void Update()
    {
        //键盘控制移动 两种方法
        PlayerMove_KeyPad_1();
        PlayerMove_KeyPad_2();
    }

    //通过Transform组件 键盘控制移动
    public void PlayerMove_KeyPad_1()
    {
        if (Input.GetKey(KeyCode.W) | Input.GetKey(KeyCode.UpArrow)) //前
        {
            Player.transform.Translate(Vector3.forward * m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.S) | Input.GetKey(KeyCode.DownArrow)) //后
        {
            Player.transform.Translate(Vector3.forward * -m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.A) | Input.GetKey(KeyCode.LeftArrow)) //左
        {
            Player.transform.Translate(Vector3.right * -m_speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.D) | Input.GetKey(KeyCode.RightArrow)) //右
        {
            Player.transform.Translate(Vector3.right * m_speed * Time.deltaTime);
        }
    }

    public void PlayerMove_KeyPad_2()
    {
        float horizontal = Input.GetAxis("Horizontal"); //A D 左右
        float vertical = Input.GetAxis("Vertical"); //W S 上 下

        Player.transform.Translate(Vector3.forward * vertical * m_speed * Time.deltaTime);//W S 上 下
        Player.transform.Translate(Vector3.right * horizontal * m_speed * Time.deltaTime);//A D 左右
    }
}

注意事项

  1. 简单但局限性大:不推荐用于复杂物理场景,容易导致碰撞抖动或穿模67。
  2. 帧率依赖:必须乘以Time.deltaTime,否则移动速度会受帧率影响26。
  3. 无物理交互:无法与物理引擎(如重力、刚体)自然交互,需手动实现逻辑7。

👉1-2、效果

人物移动之键盘控制效果

👉二、人物移动之跟随鼠标点击移动

👉2-1、代码如下

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerToMouse : MonoBehaviour
{
    public GameObject Player;
    Vector3 tempPoint = new Vector3(0, 0, 0);

    void Update()
    {
        PlayerMove_FollowMouse();
    }

    //角色移动到鼠标点击的位置
    public void PlayerMove_FollowMouse()
    {

        //右键点击
        if (Input.GetMouseButtonDown(1))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo))
            {
                tempPoint = new Vector3 ( hitInfo.point.x, hitInfo.point.y+0.5f, hitInfo.point.z);
            }
        }
        float step = 10 * Time.deltaTime;
        Player.transform.localPosition = Vector3.MoveTowards(Player.transform.localPosition, tempPoint, step);
        Player.transform.LookAt(tempPoint);
    }
}

👉2-2、效果

人物移动之跟随鼠标点击移动

👉三、人物移动之刚体移动

里面包含两个方法一个是:Velocity移动 一个是:AddForce移动

👉3-1、代码如下

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerToRigidbody : MonoBehaviour
{
    public GameObject Player;
    public float m_speed = 5f;
    void Update()
    {
        //PlayerMove_KeyRighidbody1();
        PlayerMove_KeyRighidbody2();
    }

    //通过Rigidbody组件 键盘控制移动 Velocity移动 角色身上需要挂载Rigidbody组件
    public void PlayerMove_KeyRighidbody1()
    {
        float horizontal = Input.GetAxis("Horizontal"); //A D 左右
        float vertical = Input.GetAxis("Vertical"); //W S 上 下
        //这个必须分开判断 因为一个物体的速度只有一个
        if (Input.GetKey(KeyCode.W) | Input.GetKey(KeyCode.S))
        {
            Player.GetComponent<Rigidbody>().velocity = Vector3.forward * vertical * m_speed;
        }
        if (Input.GetKey(KeyCode.A) | Input.GetKey(KeyCode.D))
        {
            Player.GetComponent<Rigidbody>().velocity = Vector3.right * horizontal * m_speed;
        }
    }
    //通过Rigidbody组件 键盘控制移动 AddForce移动 角色身上需要挂载Rigidbody组件
    public void PlayerMove_KeyRighidbody2()
    {
        float horizontal = Input.GetAxis("Horizontal"); //A D 左右
        float vertical = Input.GetAxis("Vertical"); //W S 上 下

        Player.GetComponent<Rigidbody>().AddForce(Vector3.forward * vertical * m_speed);
        Player.GetComponent<Rigidbody>().AddForce(Vector3.right * horizontal * m_speed);
    }

}

注意事项

  1. 帧率同步:物理操作需在FixedUpdate()中执行,确保与物理引擎的固定时间步长同步。
  2. 冻结旋转:避免角色因碰撞意外翻转,需勾选Rigidbody的Freeze Rotation。
  3. 性能与穿透:高速度下可能出现穿透障碍物问题,可通过调整碰撞检测模式(如Continuous)缓解

👉3-2、效果

人物移动之刚体移动

人物移动之刚体添加力移动

👉四、人物移动之第一人称控制器移动

里面包含两个方法一个是:SimpleMove控制移动 一个是:Move控制移动

👉4-1、代码如下

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerToCharacterController : MonoBehaviour
{
    public GameObject Player;
    public float m_speed = 5f;
    void Update()
    {
        //PlayerMove_KeyCharacterController1();
        PlayerMove_KeyCharacterController2();
    }

    //通过CharacterController组件 键盘移动物体 SimpleMove控制移动
    public void PlayerMove_KeyCharacterController1()
    {
        float horizontal = Input.GetAxis("Horizontal"); //A D 左右
        float vertical = Input.GetAxis("Vertical"); //W S 上 下
        if (horizontal !=0&&vertical ==0)
        {
            Player.GetComponent<CharacterController>().SimpleMove(transform.right * horizontal * m_speed);
        }
        else if (horizontal == 0 && vertical != 0)
        {
            Player.GetComponent<CharacterController>().SimpleMove(transform.forward * vertical * m_speed);
        }
        else
        {
            //斜着走 例如w a一起按
            Player.GetComponent<CharacterController>().SimpleMove(transform.forward * vertical * m_speed);
            Player.GetComponent<CharacterController>().SimpleMove(transform.right * horizontal * m_speed);
        }
      
       
    }
    //通过CharacterController组件 键盘移动物体 Move控制移动
    public void PlayerMove_KeyCharacterController2()
    {
        float horizontal = Input.GetAxis("Horizontal"); //A D 左右
        float vertical = Input.GetAxis("Vertical"); //W S 上 下
        float moveY = 0;
        float m_gravity = 10f;
        moveY -= m_gravity * Time.deltaTime;//重力
        Player.GetComponent<CharacterController>().Move(new Vector3(horizontal, moveY, vertical) * m_speed * Time.deltaTime);
    }


}

注意事项

  1. 重力模拟:需手动添加重力,如moveDir.y -= gravity * Time.deltaTime,并通过isGrounded检测地面状态,防止角色悬空。
  2. 碰撞处理:虽能处理简单地形(如楼梯),但需通过OnControllerColliderHit手动处理复杂碰撞响应。
  3. 帧率问题:建议在Update()中处理输入,在FixedUpdate()中执行移动,避免抖动。

👉4-2、效果

人物移动之第一人称控制器移动

👉五、Android触摸手势操作脚本(单指 双指 三指)

相机设置如下

在这里插入图片描述
在这里插入图片描述

单指移动,双指缩放 , 三指旋转 移动和旋转动的是Pivot 缩放动的是Main Camera的Z轴距离

👉5-1、代码如下

代码语言:javascript
复制
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TouchMove : MonoBehaviour
{
    public Camera cameraMainTrans;
    public Transform rotTransform;
    private float zoomSpeed = 0.1f;
    private float rotateSpeed = 0.5f;
    private float moveSpeed = 0.1f;
    private Vector2 prevPos1, prevPos2,prevPos3;
    private float prevDistance;

    void Update()
    {
        // 处理单指触摸平移
        if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
        {
            Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;

            float tranY = touchDeltaPosition.y * (float)Math.Sin(Math.Round(this.transform.localRotation.eulerAngles.x, 2) * Math.PI / 180.0);
            float tranZ = touchDeltaPosition.y * (float)Math.Cos(Math.Round(this.transform.localRotation.eulerAngles.x, 2) * Math.PI / 180.0);
            rotTransform.Translate(new Vector3(touchDeltaPosition.x, tranY, tranZ) * moveSpeed, Space.Self);
            Debug.Log(touchDeltaPosition.x + "单指横向+纵向+" + touchDeltaPosition.y);


        }

        // 处理双指触摸缩放
        if (Input.touchCount == 2)
        {
            Touch touch1 = Input.GetTouch(0);
            Touch touch2 = Input.GetTouch(1);

            // 获取距离和位置的差异
            Vector2 curPos1 = touch1.position;
            Vector2 curPos2 = touch2.position;
            float curDistance = Vector2.Distance(curPos1, curPos2);

            if (touch2.phase == TouchPhase.Began)
            {
                prevPos1 = curPos1;
                prevPos2 = curPos2;
                prevDistance = curDistance;
            }

            // 缩放摄像机
            float deltaDistance = curDistance - prevDistance;
            cameraMainTrans.transform.Translate(Vector3.back * -deltaDistance * 0.1f);

            // 更新变量
            prevPos1 = curPos1;
            prevPos2 = curPos2;
            prevDistance = curDistance;
        }

        // 处理三指触摸旋转
        if (Input.touchCount == 3)
        {
            Touch touch1 = Input.GetTouch(0);
            Touch touch2 = Input.GetTouch(1);
            Touch touch3 = Input.GetTouch(2);

            // 获取触摸位置的差异
            Vector2 curPos1 = touch1.position;
            Vector2 curPos2 = touch2.position;
            Vector2 curPos3 = touch3.position;
            Vector2 deltaPos1 = curPos1 - prevPos1;
            Vector2 deltaPos2 = curPos2 - prevPos2;
            Vector2 deltaPos3 = curPos3 - prevPos3;

            if (touch2.phase == TouchPhase.Moved)
            {
                // 计算横向旋转
                float horizontalRotation = deltaPos1.x * rotateSpeed;
                rotTransform.Rotate(Vector3.up, horizontalRotation);

                // 计算纵向旋转
                float verticalRotation = -deltaPos1.y * rotateSpeed;
                Vector3 verticalRotationAxis = rotTransform.TransformVector(Vector3.left);
                rotTransform.RotateAround(rotTransform.position, verticalRotationAxis, verticalRotation);
            }

            // 更新变量
            prevPos1 = curPos1;
            prevPos2 = curPos2;
            prevPos3 = curPos3;
        }
        else if (Input.touchCount == 0)
        {
            // 清除前一帧的触摸位置
            prevPos1 = Vector2.zero;
            prevPos2 = Vector2.zero;
            prevPos3 = Vector2.zero;
        }
    }
    
    private static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }
}

通用注意事项

  1. 坐标系与轴方向:Unity中默认X轴为左右,Z轴为前后,Y轴为垂直方向。需根据摄像机视角调整移动方向(如将输入向量转换为角色或摄像机的相对方向)。
  2. 输入映射:确保在Unity的Input Manager中正确设置Horizontal和Vertical轴的按键映射。
  3. 性能优化:避免在每帧频繁调用GetComponent<>(),应在Awake()或Start()中缓存组件引用

👉总结

不定时更新Unity开发技巧,觉得有用记得一键三连哦。 防止后面忘记,所以记录一下 如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢 你的点赞就是对博主的支持,有问题记得留言评论哦! 不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 👉前言
  • 👉一、人物移动之键盘移动
    • 👉1-1、代码如下
    • 👉1-2、效果
  • 👉二、人物移动之跟随鼠标点击移动
    • 👉2-1、代码如下
    • 👉2-2、效果
  • 👉三、人物移动之刚体移动
    • 👉3-1、代码如下
    • 👉3-2、效果
  • 👉四、人物移动之第一人称控制器移动
    • 👉4-1、代码如下
    • 👉4-2、效果
  • 👉五、Android触摸手势操作脚本(单指 双指 三指)
    • 👉5-1、代码如下
  • 👉总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档