文章目录
- 前言
- 定义基类
- 实现不同的BUFF效果
- 一、回血BUFF
- 1. 简单的回血效果实现
- 2. BUFF层数控制回血量
- 二、攻击附带火焰伤害
- 三、治疗领域
- 1. 简单的治疗领域实现
- 2. 添加技能冷却时间
- 通过拾取物品获取对应的BUFF
- 参考
- 源码
- 完结
前言
当创建各种Rogue-Lite(肉鸽)风格的游戏时,物品和BUFF效果是非常重要的元素之一。为了更加规范地创建这些物品和BUFF效果,可以使用抽象类来定义不同的BUFF。
那么什么是抽象类呢?他的用法?为什么用它?好处是什么呢?
在Unity中,抽象类是一种特殊的类,它不能被实例化,只能被用作其他类的基类。抽象类通常用于定义一些通用的行为和属性,但并不提供具体的实现细节。其目的是让子类来实现这些抽象方法和属性,以便根据具体的需求进行定制化。
使用抽象类的主要原因是为了实现代码的重用和统一性。抽象类可以定义一些通用的方法和属性,从而避免在多个类中重复编写相似的代码。同时,它也可以作为约定,强制子类实现特定的方法和属性,确保了程序的一致性和可扩展性。
抽象类的主要好处
包括:
- 提供了一种模板化的设计方式,使得代码更易维护和扩展。
- 强制了子类必须实现抽象方法和属性,从而减少了程序出错的可能性。
- 通过抽象类可以实现多态性,使得代码更加灵活和可复用。
在Unity中,经常会用到抽象类来定义一些通用的行为或者规范,例如定义一个抽象的游戏角色类,其中定义了移动、攻击等方法,然后具体的角色类(如玩家角色、敌对角色等)继承并实现这些方法。这样可以保持代码的一致性和可维护性。
总之,抽象类在Unity中的使用可以帮助我们更好地组织和管理代码,提高代码的复用性和可维护性。
定义基类
物品就是
物品BUFF
,下面我都会用物品
作为注释
新增Item,定义一个名为 Item 的物品BUFF抽象类
[System.Serializable]
public abstract class Item
{
// 定义BUFF名称
public abstract string GiveName();
// 定义一个虚方法 Update,其中 player 表示玩家对象,stacks 表示物品的叠加数量(及BUFF层数)
public virtual void Update(Player player, int stacks){ }
}
新增ItemList,定义物品BUFF列表参数
[System.Serializable]
public class ItemList
{
// 表示物品
public Item item;
// 表示名称
public string name;
// 表示叠加数量(及BUFF层数)
public int stacks;
// 构造函数,用于初始化 ItemList 对象
public ItemList(Item newItem, string newName, int newStacks)
{
item = newItem;
name = newName;
stacks = newStacks;
}
}
实现不同的BUFF效果
一、回血BUFF
1. 简单的回血效果实现
定义一个名为 HealingItem 的类,继承自 Item,定义回血BUFF
public class HealingItem : Item
{
public override string GiveName()
{
return "回血BUFF";
}
public override void Update(Player player, int stacks)
{
// 将玩家的生命值增加 5
player.health += 5;
}
}
新增玩家脚本,调用BUFF
public class Player : MonoBehaviour
{
// 表示玩家的生命值
public int health;
// 表示玩家的物品BUFF列表
public List<ItemList> items = new List<ItemList>();
void Start()
{
HealingItem item = new HealingItem();
// 将回血BUFF对象添加到物品列表中
items.Add(new ItemList(item, item.GiveName(), 1));
StartCoroutine(CallItemUpdate());
}
IEnumerator CallItemUpdate()
{
// 遍历物品列表中的每个物品
foreach (ItemList i in items)
{
// 调用物品的 Update 方法
i.item.Update(this, i.stacks);
}
//暂停1秒继续执行
yield return new WaitForSeconds(1);
// 重新启动协程 CallItemUpdate
StartCoroutine(CallItemUpdate());
}
}
运行效果,角色每秒回5点血
2. BUFF层数控制回血量
修改HealingItem
public override void Update(Player player, int stacks)
{
// 将玩家的生命值增加
player.health += 3 + (2 * stacks);
}
效果,两层每秒加7血
二、攻击附带火焰伤害
新增敌人脚本,定义敌人生命值
public class Enemy : MonoBehaviour {
public int health;
}
修改Item,定义攻击事件
public virtual void OnHit(Player player, Enemy enemy, int stacks){ }
新增FireDamageItem,实现火焰攻击效果
public class FireDamageItem : Item
{
public override string GiveName()
{
return "火焰攻击";
}
public override void OnHit(Player player, Enemy enemy, int stacks)
{
enemy.health -= 10 * stacks;
}
}
修改Player,默认加2层火焰攻击效果
// 表示玩家的攻击力
public int attackDamage;
void Start()
{
FireDamageItem item = new FireDamageItem();
items.Add(new ItemList(item, item.GiveName(), 2));
}
public void CallItemOnHit(Enemy enemy)
{
foreach (ItemList i in items)
{
i.item.OnHit(this, enemy, i.stacks);
}
}
新增PlayerHitbox,定义攻击判定,攻击附加额外火焰攻击BUFF伤害
public class PlayerHitbox : MonoBehaviour
{
public Player player;
//触发器检测
private void OnTriggerEnter(Collider other)
{
// 判断进入碰撞体的对象是否为敌人
if (other.tag == "Enemy")
{
Enemy enemy = other.GetComponent<Enemy>();
// 减少敌人的生命值,减少的值为玩家的攻击力
enemy.health -= player.attackDamage;
// 调用玩家的 CallItemOnHit 方法,附加额外伤害
player.CallItemOnHit(enemy);
}
}
}
效果,攻击附带额外伤害
三、治疗领域
实现治疗领域效果一般需要加载一些特性,而我们定义的BUFF是没办法挂载特效物品的,这时候就需要使用
Resources
加载指定的特效了
1. 简单的治疗领域实现
绘制预制体
修改Item,定义跳跃方法
public virtual void OnJump(Player player, int stacks) { }
新增HealingArea,实现跳跃方法生成治疗领域
public class HealingArea : Item
{
//特效
GameObject effect;
public override string GiveName()
{
return "治疗领域";
}
public override void OnJump(Player player, int stacks)
{
if (effect == null) effect= (GameObject)Resources.Load("Item Effects/Healing Area", typeof(GameObject));
GameObject healingArea = GameObject.Instantiate(effect, player.transform.position, Quaternion.Euler(Vector3.zero));
}
}
修改Player,实现每次按Space,执行治疗领域OnJump方法
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CallItemOnJump();
}
}
public void CallItemOnJump()
{
foreach (ItemList i in items)
{
i.item.OnJump(this, i.stacks);
}
}
效果,每次跳跃生成一个治疗光环
2. 添加技能冷却时间
修改HealingArea
public class HealingArea : Item
{
GameObject effect;
float internalCoolDown;//技能冷却时间
public override string GiveName()
{
return "Healing Area";
}
public override void Update(Player player, int stacks)
{
internalCoolDown -= 1;
}
public override void OnJump(Player player, int stacks)
{
if (internalCoolDown <= 0)
{
if (effect == null) effect = (GameObject)Resources.Load("Item Effects/Healing Area", typeof(GameObject));
GameObject healingArea = GameObject.Instantiate(effect, player.transform.position, Quaternion.Euler(Vector3.zero));
internalCoolDown = 10;//技能冷却时间默认定义10秒
}
}
}
效果,每10秒才能释放一次治疗光环
通过拾取物品获取对应的BUFF
新增ItemPickup ,物品拾取类
public class ItemPickup : MonoBehaviour
{
// 掉落的物品对象
public Item item;
// 物品类型
public Items itemDrop;
void Start()
{
// 调用 AssignItem 方法,传入掉落的物品类型,并将返回值赋值给 item
item = AssignItem(itemDrop);
}
// 触发器检测
private void OnTriggerEnter(Collider other)
{
// 判断进入碰撞体的对象是否为玩家
if (other.tag == "Player")
{
// 获取玩家对象
Player player = other.GetComponent<Player>();
// 调用 AddItem 方法,传入玩家对象
AddItem(player);
// 销毁 Pickup 对象
Destroy(this.gameObject);
}
}
public Item AssignItem(Items itemToAssign)
{
// 根据不同的物品类型返回不同的物品对象
switch (itemToAssign)
{
case Items.HealingItem:
return new HealingItem();
case Items.FireDamageItem:
return new FireDamageItem();
case Items.HealingAreaItem:
return new HealingArea();
default:
return new HealingItem();
}
}
public void AddItem(Player player)
{
// 遍历玩家物品列表中的每个物品
foreach (ItemList i in player.items)
{
// 如果该物品已经存在于列表中,则将该物品的叠加数量加 1,并直接返回
if (i.name == item.GiveName())
{
i.stacks += 1;
return;
}
}
// 将新的物品添加到玩家物品列表中
player.items.Add(new ItemList(item, item.GiveName(), 1));
}
}
// 定义一个公共枚举类型 Items,表示所有可用的物品类型
public enum Items
{
HealingItem,
FireDamageItem,
HealingAreaItem
}
修改Player,删除前面旧的BUFF添加
// HealingItem item = new HealingItem();
// items.Add(new ItemList(item, item.GiveName(), 1));
// FireDamageItem item = new FireDamageItem();
// items.Add(new ItemList(item, item.GiveName(), 2));
新增各种BUFF物品,配置预制体
效果,拾取物品即可获取对应的BUFF效果
ps:后续要加入其他BUFF,直接就可以修改ItemPickup很方便的进行添加定义即可
参考
【视频】https://www.youtube.com/watch?v=iU6mKyQjOYI
源码
https://gitcode.net/unity1/unity-roguelitebuff
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~