章节目录

  • 前言
  • 为角色添加Collider和Rigidbody
  • 控制角色移动
  • 添加Physics Material
  • 添加音效
  • PlayerController.cs完整代码
  • 后言
  • 参考链接

前言

  为了便于测试,我们会先使用PC端的键盘和鼠标输入来控制人物的移动,等到功能测试完成之后,再将PC端的键盘和鼠标输入换成移动端的虚拟摇杆和按钮输入。这里,我们首先使用PC端的键盘和鼠标输入来实现控制角色进行移动的功能。


为角色添加Collider和Rigidbody

  为了让角色具有物理属性,我们需要为角色添加Collider和Rigidbody。此外,为了避免角色出现翻滚的问题,让角色一直保持直立,因此我们需要在Rigidbody2DConstraints属性里设置勾选Freeze Rotation Z,不让角色在进行物理模拟时,绕Z轴进行旋转。


控制角色移动

  接下来,我们开始编写脚本来实现让怪物在场景中移动的功能。我们在Assets\Scripts文件夹下创建一个名为Player的文件夹用于保存和角色相关的脚本。创建完毕后,我们在Player文件夹下创建一个名为PlayerController的C#脚本,然后添加以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[RequireComponent(typeof(Rigidbody2D))]
public class PlayerController : MonoBehaviour {[Tooltip("角色初始朝向是否朝向右边")]public bool FacingRight = true;[Tooltip("移动时角色加速的力大小")]public float MoveForce = 365f;[Tooltip("角色移动的最大速度")]public float MaxSpeed = 5f;[Tooltip("跳跃时向上加速的力大小")]public float JumpForce = 1000f;[Tooltip("检测角色是否落地")]public Transform GroundCheck;// 记录角色当前是否处于准备跳跃状态private bool m_IsReadyToJump;// 记录角色当前是否正处于跳跃状态private bool m_IsJumping;// 记录角色当前是否处于着地状态private bool m_GroundedStatus;// 组件引用变量private Rigidbody2D m_Rigidbody2D;private void Awake() {// 获取组件引用m_Rigidbody2D = GetComponent<Rigidbody2D>();}private void Start() {// 监测变量是否正确赋值if(GroundCheck == null) {Debug.LogError("请先设置GroundCheck");}// 初始化变量m_IsReadyToJump = false;m_IsJumping = false;m_GroundedStatus = false;}private void Update() {// 通过检测角色和groundCheck之间是否存在Ground层的物体来判断当前是否落地m_GroundedStatus = Physics2D.Linecast(transform.position,GroundCheck.position,LayerMask.GetMask("Obstacle"));// 着地时,如果当前不处于跳跃状态且按下了跳跃键,进入准备跳跃状态if(m_GroundedStatus && !m_IsJumping && Input.GetButtonDown("Jump")) {m_IsReadyToJump = true;}// 刚刚落地,退出跳跃状态if(m_GroundedStatus && m_IsJumping) {m_IsJumping = false;}}private void FixedUpdate() {//获取水平输入float h = Input.GetAxis("Horizontal");// 若h * m_Rigidbody2D.velocity.x为正数且小于MaxSpeed,表示需要继续加速// 若h * m_Rigidbody2D.velocity.x为负数,则表示需要反向加速if(h * m_Rigidbody2D.velocity.x < MaxSpeed) {m_Rigidbody2D.AddForce(Vector2.right * h * MoveForce);}//设置物体速度的阈值if(Mathf.Abs(m_Rigidbody2D.velocity.x) > MaxSpeed) {m_Rigidbody2D.velocity = new Vector2(Mathf.Sign(m_Rigidbody2D.velocity.x) * MaxSpeed,m_Rigidbody2D.velocity.y);}//判断当前是否需要转向if(h > 0 && !FacingRight) {Flip();}else if(h < 0 && FacingRight) {Flip();}// 跳跃if(m_IsReadyToJump) {Jump();}}private void Jump() {// 进入跳跃状态m_IsJumping = true;// 设置一个竖直向上的力m_Rigidbody2D.AddForce(new Vector2(0f, JumpForce));// 退出准备跳跃状态,避免重复跳跃m_IsReadyToJump = false;}private void Flip() {// 修改当前朝向FacingRight = !FacingRight;// 修改scale的x分量实现转向this.transform.localScale = Vector3.Scale(new Vector3(-1, 1, 1),this.transform.localScale);}
}

