简单的技能Buff系统 - 纳金网
联系我们

给我们留言

联系我们

地址:福建省晋江市青阳街道洪山路国际工业设计园纳金网

邮箱:info@narkii.com

电话:0595-82682267

(周一到周五, 周六周日休息)

当前位置:主页 > 3D教程 > 图文教程

简单的技能Buff系统

来源: 未知 | 责任编辑:六月芳菲 | 发布时间: 2018-03-07 09:36 | 浏览量:

更多精彩unity教程:http://www.narkii.com/resource/


在本教程中,我将向您展示如何使用可脚本化对象为Unity创建灵活的buff系统。我们将使用可编写脚本的对象作为快速创建和管理buff的方法,而不必使用外部数据类型(如xml或txt文件)。这可以让我们将buff数据从游戏逻辑中分离出来,例如持续时间和统计数据。正如您将看到的那样,这也将允许我们使用CreateAssetMenu属性将我们的可脚本化对象绑定为资产。
我们设计的前提将围绕三个类。玩家类,buff类和buff脚本对象。玩家类作为我们的通用玩家模型,它可以同时具有多个buff,以及相同类型(堆叠)的多个buff。 buff脚本对象充当我们的数据,buff类是我们之间的桥梁,处理每个buff的逻辑。
首先,我们将创建一个我们的buff脚本对象。每个buff应该有一个持续时间,我们需要一种从我们的数据创建这个buff的方法。
ScriptableBuff.cs
 
public abstract class ScriptableBuff : ScriptableObject
{
 
    public float Duration;
 
    public abstract TimedBuff InitializeBuff(GameObject obj);
 
}
到目前为止,我们的ScriptableBuff只包含一个持续时间的字段和一个返回TimedBuff对象的抽象方法。 TimedBuff是我们需要链接数据和播放模型的桥梁。
TimedBuff.cs
 
public abstract class TimedBuff
{
 
    protected float duration;
    protected ScriptableBuff buff;
    protected GameObject obj;
    public Boolean IsFinished
    {
        get { return duration <= 0? true: false; }
    }
 
    public TimedBuff(float duration, ScriptableBuff buff, GameObject obj)
    {
        this.duration = duration;
        this.buff = buff;
        this.obj = obj;
    }
 
    public void Tick(float delta)
    {
        duration -= delta;
        if(duration <= 0)
            End();
    }
 
    public abstract void Activate();
    public abstract void End();
}
我们假设所有的buff都有一个持续时间,但是你可以很容易地改变。 我们希望所有TimedBuff对象存储引用持续时间,buff数据和接收buff的游戏对象。 还有以下方法:
void Tick(float delta) – 在buff的更新循环中调用它。 这用于在剩余的持续时间内保持定时器,完成后调用End()。
void Activate() – 在初始化后调用此函数来激活buff logic.void End()- 持续时间结束时调用。 也可以提早调用“end”buff。
现在我们只需要玩家类。 为此,我们将创建一个名为BuffableEntity的MonoBehaviour组件。
BuffableEntity.cs
 
public class BuffableEntity: MonoBehaviour
{
 
    public List<TimedBuff> CurrentBuffs = new List<TimedBuff>();
 
    void Update()
    {
        //if (Game.isPaused)
        //    return;
 
        foreach(TimedBuff buff in CurrentBuffs.ToArray())
        {
            buff.Tick(Time.deltaTime);
            if (buff.IsFinished)
            {
                CurrentBuffs.Remove(buff);
            }
        }   
    }
 
    public void AddBuff(TimedBuff buff)
    {
        CurrentBuffs.Add(buff);
        buff.Activate();
    }
}
BuffableEntity保存所有当前的buff的列表。 在每个更新循环期间,它会选中每个buff,并删除已经完成的buff。 通过从最后一帧提供deltaTime,这样可以更好地控制更新buff的时间。 例如,您可能希望冻结游戏暂停或玩家被淘汰时的持续时间。
那么我们如何使用这个buff系统呢?
SpeedBuff.cs
[CreateAssetMenu(menuName = "Buffs/SpeedBuff")]
public class SpeedBuff: ScriptableBuff
{
    public float SpeedIncrease;
    public override TimedBuff InitializeBuff(GameObject obj)
    {
       return new TimedSpeedBuff(Duration, this, obj);
    }
}
这扩展了我们的ScriptableBuff来保存SpeedIncrease上的数据。 另外,通过调用InitializeBuff,我们可以创建一个TimedSpeedBuff,我们将在下面实现。 我们还使用CreateAssetMenu属性来将此脚本化对象创建为asset。
TimedSpeedBuff.cs
public class TimedSpeedBuff : TimedBuff
{
    private SpeedBuff speedBuff;
    private MovementComponent movementComponent;
    public TimedSpeedBuff(float duration, ScriptableBuff buff, GameObject obj) : base(duration, buff, obj)
    {
        movementComponent = obj.GetComponent<MovementComponent>();
        speedBuff = (SpeedBuff)buff;
    }
    public override void Activate()
    {
        SpeedBuff speedBuff = (SpeedBuff) buff;
        movementComponent.moveSpeed += speedBuff.SpeedIncrease;
    }
 
    public override void End()
    {
        movementComponent.moveSpeed -= speedBuff.SpeedIncrease;
    }
}
这只是一个简单的buff,但是您可以看到,在Activate()函数中,MovementComponent的速度增加,然后在End()函数中,更改被还原。 这就是实现你的buff所需要的。。
 

更多精彩unity教程:http://www.narkii.com/resource/



相关文章
网友评论

您需要登录后才可以发帖 登录 | 立即注册

关闭

全部评论:0条

推荐
热门