如何添加脚本组件!
其实创建脚本组件和我们添加之前学过的物理组件那些差不多!
首先呢我们最好在我们的项目静态文件夹下面新建一个 Script目录,然后创建一个Player的目录,代表里面存放着控制玩家的脚本!
然后创建一个 c# 脚本!起名叫 PlayController
那么会给我们生成一个模板文件,代码中有一个和我们命名一样的PlayerController
的类!然后一些写好的实例方法!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
unity 本身内置了一些生命周期的函数,用于在不同的周期去调用!
比如模板中的
-
Start
就是在游戏的第一帧去调用 -
Update
就是在屏幕刷新的每一帧去调用,比如我们常说的60fps 120fps
,说明屏幕一秒刷新的次数!如果是60fps
的屏幕,那么update
在这个环境下一秒就被执行 60次!所以为什么高帧率的显示器最好相对配置一个好的显卡了吧!当游戏刷新率上去的时候,游戏内部的更新频率也会更高,显卡内存资源消耗的也更多!
如何让这个脚本组件和我们的人物绑定呢?其实很简单!我们只需要选中我们的人物,然后把脚本拖去检查器的添加组件那部分就好了!
那么我们来验证一下,脚本是不是真的绑定成功了!首先我们添加到了存在游戏场景中的Player身上!
那么当游戏运行的时候,就会执行身上绑定的脚本代码!
我们随便在Start的生命周期中打印点东西!
void Start()
{
Debug.Log("PlayController is ok !");
}
然后点击运行游戏,可以看到 Console 控制台打印的内容了!说明脚本绑定成功!
启用新的输入系统
这里呢我们来配置 unity 全新的输入系统!
什么是输入系统呢?
比如我们打游戏的键盘,鼠标,手柄,VR的手持遥感,这些能通过硬件向游戏中输入一些操作数据的设备!
经过输入系统的处理来操作我们的游戏物体!这个就是我们的输入系统!
首先我们要把unity升级到最新的输入系统,需要进行一些简单的设置!
进入Project Settings !
可以看到一个 Input Manger
默认看到的这个是比较旧版本的Input
控制系统!它对一些新的跨平台的控制兼容性可能没有那么好!
毕竟用新不用旧嘛,能多支持一些是一些!这个全新的输入系统对一些多平台的控制适配会相对好一点!
那么如何开启使用比较新的输入系统呢?
找到下面的Player -> Other Settings
找到这里,默认是standard标准版,我们切换到 .NetFrame Work
版本!
选择这个也可以让unity 去利用更多 c# 的特性来编写执行我们的脚本!!
如果你出现了下图中无法选择,选项置灰的情况!首先确认有没有安装.NetFrame Work
如果没有则安装并且重启!如果确认之前有安装还不行!那就也重启一下! emmm
因为我遇到这个问题就是这么解决的,目前只能给出这个方式了!
下面我们还要更改一个选项 Active Input Handing 选择激活的输入系统
当前默认为 Old 我们切换到 New版本!
切换这个的话,unity的编辑器会重启!
上面的部分只是告诉 unity 要用上面方式去使用输入系统!
但是unity 本身只是内置了 旧版本的输入系统的sdk
,我们还要去额外下载一下新版本输入系统对应的sdk
!
x去package manager 去安装一下对应的包!(可以这么理解!)
菜单栏 Window > package manager > 左上角勾选 Unity Registry > 搜索 input 安装 input System!
想了解更多安装这个东西是什么?
可以在这里点击 Document !去 看文档了
手动配置输入系统 Input Actions
启用了我们新的输入系统,然后我们还要去配置一个控制表。这个表来配置我们需要适配的设备,按键!要去指定我们去适应键盘的按键啊,switch,Xbox不同的手柄按键等等这些!
那么我们首先进入Settings文件夹,这个是项目一开始就帮我们创建好的,专门用来放置一些游戏项目的基本设置的东西!
创建Settings > Controls 文件夹
然后右键创建 Input Actions
重命名为 InputControls 双击打开!
就可以看到这样一个界面了!在这里就可以添加你要适配那些控制设备了!
Input Action Type文档 你可以能会看到多种 actiontype
,具体的区别参考前面的文档链接
然后创建一个actions
用来控制我们人物的上下前后移动,起名为movement
!action type
选为value
control type
为 vector 2
因为2d
的上下左右移动,用二维向量就可以表示了!
此时右键添加上下左右组件的actions 添加一些键位的绑定!
分别绑定WASD
比如 往上跳 是 W up 选择 path 检索 w[keyboard]这样就完成了键盘上 w 对应 Up 的绑定
然后分别对每个键位都进行绑定!
这里有一个方便的小技巧
如果你不知道那些选项都对应着哪些设备的哪些按键!可以在配置path的时候点击listen,然后摁下你设备上要配置的键位,他就可以监听到你摁的键位自动选择上去了
InputControlScheme 设备命名空间
多个设备要求的时候,为每一种设备单独制造一个命名空间!如,"键盘鼠标 "组和 "游戏手柄 "组
适用场景,当你有多个游戏场景,多个设备去控制的时候,比如开始游戏场景,正在游戏的场景,结束游戏的场景,设置游戏的场景,分别都有键盘,手柄,VR设备去控制,如果你想单独查看或者设置某个设备下的操作输入控制,可以根据命名空间进行设备的过滤!
添加方式!
然后用同样的 方式创建一个 GamePad 手柄的命名空间!
并且绑定一个手柄的输入控制到GamePad Scheme!
然后把这些 UDLR 绑定到keyboard的命名空间!
然后就可以通过命名空间进行设备筛选了!
组件方式-添加输入系统组件自动生成默认输入配置
除了手动添加,我们也可以通过添加组件的方式配置游戏的各种输入系统!
选中要控制的 Player > Add Component > Play Input(通过快速检索)
默认组件内部是没有任何的actions 的可以手动创建一个
点击Create Actions
重命名为 PlayerControls
保存到之前创建的文件夹Settings
> Controls
双击打开后!你会发现他内部有默认帮我们生成的一些配置!当然我们肯定也要单独去定制化我们的按键!
来到外面也可以看到不同设备的 scheme
然后通过配置behavior去配置调用输入控制的方式!
这个后面学习的时候在进行补充吧!
通过 c# 脚本操作输入系统 完成角色移动和转向
按照组件添加的方式,我们可以生成一份默认的输入配置 !这里我们取名为 WarriorControls
这份配置内部默认了一个Player的输入系统配置!一个UI的输入系统配置!分别对应了不同游戏场景的操作配置!
Player 我们主要是用来控制游戏场景中的主角输入的,通过按键输入让主角完成移动攻击跳跃等!理解为在游戏场景按键的配置!
从语义角度来讲,将其命名为GamePlaying
可读性比较好!
如果我们这里配置完成了!然后想让其他物体通过脚本通过这个输入系统拿到控制设备的输入信息的话,需要根据这个Input Actions 生成一个c# 脚本! 这样在脚本之间就可以调用这个输入系统了!
我们需要点击 Generate C # Class
!
勾选后然后选择apply
就可以看到给我们创建了一个基于这个输入系统的c#脚本,可以看到里面的代码maps就是我们刚刚配置的一些actions Map!
下一步!我们想让我们的主角能通过键盘输入的方式动起来!
那么其实大致流程就是:在人物脚本中获取控制系统 >>>
读取控制系统的特定按键的输入(WASD或者手柄输入) >>>
根据输入的值来决定人物如何移动!
首先给人物创建脚本!!
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 使用输入系统!
using UnityEngine.InputSystem;
public class WarriorController : MonoBehaviour
{
// 使用 WarriorControls 系统输入配置
private WarriorControls _warriorControls;
// 用于存储从控制系统读取的移动信息!因为控制输入的值是一个xy方向的二维向量!
public Vector2 direction;
void Awake()
{
// 初始化一个WarriorControls 实例
_warriorControls = new WarriorControls();
}
void Start()
{
}
void OnEnable()
{
Debug.Log("Enable");
_warriorControls.Enable();// 开启输入系统!
}
void OnDisable()
{
Debug.Log("Disable");
_warriorControls.Disable(); // 关闭输入系统!
}
// Update is called once per frame
void Update()
{
}
void Move()
{
direction = _warriorControls.GamePlaying.Move.ReadValue<Vector2>();
}
void FixedUpdate()
{
Move();
}
}
可以看到我们通过控制系统读取的值,能存到我们自定义的 Direction
变量上去了!
可以看到每次按键这个值都在 0-1之间,然后我们需要一个速度speed,这样这个 1 * speed 就是实际在场景中移动到距离了!
为了方便我们在界面中方便的改变这个speed 我们把它当做一个 public 的实例属性!这样我们就可以在主角的检查器中很方便的改变这个值了!
因为我们物体之间做了真实的物理交互(添加了刚体!碰撞体!) 所以我们的移动相关也要在刚体上进行操作!防止穿模?哈哈哈!改变刚体的位置,
可以看到单纯的改变 Transform 的话!是会穿模的!所以要保持人物和地面的碰撞关系,一般我们通过代码控制刚体的位移关系!
一般我们通过改变刚体的速度来控制移动!
为什么改变的是速度 却可以移动位置?
改变刚体的速度实际上也会导致位置的改变。这是因为在Unity中,在每一帧渲染之前,物理引擎会根据物体的速度、质量和所受力的大小和方向来计算出下一帧物体的位置和速度。
当你改变了Rigidbody组件的velocity属性时,你实际上是改变了物体的速度,并影响到了下一帧物体的位置。例如,如果你将一个静止的物体的速度设置为(1,0,0),那么它就会沿着x轴正方向移动一定距离,直到被其他物体或碰撞器停止。
因此,通过改变刚体的速度,你可以控制物体在下一帧中移动的方向和速度,从而改变它的位置。
当我们在 Unity 中控制物体移动时,实际上是通过改变物体的速度属性来达到目的。速度描述了物体在空间中移动的快慢和方向,而位置则是物体在空间中所处的具体坐标。当我们改变物体的速度属性时,它会影响物体在下一帧中的位置,因为物体会根据速度的大小和方向在空间中移动一段距离。因此,通过控制物体的速度属性,我们可以控制它在空间中的位置和运动方式。
物体在场景中时时刻刻在更新!给他一个速度,他就根据速度跑起来了!
Time.deltatime是一个值,表示一帧的间隔时间。这个值在不同电脑里不一样。
void Update()
{
transform.Translate(0,0,1);
}
比如上面的代码!在一个100fps的设备中!一秒可以移动 100 个单位! 在50fps的设备中一秒移动 50个单位长度!这样在不同设备中就出现了不一样的表现!
此时就需要引入 Time.deltatime
在100fps它的值为 0.01 ;50fps 它的值为 0.02 这样一秒移动到距离分别就是 100*0.01
& 50x0.02
都是 1 这样就能保证每一秒的移动都是一致的!
来看看效果,这样我们就完成了角色的简单移动了!
然后让人物根据移动到方向进行转向!
通过改变人物的scale
同样的我们控制方向的时候去改变 transform的 scale 为 +1
-1
评论区