设置开发编辑器 :
以下是一个简化版的移动控制代码,不依赖自定义输入配置,直接使用 Unity 新输入系统的默认绑定,并兼容手机端的 Joystick Pack 虚拟摇杆:
SimplePlayerMovement
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Rigidbody2D))]
public class SimplePlayerMovement : MonoBehaviour
{
[Header("移动设置")]
public float moveSpeed = 5f;
public bool allowDiagonal = true;
[Header("虚拟摇杆设置 (Joystick Pack)")]
public VariableJoystick variableJoystick; // 拖入Joystick Pack的摇杆
private Rigidbody2D rb;
private Vector2 movement;
// 输入动作
private InputAction moveAction;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
// 初始化默认输入动作(无需自定义配置)
var inputActionMap = new InputActionMap("Player");
moveAction = inputActionMap.AddAction("Move",
InputActionType.Value, "<Gamepad>/leftStick",
null, null, "<Keyboard>/a,<Keyboard>/d,<Keyboard>/w,<Keyboard>/s,<Keyboard>/leftArrow,<Keyboard>/rightArrow,<Keyboard>/upArrow,<Keyboard>/downArrow");
inputActionMap.Enable();
}
void Update()
{
// 优先使用虚拟摇杆输入(手机端)
if (variableJoystick != null)
{
movement = variableJoystick.Direction;
}
// 否则使用键盘/手柄输入(PC端)
else
{
movement = moveAction.ReadValue<Vector2>();
}
// 处理斜向移动限制
if (!allowDiagonal && movement.sqrMagnitude > 0)
{
if (Mathf.Abs(movement.x) > Mathf.Abs(movement.y))
movement.y = 0;
else
movement.x = 0;
}
}
void FixedUpdate()
{
// 应用移动
rb.velocity = movement * moveSpeed;
}
}
以下是一个简化版的移动控制代码,不依赖自定义输入配置,直接使用Unity新输入系统的默认绑定,并兼容手机端的Joystick Pack虚拟摇杆:
### 使用说明#### 1. 准备工作
- 确保已安装 **Joystick Pack**(可在Unity Asset Store免费获取)地址Virtual Joystick Pack | Utilities Tools | Unity Asset Store
- 确保已安装 **Input System** 包(Window > Package Manager)
搜索全包名进行安装 com.unity.inputsystem
安装完成后 重启unity 会自动 却换喂最新的Input Actions 系统
如果如果没有切换到最新系统请配置以下选项
安装好先导入
#### 2. 手机端设置(使用Joystick Pack)
1. 创建UI摇杆:
- 从Joystick Pack的Prefabs中拖拽一个`Variable Joystick`到Canvas
- 调整位置(建议左下角)和大小
- 确保Canvas有`EventSystem`(没有的话会自动创建)
下面的设置摇杆会在手机触摸的位置出现 手指触摸到哪里,摇杆就会出现到哪里
2. 关联脚本:
- 将`SimplePlayerMovement`脚本添加到角色
- 在Inspector中将创建的`Variable Joystick`拖入脚本的`variableJoystick`参数框
#### 3. PC端设置(无需额外配置)
- 直接运行即可使用:
- WASD键或方向键控制上下左右
- 手柄左摇杆也可直接使用
#### 4. 关键特性
- 无需自定义Input Actions配置文件,代码内置默认输入绑定
- 自动优先使用虚拟摇杆输入(手机端),没有摇杆时自动切换到键盘输入(PC端)
- 可通过`allowDiagonal`开关控制是否允许斜向移动
- 适用于2D项目,自动添加Rigidbody2D组件
这种方式部署简单,无需处理复杂的输入配置,只需关联Joystick Pack的虚拟摇杆即可在手机端使用,PC端则自动支持键盘和手柄输入。
在Unity中打包项目,即将项目构建为可在目标平台运行的可执行文件或安装包,不同平台的打包步骤略有差异,以下是常见平台的打包流程:
### 一、Windows平台打包
1. **准备工作**
确保项目已经完成测试,没有明显的错误和异常。同时,关闭不必要的后台程序,以保证打包过程的顺利进行。
2. **打开Build Settings窗口**
点击菜单栏中的`File` -> `Build Settings`,打开构建设置窗口。
3. **选择目标平台**
在“Platform”列表中,选择`PC, Mac & Linux Standalone`,然后点击`Switch Platform` 按钮,Unity会自动切换项目的平台设置(如果是首次切换,可能需要一些时间来导入相关资源和配置)。
4. **设置打包选项**
- **Player Settings**:点击`Player Settings`按钮,进入播放器设置界面。在这里可以设置游戏的图标(`Icon`)、名称(`Product Name`)、版本号(`Version`)、分辨率、图形质量等各种参数。
- **Build Options**:在Build Settings窗口中,还可以设置其他构建选项,比如`Development Build`(开发构建,会包含调试信息,方便测试)、`Autoconnect Profiler`(自动连接性能分析器)等。如果是正式发布,一般不勾选`Development Build`。
5. **选择输出路径**
点击`Build`按钮(如果想直接构建并运行,点击`Build And Run`),在弹出的文件浏览器中,选择一个文件夹来存放打包后的文件。
6. **开始打包**
确认输出路径后,点击`Save`,Unity就会开始打包项目。打包时间取决于项目的大小和复杂程度,完成后,在指定的输出路径下会生成可执行文件(`.exe`)以及相关的资源文件夹。### 二、Android平台打包
1. **安装必要的软件和组件**
- **JDK**:确保已经安装Java Development Kit,并且配置好环境变量。
- **Android SDK**:安装Android Software Development Kit,并在Unity中配置好SDK路径(`Edit` -> `Preferences` -> `External Tools`,设置`Android SDK`路径)。
- **NDK**:下载并配置好Android NDK,同样在`External Tools`中设置`Android NDK`路径。
2. **打开Build Settings窗口**
和Windows平台一样,点击`File` -> `Build Settings`打开构建设置窗口。
3. **选择目标平台**
在“Platform”列表中选择`Android`,然后点击`Switch Platform` 按钮。
4. **设置打包选项**
- **Player Settings**:进入播放器设置界面,设置游戏图标、名称、版本号等基本信息。此外,还需要设置`Package Name`(包名,格式通常为`com.公司名.游戏名`,是应用在Android系统中的唯一标识)、`Minimum API Level`(最低支持的Android API版本)等参数。
- **Other Settings**:在这部分可以设置屏幕方向(`Orientation`)、图形API(一般选择`OpenGLES3`)等。
- **Publishing Settings**:点击`Publishing Settings`,配置Keystore(用于签名应用,发布到应用商店必须进行签名),可以选择创建新的Keystore或者使用已有的。
5. **选择输出路径**
点击`Build`按钮(或`Build And Run`),在弹出的文件浏览器中选择存放APK文件的路径。
6. **开始打包**
确认路径后,点击`Save`,Unity会开始构建Android项目,完成后会生成APK文件(如果选择了`Build And Run`,会自动安装并运行在连接的Android设备或模拟器上)。### 三、iOS平台打包
1. **安装必要的软件和组件**
- **Mac电脑**:iOS打包必须在Mac电脑上进行,并且安装了最新版本的Xcode。
- **配置证书和描述文件**:在Apple Developer网站上创建并下载开发者证书、描述文件等,然后在Xcode中进行配置。
2. **打开Build Settings窗口**
点击`File` -> `Build Settings`。
3. **选择目标平台**
在“Platform”列表中选择`iOS`,点击`Switch Platform` 按钮。
4. **设置打包选项**
- **Player Settings**:设置游戏图标、名称、版本号等,`Bundle Identifier`(包标识符,类似于Android的包名,是iOS应用的唯一标识)等参数必须正确设置。
- **Other Settings**:设置屏幕方向、图形API等。
- **Publishing Settings**:在这配置签名相关设置,选择之前创建和配置好的证书和描述文件。
5. **选择输出路径**
点击`Build`按钮,选择一个文件夹来存放打包后的Xcode项目文件。
6. **后续处理**
Unity打包完成后会生成一个Xcode项目,打开该项目,在Xcode中进行一些最后的设置和检查,然后使用Xcode的`Archive`功能来生成最终的IPA文件,用于发布到App Store或进行企业内部分发。
在打包过程中,如果遇到错误,可查看Unity的Console窗口或相关构建日志,根据错误提示来排查和解决问题。
关于Android SDK Build Tools Install failed: Installation Failed 安装下载失败的终极解决方案
最低22 最高 30 可以 unity 对应哪些版本的构建工具
当 Unity 项目的Minimum API Level 设为 22(Android 5.1)、Target API Level 设为 30(Android 11)时,对应的构建工具版本选择如下:
一、核心工具版本要求
Android SDK Build Tools
推荐使用 30.0.3(与 Target API Level 30 完全匹配,兼容性最佳)。
- 原因:Build Tools 版本需≥Target API Level 对应的版本,30.0.3 是 API 30 的官方稳定版本,支持所有 Android 11 的特性,同时向下兼容 Minimum API 22。
- 可选版本:30.0.0~30.0.4 之间的版本(均为 API 30 的配套工具),但 30.0.3 经过大量项目验证,稳定性最优。
Android SDK Platform Tools
必须≥32.0.0(解决之前提到的 “version 0.0 < 32.0.0” 错误)。
推荐使用 34.0.4(最新稳定版),兼容 API 22~30 的所有平台,且修复了旧版本的部分兼容性问题。Android SDK Command-line Tools
推荐 6.0 版本 或更高(如 10.0),需与 SDK 整体版本匹配。
- 确保安装后能在
SDK目录/cmdline-tools/latest/bin
找到sdkmanager.bat
,避免 Unity 检测失败。二、Unity 版本兼容性
以上工具版本组合适用于 Unity 2019.4 及以上版本(包括 2020、2021、2022 等):
- Unity 2019.4:对 API 30 的支持需通过补丁更新,建议升级到 2019.4.30f1 及以上。
- Unity 2020.3 及更高:原生支持 API 30,无需额外配置,直接使用上述工具版本即可。
三、安装与配置要点
确保 SDK 目录下存在:
platforms/android-22
(API 22 的系统镜像)platforms/android-30
(API 30 的系统镜像)build-tools/30.0.3
(对应版本的构建工具)在 Unity 的
Player Settings
中:
- 确认
Minimum API Level = Android 5.1 (API Level 22)
- 确认
Target API Level = Android 11 (API Level 30)
按以上配置,既能保证应用在 Android 5.1~11 的设备上正常运行,又能满足大多数应用商店的上架要求(Target API 30 目前仍被主流平台支持),同时避免版本不匹配导致的构建错误。
上面的所有依赖请在 Android studio中下载匹配对应版本,重要,所有的版本都要一 一匹配
请选择自己Android studio 的SDK安装目录
下面目录是显示所有依赖文件
新建文件 -------->>>> bemulator目录记录与tools切换
记录原Android studio 开发环境中的bemulator 文件名
将bemulator虚拟机文件夹改名为tools 以适配unity 依赖文件的需求
将SDK文件夹 中的cmdline-tools 命令行 工具复制到
SDK目录中的build-tools 的对应API级别的30.0.3的目录中去
D:\development\Android\sdk\build-tools\30.0.3
让后到file 菜单中的Build ------> settings
点击Build And Run 构建运行就可以了
如果你用打开了开发者模式的 手机, 数据线 电脑连接到一起,unity会将这个apk文件安装到手机
我们也可以通过手机 unity Remote APP (这个app请搜索百度自行下载)连接数据线到笔记本电脑 进行实时传输测试
注意连接测试的时候请打开手机开发者模式,进行测试。
如果你的游戏人物图层显示不出来 请检查图层问题 数越高 在图层上越置顶

