【unity实战】如何更加规范的创建各种Rogue-Lite(肉鸽)风格的物品和BUFF效果(附项目源码)

简介: 【unity实战】如何更加规范的创建各种Rogue-Lite(肉鸽)风格的物品和BUFF效果(附项目源码)

前言

当创建各种Rogue-Lite(肉鸽)风格的游戏时,物品和BUFF效果是非常重要的元素之一。为了更加规范地创建这些物品和BUFF效果,可以使用抽象类来定义不同的BUFF。

那么什么是抽象类呢?他的用法?为什么用它?好处是什么呢?

在Unity中,抽象类是一种特殊的类,它不能被实例化,只能被用作其他类的基类。抽象类通常用于定义一些通用的行为和属性,但并不提供具体的实现细节。其目的是让子类来实现这些抽象方法和属性,以便根据具体的需求进行定制化。

使用抽象类的主要原因是为了实现代码的重用和统一性。抽象类可以定义一些通用的方法和属性,从而避免在多个类中重复编写相似的代码。同时,它也可以作为约定,强制子类实现特定的方法和属性,确保了程序的一致性和可扩展性。

抽象类的主要好处包括:

  1. 提供了一种模板化的设计方式,使得代码更易维护和扩展。
  2. 强制了子类必须实现抽象方法和属性,从而减少了程序出错的可能性。
  3. 通过抽象类可以实现多态性,使得代码更加灵活和可复用。

在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

目录
相关文章
|
3月前
|
编译器 vr&ar 图形学
从零开始的unity3d入门教程(五)---- 基于Vuforia的AR项目
这是一篇Unity3D结合Vuforia实现增强现实(AR)项目的入门教程,涵盖了环境配置、Vuforia账户注册、Target数据集创建、Unity项目设置、AR程序配置、Android环境配置以及最终在手机上测试运行的全过程。
从零开始的unity3d入门教程(五)---- 基于Vuforia的AR项目
|
3月前
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
78 1
|
3月前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
2月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
201 0
|
3月前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
120 0
|
3月前
|
开发者 图形学 C#
揭秘游戏沉浸感的秘密武器:深度解析Unity中的音频设计技巧,从背景音乐到动态音效,全面提升你的游戏氛围艺术——附实战代码示例与应用场景指导
【8月更文挑战第31天】音频设计在游戏开发中至关重要,不仅能增强沉浸感,还能传递信息,构建氛围。Unity作为跨平台游戏引擎,提供了丰富的音频处理功能,助力开发者轻松实现复杂音效。本文将探讨如何利用Unity的音频设计提升游戏氛围,并通过具体示例代码展示实现过程。例如,在恐怖游戏中,阴森的背景音乐和突然的脚步声能增加紧张感;在休闲游戏中,轻快的旋律则让玩家感到愉悦。
84 0
|
5月前
|
存储 JSON 关系型数据库
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
159 2
|
3月前
|
图形学 C#
超实用!深度解析Unity引擎,手把手教你从零开始构建精美的2D平面冒险游戏,涵盖资源导入、角色控制与动画、碰撞检测等核心技巧,打造沉浸式游戏体验完全指南
【8月更文挑战第31天】本文是 Unity 2D 游戏开发的全面指南,手把手教你从零开始构建精美的平面冒险游戏。首先,通过 Unity Hub 创建 2D 项目并导入游戏资源。接着,编写 `PlayerController` 脚本来实现角色移动,并添加动画以增强视觉效果。最后,通过 Collider 2D 组件实现碰撞检测等游戏机制。每一步均展示 Unity 在 2D 游戏开发中的强大功能。
172 6
|
2月前
|
测试技术 C# 图形学
掌握Unity调试与测试的终极指南:从内置调试工具到自动化测试框架,全方位保障游戏品质不踩坑,打造流畅游戏体验的必备技能大揭秘!
【9月更文挑战第1天】在开发游戏时,Unity 引擎让创意变为现实。但软件开发中难免遇到 Bug,若不解决,将严重影响用户体验。调试与测试成为确保游戏质量的最后一道防线。本文介绍如何利用 Unity 的调试工具高效排查问题,并通过 Profiler 分析性能瓶颈。此外,Unity Test Framework 支持自动化测试,提高开发效率。结合单元测试与集成测试,确保游戏逻辑正确无误。对于在线游戏,还需进行压力测试以验证服务器稳定性。总之,调试与测试贯穿游戏开发全流程,确保最终作品既好玩又稳定。
98 4
|
3月前
|
图形学 缓存 算法
掌握这五大绝招,让您的Unity游戏瞬间加载完毕,从此告别漫长等待,大幅提升玩家首次体验的满意度与留存率!
【8月更文挑战第31天】游戏的加载时间是影响玩家初次体验的关键因素,特别是在移动设备上。本文介绍了几种常见的Unity游戏加载优化方法,包括资源的预加载与异步加载、使用AssetBundles管理动态资源、纹理和模型优化、合理利用缓存系统以及脚本优化。通过具体示例代码展示了如何实现异步加载场景,并提出了针对不同资源的优化策略。综合运用这些技术可以显著缩短加载时间,提升玩家满意度。
138 5