代码说明:

  • Input.GetAxis(“Horizontal”):Unity提供的默认输入项,能获取键盘上A\D键和<-\->方向键的输入
  • Input.GetButtonDown(“Jump”):Unity提供的默认输入项,能获取键盘上空格键的输入
  • Physics2D.Linecast:来获取场景里两个点之间属于某个Layer的所有Collider
  • 因为和角色物理模拟有关的操作都应该在FixedUpdate里执行,所以Jump函数需要在FixedUpdate里调用
  • 我们为了避免出现多次按跳跃键导致Jump函数被多次调用的问题,我们使用变量m_IsJumping来判断当前是否处于跳跃状态

添加Physics Material

  添加完成后,将PlayerController.cs添加到Hierarchy窗口的Player上,运行游戏,我们发现角色在运动时,会出现很明显的滑动现象。这是因为我们没有为角色和平台上的Collider设置Physics Material,导致角色和平台之间的摩擦力为0。

添加Physics Material的步骤

  1. Assets目录下新建一个名为Physics Material的文件夹
  2. Physics Material的文件夹创建两个Physics Material 2D,并将它们分别命名为PlatformPlayer
  3. PlatformPlayer这两个Physics Material 2DFriction属性都设置为1
  4. PlatformPlayer这两个Physics Material 2D分别设置到所有角色可移动的平台角色的Rigidbody2D

  因为平台数量较多,我们可以批量操作。按住shift键选择多个GameObject,右侧Inspector就会显示它们同时都具备的组件,我们可以同时对它们同时都具备的组件进行编辑。

  此外,角色在跳跃时,我们发现角色跳跃的高度很高,且下落的速度很慢,游戏体验较差。为了提高游戏体验,我们需要增大游戏角色的重力加速度。将PlayerRigidbody2D组件的Gravity Scale设置为3.1,表示将角色的重力加大至原有的3.1倍。

  从上面的图片可以看到,我将Player这一Physics Material 2D设置到角色的Rigidbody2D上,这表示角色的所有没设置Physics Material 2D的Collider都会使用Player这一Physics Material 2D

  设置完成之后,运行游戏,可以看到之前的滑动和下落缓慢的问题都消失了,但是出现了一个新的问题,那就是当我们按住方向键不动的时候,角色会贴在平台边缘。之所以会出现这个问题,是因为角色和平台之间有摩擦力,为了避免这一情况,我们需要创建一个名为WallPhysics Material 2D,将其Friction属性都设置为0,然后在各个平台的末端处创建一个使用Wall这一Physics Material 2D的Collider。

Foreground添加Collider的情况如下:

  • env_TowerFull和env_TowerFull (1):

    • 不添加新的Collider
    • 设置原有Collider的Physics Material 2DWall
  • env_PlatformBridge和env_PlatformBridge (1):
    • 新添加一个BoxCollider2D
    • Material:Wall
    • Offset:(0.8, 0.8)
    • Size: (15.5, 0.6)
  • env_PlatformTop和env_PlatformTop (1):
    • 新添加一个BoxCollider2D
    • Material:Wall
    • Offset:(4.7, 0.12)
    • Size: (0.5, 2.6)
  • env_PlatformUfo:
    • 新添加两个CircleCollider2D
    • Material:都为Wall
    • Offset:(-15.3, -0.65)和(15.3, -0.65)
    • Radius: 都为0.5

  添加完毕之后,再次运行游戏,可以看到不再出现角色贴在平台边缘的问题。


添加音效

  接着,我们需要为角色添加音效。首先,在PlayerController.cs内加入以下代码,其中...表示原有的代码:

...
[RequireComponent(typeof(AudioSource))]
public class PlayerController : MonoBehaviour {...[Tooltip("跳跃音效")]public AudioClip[] JumpClips;...private AudioSource m_AudioSource;...private void Awake() {...m_AudioSource = GetComponent<AudioSource>();}private void Jump() {...//随机在角色当前所处的位置播放一个跳跃的音频if(JumpClips.Length > 0) {int i = Random.Range(0, JumpClips.Length);AudioSource.PlayClipAtPoint(JumpClips[i], transform.position);}}
}

  添加完毕之后,我们给Player添加AudioSource组件,并将Assets\Audio\Player\Jumps添加到JumpClips属性上。接着运行游戏,可以听到角色在跳跃的时候已经有了音效。最后,将我们在Player上做的修改Apply到Prefab上,并保存场景产生的修改即可。


PlayerController.cs完整代码

