目录

8 添加生命系统

演示效果

9 使用触发器实现吃血包

9.1 添加一个可以被吃掉的血包

10 使用触发器添加伤害区域

10.1 设置伤害区域

10.2 设置无敌时间

关于无敌时间的讨论

10.3 平铺伤害区域/平铺精灵

1 精灵渲染器Draw Mode -> Tiled

2 精灵素材中Mesh Type -> Full Rect

3 2D碰撞体组件 -> 勾选Auto Tilling

11 添加敌人

11.1 敌人来回移动

11.2 敌人伤害

Collision2D 2D碰撞类


学习的教程

【unity2021入门教程】68-2D游戏开发教程系列-03-RubyAdventure2DRpg官方教程-16-完善触发器代码_哔哩哔哩_bilibili

已进行步骤

【Unity入门计划】制作RubyAdventure01-玩家的创建&移动_flashinggg的博客-CSDN博客

【Unity入门计划】制作RubyAdventure02-处理瓦片地图&碰撞_flashinggg的博客-CSDN博客

8 添加生命系统

先在之前的Ruby Controller脚本中,加上一个简单的生命上限&规定初始生命值

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RubyController : MonoBehaviour
{//设置最大生命值(生命上限)public int maxHealth = 5;//当前生命值,默认为0private int currentHealth;private void Start(){//初始化当前生命值currentHealth = maxHealth;}// 每帧都会执行一次Update函数void Update(){...}//控制速度,比update快一点void FixedUpdate(){ChangeHealth(1);}//更改生命值//amount是游戏中加血/减血的操作void ChangeHealth(int amount){//限制当前生命值范围为[0,maxHealth]currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);//输出Debug.Log("当前生命值为:" + currentHealth + "/" + maxHealth);}
}

演示效果

9 使用触发器实现吃血包

之前写过一个触发器的简单博客:【Unity入门计划】基本概念(2)-触发器 Trigger_flashinggg的博客-CSDN博客

它是一个特殊的碰撞体,只检测碰撞,不阻止移动。

9.1 添加一个可以被吃掉的血包

关于数据保护内容,我另开了一个博客进行简单的记录介绍:【Unity入门计划】Unity实例-C#如何通过封装实现对数据成员的保护

先从Project中加入一个可以充当血包的精灵,同时创建一个预制件,给他一个2D碰撞体并设置为触发器。

挂一个检测触发并进行相应设置的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class HealthCollectible : MonoBehaviour
{//设置每次碰撞加的血量public int amount = 1;private int CollideTimes;//添加触发器事件,每次碰撞触发器时执行其中的代码private void OnTriggerEnter2D(Collider2D other){CollideTimes++;Debug.Log($"和当前物体发生碰撞的是:{other},当前是第{CollideTimes}次发生碰撞!");//获取Ruby对象的脚本组件,还是用GetComponent方法RubyController rubyController=other.GetComponent<RubyController>();if(rubyController != null){//血量+1if (rubyController.health<rubyController.maxHealth){rubyController.ChangeHealth(amount);//销毁血包Destroy(gameObject);}else Debug.Log("血量已满!");}else{Debug.LogError("未获取到当前游戏对象");}}
}

同时RubyController中也要定义一个属性,访问私有变量currentHealth。

    //设置最大生命值(生命上限)public int maxHealth = 5;//当前生命值,默认为0internal int currentHealth;//C#中支持面向对象程序设计中的封装,实现对数据成员进行保护//数据成员变量本身是私有的,只能通过某一种方法或者属性访问//属性是共有的,可以通过取值器--get,赋值器--set,设定对应字段的访问规则//满足规则才能访问该成员变量public int health { get { return currentHealth; } }

这里只贴出了结果代码,具体过程直接参考对应的教程即可。

10 使用触发器添加伤害区域

10.1 设置伤害区域

还是跟之前一样,添加伤害区域精灵,变成预制体,勾选Is Trigger,再挂脚本实现一些进入后减血的操作。

挂一个减血脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DamageZone : MonoBehaviour
{public int damageHealth = -1;public int damageSpeed;private double TruedamageHealth = -0.02;private double True = 0;int round=1;private void OnTriggerStay2D(Collider2D other){RubyController rubyController=other.GetComponent<RubyController>();if(rubyController != null){True += damageSpeed*TruedamageHealth;if (round==1||True < round * damageHealth){round++;rubyController.ChangeHealth(damageHealth);}}}
}

这里我优化了一下,加入了可以控制减血速度的变量,详情可以看:【Unity入门计划】用双血条方法控制伤害区域减血速度_flashinggg的博客-CSDN博客

10.2 设置无敌时间

关于无敌时间的讨论

教程中把无敌时间设置在了玩家减血的方法里,意思就是无论伤害来自敌人还是来自陷阱,只要受到伤害,就会进入2秒的无敌时间。

