2021-9-4 爆肝一整天,关于2D横板游戏中攀爬楼梯的考虑
今日份关于2D横板游戏中攀爬楼梯的考虑
- 引言
- 关于攀爬楼梯考虑
- 总体考虑
- 玩家站在1处
- 玩家站在2处
- 玩家通过跳跃来到3处
- 1处升至3处 和 2处降至3处
- 3处升至2处
- 3处降至1处
- 其他考虑
- 解决方案及代码
- 动画条件
- 解决代码(非完全代码)
- 首先是一些设置
- 初始化
- 然后,重点来了,各类情况分析
- 最重要的几点分析(前提时在梯子范围内)
- 两个检测函数
- 考虑梯子上的受力情况
- 各类函数实现,没什么好说的
- 最坑爹的地方来了,如何判断在梯子范围内和位于梯子底部
- 结束
- 下面放几张效果图
- 梯子底部不影响下蹲
- 底部向上攀爬
- 停留在梯子上
- 战立在梯子顶端
- 顶部向下攀爬
引言
以前觉得2D横板游戏制作起来很简单,殊不知一个小小的动作就需要考虑这么多要素。通过对这个小小的2D横版游戏的设计,我对那些开发出好玩炫酷兼顾打击手感,不停琢磨提高游戏的性能及优化的开发者们的敬意油然而生啊!!!
关于攀爬楼梯考虑
总体考虑
- 玩家在梯子上将不能左右移动,不能跳跃
- 增加梯子上的停留动画,保证在梯子上停留时不会出现原地攀爬的情况
玩家站在1处
- 按下s键,仍应播放下蹲动作,而不是攀爬下降动作,无竖直方向受力
- 按下w键,播放攀爬上升动作,受力向上
玩家站在2处
- 按下w键,不播放攀爬上升动画,无竖直方向受力
- 按下s键, 播放攀爬下降动画,受力向下
玩家通过跳跃来到3处
- 按下w键,播放攀爬上升动画,受力向上
- 按下s键,播放攀爬下降动画,受力向下
1处升至3处 和 2处降至3处
- 暂时没想到有什么可考虑的
3处升至2处
- 停止播放攀爬上升动画,播放站立动画
- 不影响跳跃(检测盒子检测到的不再是地面)
- 下蹲无效
- 到达桥的顶点后,桥上是可以站立的
3处降至1处
- 停止播放攀爬下降动画,播放站立动画
- 不影响跳跃(检测盒子检测到再次变成地面)
- 不影响下蹲
其他考虑
- 到达梯子什么地方可以攀爬,如果太宽,可能会出现没有借助梯子而是悬空攀爬的情况
- 被攻击就会掉落
解决方案及代码
情况极其复杂,经过今天一整天的调试,我才成功得完成我对于攀爬的各种需求。
动画条件
- 很明显,我将跳跃与下落分开,然后又将向上攀爬,向下攀爬,停止攀爬分开。
- 本来连线还是较为简单的,因为将转换状态时间设置为0,为通过不断调试,发现多条连线尽管不需要转换时间,但如果没有直接连通的线,仍会出现许多不合常理的bug。例如到梯子顶部仍无法结束攀爬动画的情况。因此,经过不断调试,我增加了很多连线。
解决代码(非完全代码)
自己动手敲一敲哦,就会发现这其中还是很消耗脑细胞的。
首先是一些设置
[Header("地面检测盒子的高度")]public float BoxHeight = 0.2f;[Header("地面检测层")]public LayerMask groundMask;[Header("桥检测层")]public LayerMask bridgeMask;[Header("攀爬速度")]public float ClimbSpeed = 10.0f;private bool isOnLadder = false; // 是否在梯子上private bool isClimb = false; // 是否正在攀爬[HideInInspector]public bool bridgeBottom = false; // 是否在梯子底[HideInInspector]public bool bridgeTop = false; // 是否在梯子顶private Animator _animator;private Rigidbody2D _rigidbody2D;private Collider2D _collider2D;private Collider2D BridgeCollider;private Vector2 playersize; // 玩家大小private Vector2 boxsize; // 检测盒子尺寸// 所有状态参数的id定义#regionprivate int id_run;private int id_jump;private int id_fall;private int id_climbup;private int id_climbdown;private int id_onladder;private int id_bridgebottom;private int id_bridgetop;private int id_crouch;private int id_hurt;#endregion
初始化
void Awake(){_animator = GetComponent<Animator>();_rigidbody2D = GetComponent<Rigidbody2D>();_collider2D = GetComponent<Collider2D>();playersize = GetComponent<SpriteRenderer>().bounds.size;boxsize = new Vector2(playersize.x * 0.3f, BoxHeight); // 设置检测盒的大小healthscontroller = GameObject.FindGameObjectWithTag("healths").GetComponent<HealthsController>();BridgeCollider = GameObject.FindGameObjectWithTag("bridgetop").GetComponent<Collider2D>();// 所有状态参数转为其id,提高性能#regionid_run = Animator.StringToHash("run");id_jump = Animator.StringToHash("jump");id_fall = Animator.StringToHash("fall");id_climbup = Animator.StringToHash("climbup");id_climbdown = Animator.StringToHash("climbdown");id_onladder = Animator.StringToHash("onladder");id_bridgebottom = Animator.StringToHash("bridgebottom");id_bridgetop = Animator.StringToHash("bridgetop");id_crouch = Animator.StringToHash("crouch");id_hurt = Animator.StringToHash("hurt");#endregion}
然后,重点来了,各类情况分析
// Update is called once per framevoid Update(){// 判断是否到达梯子顶#regionif (bridgeTop){isClimb = false;_animator.SetBool(id_bridgetop, true);}else{_animator.SetBool(id_bridgetop, false);}#endregion// 判断是否到达梯子底#regionif (bridgeBottom){isClimb = false;_animator.SetBool(id_bridgebottom, true);}else{_animator.SetBool(id_bridgebottom, false);}#endregion}private void FixedUpdate(){// 判断在地面上则下落停止if (IsOnGround()){StopFall();_animator.SetBool(id_climbdown, false);_animator.SetBool(id_bridgebottom, true);}// 判断在梯子顶部if (IsOnBridge()){StopFall();bridgeTop = true;BridgeCollider.isTrigger = false; // 空气墙是否有碰撞_animator.SetBool(id_climbup, false);_animator.SetBool(id_crouch, false);}else{bridgeTop = false;}
最重要的几点分析(前提时在梯子范围内)
- 在梯子底部按下w键,执行向上攀爬
- 在梯子顶部按下s键,执行向下攀爬
- 不在梯子顶部按下w键,执行向上攀爬
- 不在梯子底部按下s键,执行向下攀爬
- 按下w或者s键后抬起,执行停止攀爬
// 攀爬楼梯相关if (isOnLadder){_animator.SetBool(id_onladder, true);1.if (Input.GetButton("Climb") && bridgeBottom) {ClimbUp();}2.else if(Input.GetButton("Crouch") && bridgeTop){BridgeCollider.isTrigger = true;ClimbDown();}3.else if (Input.GetButton("Climb") && !bridgeTop){ClimbUp();}4.else if (Input.GetButton("Crouch") && !bridgeBottom){ClimbDown();}5.if (Input.GetButtonUp("Climb") || Input.GetButtonUp("Crouch")){StopClimb();}}else{_animator.SetBool(id_onladder, false);BridgeCollider.isTrigger = true;}}
两个检测函数
// 利用检测盒子检测人物是否在地面上private bool IsOnGround(){Vector2 boxcenter = (Vector2)transform.position + (Vector2.down * playersize.y * 0.5f);return Physics2D.OverlapBox(boxcenter, boxsize, 0, groundMask);}// 利用检测盒子检测人物是否在梯子顶部private bool IsOnBridge(){Vector2 boxcenter = (Vector2)transform.position + (Vector2.down * playersize.y * 0.5f);return Physics2D.OverlapBox(boxcenter, boxsize, 0, bridgeMask);}
考虑梯子上的受力情况
在梯子上停留的话应该是不动的,因此,要将重力倍数设置为0
/// <summary>/// 改变上升下落重力大小的函数,可以让人物没有飘飘的感觉,提升玩家体验/// </summary>private void BetterJump(){if (_rigidbody2D.velocity.y > 0 && !isClimb){_rigidbody2D.gravityScale = JumpUpGravity;}else if (_rigidbody2D.velocity.y < 0 && !isClimb){_rigidbody2D.gravityScale = FallGravity;_animator.SetBool(id_jump, false);_animator.SetBool(id_fall, true);}else if (isOnLadder && !bridgeTop && !bridgeBottom &&isClimb){_rigidbody2D.gravityScale = 0f; // 重力设为0}else{_rigidbody2D.gravityScale = 1.0f;}}
各类函数实现,没什么好说的
// 控制攀爬上升受力及动画private void ClimbUp(){isClimb = true;_animator.SetBool(id_climbup, isClimb);_animator.SetBool(id_climbdown, false);_rigidbody2D.velocity = new Vector2(0, ClimbSpeed);}// 控制攀爬下降受力及动画private void ClimbDown(){isClimb = true;_animator.SetBool(id_climbup, false);_animator.SetBool(id_climbdown, isClimb);_rigidbody2D.velocity = new Vector2(0, -ClimbSpeed);}// 停止攀爬private void StopClimb(){_animator.SetBool(id_climbup, false);_animator.SetBool(id_climbdown, false);_rigidbody2D.velocity = new Vector2(0, 0); // 防止莫名缓慢下落}
最坑爹的地方来了,如何判断在梯子范围内和位于梯子底部
坑爹并不是说它有多难想到,而是本来我觉得主角控制器上的代码已经够多了,所以我就这段代码挂载到和主角发生触发事件的物体上,结果爬了半天爬不上去,一直很鬼畜的停在最底端,播放攀爬动画,但就是上不去。我调试了很久都没效果。后来才发现在梯子底部时,一按向上攀爬,系统自动判定,主角离开了碰撞物体,这点我也很不明白是为什么!!!
// 检测是否在梯子上和梯子底部private void OnTriggerEnter2D(Collider2D collision){if (collision.tag == "bridge"){isOnLadder = true;}if(collision.tag == "bridgebottom"){bridgeBottom = true;}}private void OnTriggerExit2D(Collider2D collision){if (collision.tag == "bridge"){isOnLadder = false;}if (collision.tag == "bridgebottom"){bridgeBottom = false;}}
}
希望有知道为什么的小伙伴不吝赐教,留言交流!
结束
经过一天的调试,总算大功告成
下面放几张效果图
梯子底部不影响下蹲
底部向上攀爬
停留在梯子上
战立在梯子顶端
顶部向下攀爬
大家有什么更好的想法可以和我交流交流哦!
2021-9-4 爆肝一整天,关于2D横板游戏中攀爬楼梯的考虑相关推荐
- 2021-9-2 Cinemachine 不需要写代码的高级跟随摄像机 2D横板游戏应用
Cinemachine在2D横版游戏中的使用方法简介 Cinemachine的下载及导入 Cinemachine基础 设置 简单用法的一些重要的属性(没讲到的暂时就保持默认设置,如果有补充,欢迎评论区 ...
- Unity游戏开发日记(一):独自开发2d横板游戏:Small man(MainMenu主界面)基本构建
目录 一.独自开发想法 前言: 开发构想: 二.主要内容:MainMenu主界面基本构建 (一)预想功能 (二)功能实现 1.主界面UI设计 2.Option功能设计 3.TypeOption功能设计 ...
- Unity 3D下开发2D飞行游戏中的背景滚动
背景滚动 有以下几点必要的: 在Canvas下创建Raw Image组件 背景图片设置为Texture 填充方式为Repeat重复填充方式 C#代码 using UnityEngine; using ...
- 2D动作游戏开发与实现(翻译) .
本文为 cping1982 主持翻译,如有转载,请严格按照如下方式显示标明译文作者及出处,以示尊重! 译者:cping1982 原文:http://blog.csdn.net/cping1982/ar ...
- 用python写跑酷游戏脚本_用python写游戏之2D跑酷游戏(二)
这篇文章介绍2D跑酷游戏中,添加地板资源, 给主角附加重力作用,以及添加游戏控制器和游戏场景的切换. 废话不多说,直接开始. 添加地板资源 定义地板类,继承自pygame.sprite.Sprite ...
- 2D动作游戏开发与实现(翻译)
原文太长,所以将翻译与原文分成了两部分, 主要是讲2D游戏瓦片规则及不规则渲染与角色碰撞原理的. 因为单纯的2D游戏开发过于简单,所以本文尝试结合不同的2D平面游戏并将之归类,列出他们的优缺点,然后讨 ...
- 高二学生爆肝10个月!自学数电在《我的世界》里打造理论最快计算器,5天涨粉1万...
金磊 梦晨 发自 凹非寺 量子位 报道 | 公众号 QbitAI 辛丑牛年(2021),<我的世界>,一高二学生因爆肝在B站火了. 他从未接触过数电,一切从零开始,仅仅是为了搞清计算器的原 ...
- LeCun大佬点赞转发!B站大佬爆肝6个月,目前播放量破百万!
来源:量子位 非计算机专业.神经网络小白,爆肝六个月-- 在<我的世界>里搭建一个卷积神经网络,这是什么神操作? 最近,来自B站up主@辰占鳌头的作品着实火了一把. 他和朋友们合作完 ...
- 再也不用熬夜爆肝做汇报了!PPT生成神器ChatBCG来啦!
来源:新智元 相信不管是学生党,还是上班族,都有为PPT汇报熬夜爆肝的经历...... 光挑选模版和样式就杀死了一堆脑细胞. 而现在,一款能一键自动生成PPT模版和文字可能成为解放生产力的神器,它就是 ...
最新文章
- VRRP和单臂路由的综合运用
- 【Timbre,Amplitude,Pitch】声音的基本属性
- python映射类型-python笔记-映射类型(字典)
- JavaScript实现浏览器菜单的一些功能
- Redis分布式锁---完美实现
- 牛客题霸 [判断二叉树是否对称] C++题解/答案
- [转]C#用SHA对密码加密
- Ubuntu 无法mount解决办法
- 【车辆计数】基于matlab形态学停车场车辆计数【含Matlab源码 628期】
- 匹配滤波器及matlab仿真
- 网络唤醒Wake On Lan
- 注册表启动项设置方法
- order by使用索引列排序时会失效吗?
- Python语言中的注释方法应用
- 做不大的支付宝小程序,逃不脱的付钱关系
- android客户端与服务器端交互 如何保持session
- 编制计算机程序的算法是什么,中国大学MOOC: 编制计算机程序解决问题的过程有:描述问题、算法设计、编写计算机程序和调试等,其中对算法描述不正确的是()。...
- 时间戳转换,在线转换时间戳
- 二极管正向压降测试仪适合在哪里应用?
- 卡梅隆大学计算机排名,2022卡梅隆大学全美排名多少(研究生院)