  此时,PlayerController.cs完整代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(AudioSource))]
public class PlayerController : MonoBehaviour {[Tooltip("角色初始朝向是否朝向右边")]public bool FacingRight = true;[Tooltip("移动时角色加速的力大小")]public float MoveForce = 365f;[Tooltip("角色移动的最大速度")]public float MaxSpeed = 5f;[Tooltip("跳跃时向上加速的力大小")]public float JumpForce = 1000f;[Tooltip("检测角色是否落地")]public Transform GroundCheck;[Tooltip("跳跃音效")]public AudioClip[] JumpClips;// 记录角色当前是否处于准备跳跃状态private bool m_IsReadyToJump;// 记录角色当前是否正处于跳跃状态private bool m_IsJumping;// 记录角色当前是否处于着地状态private bool m_GroundedStatus;// 组件引用变量private Rigidbody2D m_Rigidbody2D;private AudioSource m_AudioSource;private void Awake() {// 获取组件引用m_Rigidbody2D = GetComponent<Rigidbody2D>();m_AudioSource = GetComponent<AudioSource>();}private void Start() {// 监测变量是否正确赋值if(GroundCheck == null) {Debug.LogError("请先设置GroundCheck");}// 初始化变量m_IsReadyToJump = false;m_IsJumping = false;m_GroundedStatus = false;}private void Update() {// 通过检测角色和groundCheck之间是否存在Ground层的物体来判断当前是否落地m_GroundedStatus = Physics2D.Linecast(transform.position,GroundCheck.position,LayerMask.GetMask("Obstacle"));// 着地时,如果当前不处于跳跃状态且按下了跳跃键,进入准备跳跃状态if(m_GroundedStatus && !m_IsJumping && Input.GetButtonDown("Jump")) {m_IsReadyToJump = true;}// 刚刚落地,退出跳跃状态if(m_GroundedStatus && m_IsJumping) {m_IsJumping = false;}}private void FixedUpdate() {//获取水平输入float h = Input.GetAxis("Horizontal");// 若h * m_Rigidbody2D.velocity.x为正数且小于MaxSpeed,表示需要继续加速// 若h * m_Rigidbody2D.velocity.x为负数,则表示需要反向加速if(h * m_Rigidbody2D.velocity.x < MaxSpeed) {m_Rigidbody2D.AddForce(Vector2.right * h * MoveForce);}//设置物体速度的阈值if(Mathf.Abs(m_Rigidbody2D.velocity.x) > MaxSpeed) {m_Rigidbody2D.velocity = new Vector2(Mathf.Sign(m_Rigidbody2D.velocity.x) * MaxSpeed,m_Rigidbody2D.velocity.y);}//判断当前是否需要转向if(h > 0 && !FacingRight) {Flip();}else if(h < 0 && FacingRight) {Flip();}// 跳跃if(m_IsReadyToJump) {Jump();}}private void Jump() {// 进入跳跃状态m_IsJumping = true;// 设置一个竖直向上的力m_Rigidbody2D.AddForce(new Vector2(0f, JumpForce));// 退出准备跳跃状态,避免重复跳跃m_IsReadyToJump = false;//随机在角色当前所处的位置播放一个跳跃的音频if(JumpClips.Length > 0) {int i = Random.Range(0, JumpClips.Length);AudioSource.PlayClipAtPoint(JumpClips[i], transform.position);}}private void Flip() {// 修改当前朝向FacingRight = !FacingRight;// 修改scale的x分量实现转向this.transform.localScale = Vector3.Scale(new Vector3(-1, 1, 1),this.transform.localScale);}
}

后言

  可以看到,目前角色在运动的时候还没有动画。因为给角色加上动画设计到动画状态机的制作,较为复杂,在下一篇文章将会介绍如何给角色添加动画。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay5分支下看到,读者可以clone这个仓库到本地进行查看。


参考链接

  1. Gravity Scale
  2. Conventional Game Input
  3. Physics Material 2D

