找回密码
 立即注册
查看: 352|回复: 0

Unity初学者实践与提高(四)---角色控制系统

[复制链接]
发表于 2022-6-29 15:52 | 显示全部楼层 |阅读模式

效果

输入系统

上一章角色可以做不同的动作了,但是还是原地动作,现在我们让他真正的动起来。
控制角色移动需要输入设备,PC上一般是用键盘控制,手机用触摸屏(软摇杆),其它硬件也有不同的配套输入设备,我们要给每种设备都写一套事件响应逻辑吗?显然不是一个好主意,Unity为我们提供了封装。
以前的Unity版本中有Input,InputManager分别提供了读取设备输入值,以及通过虚拟轴映射游戏事件的作用,新版本提供了一套新的输入系统InputSystem.我们就介绍一下新输入系统的使用方法。
首先打开包管理器: Window->Package Manager,选择Input System进行安装:


安装

随后弹出的对话框中选Yes.


警告

Unity将重新启动并禁用旧版Input Api,启用新版Input System.即使这里没有选Yes,我们也可以手动去切换输入系统,方法是打开项目设置: Edit->Project Setting->Player->Active Input Handling,选择Input System Package(New):

设置

遇到问题

好了,输入系统切换完成,运行项目,发现UI不响应了,又发生了什么?
其实这是因为UI默认采用的是老版输入系统作为其输入,我们只需要一个简单的设置就可以解决它。


切换新输入系统

在Hierarchy面板选中EventSystem,点击Inspector面板的 Replace with InputSystemUIInputModule.然后再运行项目,UI又恢复响应了。
控制角色

新输入系统准备好了,现在要开始控制角色了,先给角色加一个Player Input组件:


PlayerInput组件

在红框位置有一个CreateActions的按钮,按一下,选择文件位置,会创建一个Input Action Assets,同时会打开左边的面板。这里面定义好了一些Action,以及对输入设备的映射。
写逻辑的时候,只要处理Action就好了,而不用管具体的是键盘输入的,还是手柄摇杆,达到了输入和逻辑相分离的目的。
逻辑代码和Action关联的方式有多种,可以通过Player Input组件的Behavior来控制,它表示当有动作触发时的响应方式:
    Send MessagesBroadcast MessagesUnity EventsCSharp Events
这四种触发模式,从效率上看,Broadcast Messsages < Send Messages < Unity Events < Csharp Events。
前两种很好接入,只要在脚本中添加 On{ActionName}()函数就可以。
Unity Events 要在 Inspector 中分配各种回调函数,可视化操作,对新手友好,但在函数和动作逻辑较多时比较麻烦。
最后一个比较高效,但是所有的动作共享同一个回调事件 event Action<InputAction.CallbackContext> onActionTriggerd,需要在这个函数中自行区分具体的触发动作。

具体的接入方式可以参考Input System提供的Demo: 打开包管理器,选中Input System,在右边面板选中要查看的Demo,然后点击Import按钮(非必须):


查看Demo

现在我们来创建自己的角色控制逻辑,创建一个名为SimpleActorController的脚本,挂载到角色身上,代码如下:
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.InputSystem;public class SimpleActorController : MonoBehaviour{    public float moveSpeed; //角色移动速度        private InputAction m_MoveAction;    private Animator animator;    private Vector3 rotationVector;        private Vector2 m_Move;    // Start is called before the first frame update    void Start()    {        animator = GetComponent<Animator>();        if (m_MoveAction == null)        {            PlayerInput input = GetComponent<PlayerInput>();            m_MoveAction = input.actions["move"];        }    }    private void Update()    {        MoveActor();    }    //移动角色    public void MoveActor()    {        bool isMoving = false;        if (m_MoveAction != null && m_MoveAction.IsPressed())        {            m_Move = m_MoveAction.ReadValue<Vector2>();            if(m_Move.sqrMagnitude > 0.1f)            {                Vector2 moveVector = m_Move * (moveSpeed * Time.deltaTime);                //求前进的方向                Vector3 dir = Camera.main.transform.localToWorldMatrix.MultiplyVector(new Vector3(moveVector.x, 0, moveVector.y));                dir.y = 0f;                dir = dir.normalized;                //把角色转向前进方向                transform.forward = Vector3.SmoothDamp(transform.forward, dir, ref rotationVector, 0.1f);                transform.position = transform.position + dir * moveVector.magnitude;                isMoving = true;            }        }                animator.SetFloat("speed", isMoving ? moveSpeed : 0.0f);    }}
可以看到,我们用最简便快捷的方式,在Update函数中直接检测Action是否被按下,实际项目中不建议这么做。

然后在Inspector面板中设置移动速度为5左右,现在运行程序,并尝试按方向按钮或者ASDW键,可以看到角色动起来了。
再遇问题

角色是可以移动了,但是好像反应迟钝,先滑步好长距离,才开始跑步,停下的时候也原地踏步半天才停下,这是什么原因呢?
我们在实际项目中经常会遇到类似的状况,明明觉得该做的都做了,但总会出现一些意外。这就要考验大家知识掌握的是否扎实,或者经验是否老到。你可能会记起在学习Animator Controller的时候,有个Has Exit Time的选项,用来控制角色是否一定要播完上一个动作,再切换到下一个动作,目前这个现象很像是勾选了这个选项造成的,打开我们的RoleController,点击Idle状态,在Inspector面板中查看,果然是勾选状态,去掉勾选。


去掉Has Exit Time

我们还要能够举一反三,想想还有没有类似的问题,好像子状态机里面还有状态,好打开后进行同样的操作,保存再试.
"果然好了,不那么迟钝了。可是为什么摄像机不跟着角色走呀?"
因为我们还没有写摄像机控制的代码呀,游戏界有个名词叫 "3C" 就是 "Character Camera Control(角色、相机、控制)" 三个单词的缩写, 它的好坏直接影响到游戏体验,是游戏中十分重要的功能,我们的SimpleActorController是帮助大家入门,所以写的越简单越好,真正项目中要复杂的多,就等你去完善了。

说到摄像机控制,我们下章再来实现吧。

同样给出本章项目连接 角色控制系统
<hr>
返回主目录
【转载请注明出处】

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-15 20:38 , Processed in 0.146515 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表