如果你打包到手机上面显示不出人物,那么请点击
添加和项目中匹配的长江,将不匹配的场景取消勾选
unity游戏开发动画状态机上下左右方向移动 虚拟摇杆切换走路上下左右动画 添加摄像机跟随游戏人物移动的动画,摄像机跟随
深海蓝图
在 Unity 的 Animator 过渡条件中,可以设置多个条件,这些条件之间是 “逻辑与(AND)” 的关系,即所有条件都满足时,过渡才会触发。
以你截图中的例子来说:
- 条件 1:
IsWalkUp = false
(“向上走” 的布尔参数为 false,即角色当前不处于向上走的状态)。- 条件 2:
IsWalkDown = true
(“向下走” 的布尔参数为 true,即角色需要切换到向下走的状态)。只有当这两个条件同时满足时,这条过渡线对应的动画过渡(比如从其他状态切换到 “向下走” 的动画状态)才会触发。这种多条件的设置,常用于 “排除当前状态 + 激活目标状态” 的精准逻辑控制,确保动画切换更符合预期。
编辑分享
以下是所有状态间过渡线的条件,按 “Idle 与走路状态”“走路状态之间” 两组分类,直接对照设置即可:
一、Idle ↔ 各走路状态的过渡(双向,共 8 条)
过渡方向 | 条件设置 | 说明 |
---|---|---|
Idle → WalkUp | IsWalkUp = true |
从待机切到向上走 |
WalkUp → Idle | IsWalkUp = false |
从向上走切到待机 |
Idle → WalkDown | IsWalkDown = true |
从待机切到向下走 |
WalkDown → Idle | IsWalkDown = false |
从向下走切到待机 |
Idle → WalkLeft | IsWalkLeft = true |
从待机切到向左走 |
WalkLeft → Idle | IsWalkLeft = false |
从向左走切到待机 |
Idle → WalkRight | IsWalkRight = true |
从待机切到向右走 |
WalkRight → Idle | IsWalkRight = false |
从向右走切到待机 |
二、走路状态之间的过渡(双向,共 12 条)
过渡方向 | 条件设置(多条件为 “逻辑与”) | 说明 |
---|---|---|
WalkUp → WalkDown | IsWalkUp = false 且 IsWalkDown = true |
从向上走切到向下走 |
WalkDown → WalkUp | IsWalkDown = false 且 IsWalkUp = true |
从向下走切到向上走 |
WalkUp → WalkLeft | IsWalkUp = false 且 IsWalkLeft = true |
从向上走切到向左走 |
WalkLeft → WalkUp | IsWalkLeft = false 且 IsWalkUp = true |
从向左走切到向上走 |
WalkUp → WalkRight | IsWalkUp = false 且 IsWalkRight = true |
从向上走切到向右走 |
WalkRight → WalkUp | IsWalkRight = false 且 IsWalkUp = true |
从向右走切到向上走 |
WalkDown → WalkLeft | IsWalkDown = false 且 IsWalkLeft = true |
从向下走切到向左走 |
WalkLeft → WalkDown | IsWalkLeft = false 且 IsWalkDown = true |
从向左走切到向下走 |
WalkDown → WalkRight | IsWalkDown = false 且 IsWalkRight = true |
从向下走切到向右走 |
WalkRight → WalkDown | IsWalkRight = false 且 IsWalkDown = true |
从向右走切到向下走 |
WalkLeft → WalkRight | IsWalkLeft = false 且 IsWalkRight = true |
从向左走切到向右走 |
WalkRight → WalkLeft | IsWalkRight = false 且 IsWalkLeft = true |
从向右走切到向左走 |
注!请将上面所有线路全部一 一 匹配
举例
附赠 第二版本的代码:
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Rigidbody2D), typeof(Animator))] // 自动添加必要组件
public class SimplePlayerMovement : MonoBehaviour
{
[Header("移动设置")]
public float moveSpeed = 5f;
public bool allowDiagonal = true; // 是否允许斜向移动
[Header("虚拟摇杆设置 (Joystick Pack)")]
public VariableJoystick variableJoystick; // 拖入Joystick Pack的摇杆(手机端用)
[Header("动画设置")]
public Animator playerAnimator; // 拖入角色的Animator组件
[Header("摄像机跟随设置")]
[Tooltip("引用场景中的主摄像机")]
public Camera mainCamera;
[Tooltip("摄像机与玩家的偏移量")]
public Vector3 cameraOffset = new Vector3(0, 1, -10);
[Tooltip("摄像机跟随的平滑程度")]
public float cameraSmoothSpeed = 0.125f;
[Tooltip("是否限制摄像机移动范围")]
public bool limitCameraBounds = false;
[Tooltip("摄像机移动的边界范围")]
public Rect cameraBounds;
// 动画参数名(需与Animator中设置的参数完全一致)
private const string IsWalkUp = "IsWalkUp";
private const string IsWalkDown = "IsWalkDown";
private const string IsWalkLeft = "IsWalkLeft";
private const string IsWalkRight = "IsWalkRight";
private Rigidbody2D rb;
private Vector2 movement; // 移动向量(x:左右, y:上下)
private CameraFollow cameraFollow; // 摄像机跟随组件引用
// 输入动作(键盘/手柄)
private InputAction moveAction;
void Awake()
{
// 初始化组件引用
rb = GetComponent<Rigidbody2D>();
playerAnimator = GetComponent<Animator>();
// 初始化输入动作(键盘WASD/方向键、手柄左摇杆)
var inputActionMap = new InputActionMap("Player");
moveAction = inputActionMap.AddAction("Move",
InputActionType.Value,
"<Gamepad>/leftStick", // 手柄左摇杆
null, null,
"<Keyboard>/a,<Keyboard>/d,<Keyboard>/w,<Keyboard>/s,<Keyboard>/leftArrow,<Keyboard>/rightArrow,<Keyboard>/upArrow,<Keyboard>/downArrow"); // 键盘
inputActionMap.Enable(); // 启用输入监听
// 初始化摄像机跟随
SetupCameraFollow();
}
void Update()
{
// 1. 获取移动输入(优先虚拟摇杆,其次键盘/手柄)
GetMovementInput();
// 2. 处理斜向移动限制(若关闭斜向,则只保留一个轴的移动)
HandleDiagonalMovement();
// 3. 根据移动方向更新动画参数
UpdateAnimationParameters();
}
void FixedUpdate()
{
// 物理帧应用移动(Rigidbody2D建议在FixedUpdate中操作)
rb.velocity = movement * moveSpeed;
}
void LateUpdate()
{
// 摄像机跟随逻辑在LateUpdate执行,确保在玩家移动后更新
if (cameraFollow != null)
{
cameraFollow.FollowTarget(transform, cameraOffset, cameraSmoothSpeed,
limitCameraBounds, cameraBounds);
}
}
/// <summary>
/// 设置摄像机跟随组件
/// </summary>
private void SetupCameraFollow()
{
// 如果没有指定主摄像机,尝试获取场景中的主摄像机
if (mainCamera == null)
mainCamera = Camera.main;
// 为主摄像机添加CameraFollow组件(如果没有的话)
if (mainCamera != null)
{
cameraFollow = mainCamera.GetComponent<CameraFollow>();
if (cameraFollow == null)
{
cameraFollow = mainCamera.gameObject.AddComponent<CameraFollow>();
}
}
}
/// <summary>
/// 获取移动输入(手机摇杆 / 键盘/手柄)
/// </summary>
private void GetMovementInput()
{
if (variableJoystick != null)
{
// 手机端:使用虚拟摇杆输入
movement = variableJoystick.Direction;
}
else
{
// PC端:使用键盘/手柄输入
movement = moveAction.ReadValue<Vector2>();
}
// 优化:消除微小输入(避免因设备精度问题导致角色"抖动")
movement.x = Mathf.Abs(movement.x) < 0.1f ? 0 : movement.x;
movement.y = Mathf.Abs(movement.y) < 0.1f ? 0 : movement.y;
}
/// <summary>
/// 处理斜向移动限制
/// </summary>
private void HandleDiagonalMovement()
{
if (!allowDiagonal && movement.sqrMagnitude > 0)
{
// 斜向移动时,保留绝对值更大的轴(优先水平或垂直移动)
if (Mathf.Abs(movement.x) > Mathf.Abs(movement.y))
{
movement.y = 0; // 只保留水平移动(左/右)
}
else
{
movement.x = 0; // 只保留垂直移动(上/下)
}
}
}
/// <summary>
/// 根据移动方向更新Animator的布尔参数
/// </summary>
private void UpdateAnimationParameters()
{
// 默认为所有方向"不移动"
bool isUp = false;
bool isDown = false;
bool isLeft = false;
bool isRight = false;
// 有移动输入时,判断具体方向
if (movement.sqrMagnitude > 0)
{
// 1. 处理垂直方向(上/下)
if (Mathf.Abs(movement.y) > Mathf.Abs(movement.x))
{
// 垂直移动优先级高于水平(斜向时优先播放上下动画)
isUp = movement.y > 0;
isDown = movement.y < 0;
}
// 2. 处理水平方向(左/右)
else
{
// 水平移动优先级高于垂直(斜向时优先播放左右动画)
isLeft = movement.x < 0;
isRight = movement.x > 0;
}
}
// 将参数传递给Animator
playerAnimator.SetBool(IsWalkUp, isUp);
playerAnimator.SetBool(IsWalkDown, isDown);
playerAnimator.SetBool(IsWalkLeft, isLeft);
playerAnimator.SetBool(IsWalkRight, isRight);
// 调试:打印当前动画参数值
// Debug.Log($"Up: {isUp}, Down: {isDown}, Left: {isLeft}, Right: {isRight}");
}
}
// 摄像机跟随组件
public class CameraFollow : MonoBehaviour
{
private Camera mainCamera;
void Awake()
{
mainCamera = GetComponent<Camera>();
}
/// <summary>
/// 跟随目标移动
/// </summary>
public void FollowTarget(Transform target, Vector3 offset, float smoothSpeed,
bool useBounds, Rect bounds)
{
if (target == null || mainCamera == null) return;
// 计算目标位置(目标位置 + 偏移量)
Vector3 desiredPosition = target.position + offset;
// 如果启用边界限制,将目标位置限制在边界内
if (useBounds)
{
// 计算摄像机在世界空间中的边界
float camHalfWidth = mainCamera.orthographicSize * mainCamera.aspect;
float camHalfHeight = mainCamera.orthographicSize;
// 限制X轴在边界内
desiredPosition.x = Mathf.Clamp(desiredPosition.x,
bounds.xMin + camHalfWidth,
bounds.xMax - camHalfWidth);
// 限制Y轴在边界内
desiredPosition.y = Mathf.Clamp(desiredPosition.y,
bounds.yMin + camHalfHeight,
bounds.yMax - camHalfHeight);
}
// 保持Z轴不变(避免摄像机前后移动)
desiredPosition.z = transform.position.z;
// 平滑过渡到目标位置
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
}
// 在编辑器中绘制Gizmos,显示边界范围
private void OnDrawGizmosSelected()
{
// 获取PlayerMovement组件以获取边界设置
SimplePlayerMovement playerMovement = FindObjectOfType<SimplePlayerMovement>();
if (playerMovement != null && playerMovement.limitCameraBounds)
{
Gizmos.color = Color.blue;
Gizmos.DrawWireCube(
new Vector3(playerMovement.cameraBounds.center.x, playerMovement.cameraBounds.center.y, 0),
new Vector3(playerMovement.cameraBounds.width, playerMovement.cameraBounds.height, 0)
);
}
}
}
主要修改说明:最重要是加入了animation 动画状态机
添加了摄像机跟随设置区域:
- 可以指定主摄像机
- 设置摄像机与玩家的偏移量
- 调整跟随平滑度
- 可选的边界限制功能
内部集成了 CameraFollow 组件:
- 作为嵌套类存在,不需要额外的脚本文件
- 保留了平滑跟随和边界限制功能
- 通过 LateUpdate 确保在玩家移动后更新摄像机位置
自动设置机制:
- 如果没有指定摄像机,会自动查找主摄像机
- 自动为摄像机添加必要的跟随组件
保留了所有原有功能:
- 玩家移动、输入处理、动画控制等功能不变
- 可继续使用虚拟摇杆或键盘控制
- 斜向移动限制功能依然有效
使用时,只需在 Inspector 面板中调整摄像机相关参数即可,无需额外设置。如果需要限制摄像机移动范围,可以勾选 "limitCameraBounds" 并设置合适的边界值。
分享
如何调整摄像机跟随的平滑程度?
怎样限制摄像机移动范围?
摄像机偏移量如何设置?
最终打包你的项目不要出现中文,不然打包为Android APP 会出错
初次打包用了3分钟左右 之后再次打包就会很快了!!!
整理不易,更多游戏开发教程请持续关注CSDN王家视频教程图书馆,点赞+关注+转发 亲!!!!!!!!