《土豆荣耀》重构笔记(七)控制角色移动并添加音效相关推荐

  1. Vue.js 学习笔记 七 控制样式

    Vue.js可以灵活的控制样式 我们首先随便写2个样式 <style>.divCss {background-color: green;width:400px;height:400px;} ...

  2. 《土豆荣耀》重构笔记(五)创建角色以及怪物的动画

    章节目录 前言 创建角色和怪物 创建怪物的动画 创建角色动画 制作Prefab 后言 参考链接 前言   在游戏中,角色和AI的移动都需要配上相应的动画,以免让玩家产生游戏中的角色或者AI在平移的不真 ...

  3. 《土豆荣耀》重构笔记(三)创建游戏场景

    章节目录 前言 导入资源 调整Unity布局 创建游戏场景 设置Aspect 放置Sprite Sorting Layer 组织场景中的物体 后言 参考链接 前言   为了记录重构笔记的进度,我在Gi ...

  4. (完结)Unity游戏开发——新发教你做游戏(七):Animator控制角色动画播放

    文章目录 一.前言 二.Animator状态机组织 三.过渡条件 四.用代码设置过渡条件,触发动画播放 五.CharacterAniLogic.cs完整代码 一.前言 文章列表 Unity游戏开发-- ...

  5. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  6. 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9344721 作者:七十一雾央 新浪微博:http:// ...

  7. 【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练

    [K210]K210学习笔记七--使用K210拍摄照片并在MaixHub上进行训练 前言 K210准备工作 K210如何拍摄照片 准备工作 拍摄相关代码定义 用K210拍摄到的照片在MaixHub平台 ...

  8. window的dos命令学习笔记 七

    文章目录 一.dos历史学习笔记(后期整合到这里,我想能学到这里的应该不多了,嘿嘿,加油) 二.执行状态返回值(`%errorlevel%`,和shell中`$?`相似): 三.视窗 1.color ...

  9. jQuery整理笔记七----几个经典表单应用

    1.文本框获得(失去)焦点 当文本框获得输入焦点时,将该文本框高亮显示,算不得一个应用,仅仅是一个小技巧,能够提高用户体验. <!DOCTYPE html PUBLIC "-//W3C ...

  10. jQuery整理笔记七----几个经典表单应用 .

    登录 | 注册 收藏成功 确定 收藏失败,请重新收藏 确定 标题 标题不能为空 网址 标签 摘要 公开 取消收藏 全部设为已读查看所有通知 暂没有新通知 返回通知列表 下一条 上一条 分享资讯传PPT ...

最新文章

  1. 1. C语言中只能使用单行注释,贵州大学C语言判断题
  2. C++Eratosthenes埃氏筛法获取素数列表的实现算法(附完整源码)
  3. 授人以鱼不如授人以渔——CPU漏洞的Symantec解决之道
  4. 《PHP精粹:编写高效PHP代码》——1.1节为什么要使用面向对象编程
  5. 接口500什么原因_80%小餐饮店几乎都“活“不过500天,为什么?都在这5个原因里...
  6. Oracle11完全卸载方法
  7. Redis系列 --第一篇
  8. e盾服务端源码_原罪西游源码发布!!!
  9. Java Servlet(八):EL自定义函数
  10. tidyr | 批量处理数据的前奏——数据嵌套化
  11. vector, list, deque的使用区别
  12. windows桌面待办事项_想拒绝拖延症?你还缺一款云同步提醒的的桌面便签软件!...
  13. 容器(Context)使用之支付系统
  14. (转)log4j(二)——如何控制日志信息的输出?
  15. ios 启动图一键生成工具_一键生成App图标所有尺寸的三个酷站分享
  16. 超好看的QQ群管机器人html官网源码
  17. 惠普扫描应用程序当前正由此计算机上的其,惠普打印机 打印扫描的时候显示“由于另一个程序或另一台计算机正在使用联网的HP成像设备因此无法执行”...
  18. 李宏毅2020机器学习深度学习(完整版)国语课程PPT
  19. 工业大数据的关键技术是什么
  20. 什么叫云计算?云计算通俗解释

热门文章

  1. python爬虫英文翻译_python爬虫学习---爬取微软必应翻译(中英互译)
  2. ThinkPHP5旅游管理系统
  3. dell 服务器ghost系统,Dell 5000笔记本装win7 64位Ghost系统真正成功教程
  4. 无法创建堆栈的防护页面 解决方法
  5. 网络安全-SQL注入原理、攻击及防御
  6. A_A03_001 stc-isp 单片机烧录软件安装与使用
  7. 《廖雪峰python3教程》| 书评 + 学习笔记干货
  8. 2022-2028全球记账软件行业调研及趋势分析报告
  9. 活学活用pic单片机c语言编程pdf,活学活用PIC单片机C语言编程
  10. 在java中调用python程序