先讨论一下这个方法是否无敌:

  1. 我们假设Ruby走入了陷阱,血量-1,由于受到伤害进入了无敌时间(教程中设置为2s),此时Ruby有2s的时间赶快离开陷阱!这2s里Ruby将不受任何攻击的影响,过了无敌时间后就恢复到会受到攻击的状态。同时,如果想要更贴近现有游戏的情景,无敌时间也会伴随着玩家的闪烁,以此展示当前处于无敌状态了。
  2. 我们假设Ruby被敌人发射炮弹/近身攻击了!血量-1,此时Ruby进入了无敌状态,此时敌人发射的连续炮弹、进行的连招攻击将不再有多重伤害的减血效果。

因此,我认为对于一个基础教程的游戏项目制作,把脚本直接挂在玩家对象上是可行的,意味着敌人也是基础的敌人、没有可以“连招攻击”的敌人,也没有叠加伤害一说。

如果希望敌人进行的连招攻击会对玩家造成叠加伤害,最好是将无敌时间的脚本挂在陷阱、敌人身上,便于修改。

这里因为只是跟着教程学习,因此我就跟着教程思路走,还是把脚本挂在玩家身上。

加入了无敌时间系统的玩家脚本代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RubyController : MonoBehaviour
{//设置无敌时间public float timeInvincible = 2.0f;//设置判断是否无敌的bool变量bool isInvincible;//规定一个无敌时间计数器,倒计时float invincibleTimer;//声明刚体对象Rigidbody2D rigidbody2D;//在方法外声明水平和数值量float horizontal;float vertical;//设置最大生命值(生命上限)public int maxHealth = 5;//当前生命值,默认为0private int currentHealth;//C#中支持面向对象程序设计中的封装,实现对数据成员进行保护//数据成员变量本身是私有的,只能通过某一种方法或者属性访问//属性是共有的,可以通过取值器--get,赋值器--set,设定对应字段的访问规则//满足规则才能访问该成员变量public int health { get { return currentHealth; } }private void Start(){//游戏运行前,获取当前游戏对象的刚体组件//这里用到了GetComponent获取当前所在对象的吗某个组件 - GetComponent<>() rigidbody2D = GetComponent<Rigidbody2D>();//初始化当前生命值currentHealth = maxHealth;}// 每帧都会执行一次Update函数void Update(){//判断是否无敌if (isInvincible){//是,则计时器开始倒计时:deltaTime获取两帧之间的时间间隔invincibleTimer -= Time.deltaTime;if (invincibleTimer < 0){isInvincible = false;//倒计时结束,不再是无敌时间    }}//声明新变量//获取水平轴并储存在新变量中horizontal = Input.GetAxis("Horizontal");//获取垂直轴vertical = Input.GetAxis("Vertical");}//控制速度,比update快一点void FixedUpdate(){Vector2 position = transform.position;//对x轴移动距离做了细微的更改position.x += horizontal * 3.0f * Time.deltaTime;//对y轴也做相应更改position.y += vertical * 3.0f * Time.deltaTime;rigidbody2D.position = position;}//更改生命值//amount是游戏中加血/减血的操作public void ChangeHealth(int amount){if (amount < 0)//if >0加血,则不进入无敌时间{if (isInvincible)//当前处于无敌状态,则不减血{return;//直接中段当前方法}//不是无敌状态,接下来会减血,因此提前改成trueisInvincible = true;//重置计时器invincibleTimer = timeInvincible;}//限制当前生命值范围为[0,maxHealth]currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);//输出Debug.Log("当前生命值为:" + currentHealth + "/" + maxHealth);}}

10.3 平铺伤害区域/平铺精灵

有时候需要平铺伤害区域,Unity自带有平铺精灵的功能。

1 精灵渲染器Draw Mode -> Tiled

还记得精灵渲染器里的Draw Mode,默认是Simple,选择Tiled

2 精灵素材中Mesh Type -> Full Rect

在对应的精灵素材属性中,Mesh Type选择Full Rect

再进入Scene中调整当前游戏对象,T键框选,发现可以实现平铺了。

还需要将碰撞体也平铺对应

3 2D碰撞体组件 -> 勾选Auto Tilling

此时就完成了伤害区域平铺的操作了。

11 添加敌人

首先需要在官网下载敌人Robot的图片。

世界交互 - 伤害区域和敌人 - Unity Learn

同样的操作,再Unity中把他变成精灵,挂上Order的脚本。

11.1 敌人来回移动

关于来回移动代码的编写,可以看看我的这篇博客:【Unity入门计划】2D游戏实现敌人来回移动控制脚本

11.2 敌人伤害

这里想要实现Ruby碰撞敌人后,掉血的操作。由于需要真实的碰撞感,因此不能使用之前的OnTriggerEnter,而是采取碰撞检测。

    //碰撞检测//添加敌人伤害的逻辑private void OnCollisionEnter2D(Collision2D other){//获取和当前collision碰撞的对象的脚本组件RubyController player = other.gameObject.GetComponent<RubyController>();if (player != null){player.ChangeHealth(Hurt);}}

Collision2D 2D碰撞类

官方文档:UnityEngine.Collision2D - Unity 脚本 API

在之前的一篇【Unity入门计划】基本概念(2)-触发器 Trigger中就有说到碰撞检测的三种类别。

在【Unity入门计划】Collision2D类&Collider2D类这篇博客中针对涉及到两个不同类的碰撞检测和触发检测,我对它们的回调函数在脚本中的使用进行一个简单的讨论。

【Unity入门计划】制作RubyAdventure03-使用碰撞体触发器实现世界交互相关推荐

  1. 【Unity入门计划】基本概念(8)-瓦片地图 TileMap 01

    目录 1 TileMap概念 主要思想 优点 创建的层级 2 Unity中的TileMap 2.1 自动父级Grid 网格 2.2 Sprite精灵 2.3 Tile 瓦片 2.4 Tile Pale ...

  2. 【Unity】物理系统的静态碰撞体、刚体碰撞体、Kinematic刚体碰撞体

    碰撞体分为三类(触发器同理):静态碰撞体.刚体碰撞体.Kinematic刚体碰撞体. 静态碰撞体:不挂载刚体组件的碰撞体 常用于地形.障碍物等不会移动位置的物体,物理引擎会对此优化性能.在游戏运行时, ...

  3. 【Unity入门计划】CreatorKitFPS:第一人称射击3D小游戏

    目录 Unity学习教程 1 添加并载入项目资源 添加项目资源 载入到Unity 2 载入Scene 3 从预制体添加射击Targets 4 管理游戏对象 4.1创建分组关系 4.2 区分相对坐标&a ...

  4. 【Unity入门计划】playground项目:2D飞船移动小游戏

    目录 跟学的Unity教程 我的Unity版本 1 导入playground项目资源 2 创建新场景 3 创建玩家飞船 3.1 调整大小位置 3.2 调整Game视图的背景 3.3 Inspector ...

  5. 【Unity入门计划】基本概念(1)-2D刚体Rigidbody 2D

    目录 官方参考文档 我的Unity版本 Rigidbody刚体的作用 Rigidbody 2D的添加 Rigidbody的面板属性 Body Type 刚体类型 Body Type -> Dyn ...

  6. 【Unity入门计划】基本概念(4)-预制件 Prefab

    目录 官方文档 相关教程 我的Unity版本 1 预制件的作用 2 预制件的定义 3 预制件的优点 4 一般使用的场景 5 预制件的创建&使用 5.1 创建 5.2 使用 6 预制件的编辑 6 ...

  7. 【Unity入门计划】界面介绍(1)-Scene视图

    目录 正式记录前的废话 Unity的坐标系 2D/3D视图转换 视图的移动.旋转.缩放 移动 旋转 缩放 选中游戏对象Game Object 单选 多选 设置不允许选中 场景可见性 游戏对象的移动.变 ...

  8. 【Unity入门计划】Unity2D动画(1)-动画系统的组成及功能的使用

    目录 Unity动画 1 Unity动画系统:MEcanim 该动画系统中常见的术语 2 游戏对象的Animator组件 组件属性 Controller 控制器 Avatar 骨骼 Apply Roo ...

  9. 【Unity入门计划】Unity2D动画(2)-脚本与混合树实现玩家角色动画过渡

    目录 1 玩家角色移动伴随的简单动画 1.1 行走 1.2 停留 1.3 攻击敌人(触发型) 1.4 受伤(触发型) 1.5 跳跃 1.6 下蹲 2 动画间的过渡 3 过渡的判断逻辑 3.1 行走与停 ...

最新文章

  1. visualVM 安装使用
  2. BigDecimalf大小的比较
  3. mac、linux 查看端口占用程序
  4. 外媒:社交媒体的大量使用与精神疾病有关
  5. 目前最先进的目标检测能用于自动驾驶吗?这群德国人认真地做了个测评!
  6. el-button点击后颜色消失_第八十三式:Word也可以点击填充文本
  7. ul li横向排列及圆点处理
  8. php 页面异步刷新,php+jQuery+Ajax简单实现页面异步刷新
  9. 阿尔法贝塔阀原理_臭氧投加在污水处理中的应用_美国阿尔法Alpha
  10. 斐波那契数列的量化分析
  11. Web Components 小榄
  12. SpringBoot入门——使用Swagger构建Restful API文档
  13. 240.搜索二维矩阵II
  14. 微信小程序时间轴demo_微信小程序 - 时间轴(组件)
  15. 信息处理技术员下午考试试题分析
  16. Python经典面试题解析:实现斐波那契数列
  17. new115.com dz.html,超实用的HTML代码段(赵荣娇)
  18. 如何成为一个优秀的测试工程师
  19. docker入门命令
  20. webshell一句话

热门文章

  1. Android后台驻留:保活和回收的机制
  2. java实现国密算法
  3. 微信授权获取openID等信息,这里简化记录一下
  4. uniapp实现底部凸起的tabbar
  5. SCAU2022春季个人排位赛第五场
  6. 空间三角形重心坐标计算方法
  7. 轻量级分布式 RPC 框架DIY(转)
  8. CSS设置文字镂空效果
  9. 【为Android 应用创建 XML 布局】
  10. 程序员麦兜【编程笔记】-String存储管理