文章目录
- 前言
- 定义基类
- 实现不同的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){// 将玩家的生命值增加 5player.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);// 重新启动协程 CallItemUpdateStartCoroutine(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 方法,传入掉落的物品类型,并将返回值赋值给 itemitem = 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。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~