| Readme Languages: | ||
| English | Русский | |
A simple implementation of a buff-system for use in scripts. Its advantage is that you can use any C#-types as the buff value and value-processors.
In addition to the default processors for the buff values, you can create your own implementations.
- Unity 2021.3 or later
Use ONE of two options:
- Open Package Manager from Window > Package Manager.
- Click the "+" button > Add package from git URL.
- Enter the following URL:
https://github.com/Demexis/Unity-Buffs.git
Alternatively, open Packages/manifest.json and add the following to the dependencies block:
{
"dependencies": {
"com.demegraunt.buffs": "https://github.com/Demexis/Unity-Buffs.git"
}
}Download a unity package from the latest release.
1) Create a buff with the desired type and bind an original value:
// This variable can change its value!
public float originalValue = 1f;
...
var buff = new Buff<float>(() => originalValue);2) Add processor(-s) that will sequentially transform the original value:
private readonly Guid processorId = Guid.NewGuid();
...
buff.Add(processorId, new BuffProcessor<float>(value => value * 4f));3) Calculate the buff value:
var resultValue = buff.Calculate();
Debug.Log(resultValue); // prints 44) Replace the processor:
buff.Replace(processorId, new BuffProcessor<float>(value => value + 20f));
resultValue = buff.Calculate();
Debug.Log(resultValue); // prints 215) Remove the processor:
buff.Remove(processorId);
resultValue = buff.Calculate();
Debug.Log(resultValue); // prints 1 - the original value1: A sprint mechanic using a buff
using System;
using Demegraunt.Framework;
using UnityEngine;
public sealed class MovementWithBuff : MonoBehaviour {
[field: SerializeField] public float Speed { get; set; } = 1f;
[field: SerializeField] public float SprintMultiplier { get; set; } = 4f;
private Buff<float> SpeedBuff { get; set; }
private readonly Guid sprintProcessorId = Guid.NewGuid();
private void Awake() {
SpeedBuff = new Buff<float>(() => Speed);
}
private void Update() {
if (Input.GetKeyDown(KeyCode.LeftShift)) {
ActivateSprint();
} else if (Input.GetKeyUp(KeyCode.LeftShift)) {
DeactivateSprint();
}
transform.position += Vector3.right * (Time.deltaTime * SpeedBuff.Calculate());
}
public void ActivateSprint() {
if (SpeedBuff.Contains(sprintProcessorId)) {
return;
}
SpeedBuff.Add(sprintProcessorId, new BuffProcessor<float>(originalValue => originalValue * SprintMultiplier));
}
public void DeactivateSprint() {
SpeedBuff.Remove(sprintProcessorId);
}
}2: One buff affects the other
public sealed class WalkRunBuffs : MonoBehaviour {
[field: SerializeField] public float Speed { get; set; } = 1f;
[field: SerializeField] public float SprintMultiplier { get; set; } = 4f;
private Buff<float> WalkBuff { get; set; }
private Buff<float> RunBuff { get; set; }
private readonly Guid slowdownProcessorId = Guid.NewGuid();
private void Awake() {
WalkBuff = new Buff<float>(() => Speed);
RunBuff = new Buff<float>(() => WalkBuff.Calculate() * SprintMultiplier);
}
private void Start() {
Slowdown();
}
private void Update() {
// always running
transform.position += Vector3.right * (Time.deltaTime * RunBuff.Calculate());
}
public void Slowdown() {
WalkBuff.Add(slowdownProcessorId, new FloatBuffMultiplier(0.1f));
}
}-
The package contains custom processors such as:
FloatBuffAdder,FloatBuffMultiplier,IntBuffAdder,IntBuffMultiplier. You can define your own types of processors by inheriting fromBuffProcessor<T>. -
If you cache the created processor instance, you can access the
ProcessCallbackproperty to change the processing logic, instead of creating a completely new instance:
var buff = new Buff<float>(1f);
var processor = new BuffProcessor<float>(value => value + 5f);
buff.Add(Guid.NewGuid(), processor);
Debug.Log(buff.Calculate()); // prints 6
processor.ProcessCallback = value => value / 2f;
Debug.Log(buff.Calculate()); // prints 0.5- If you don't want to write separately a field with a parameter (
float,int, ...) and a field with a buff, you can use the types:FloatBuffField,IntBuffField. You can also make an implementation for a new type by inheriting fromBuffField<T>and adding the[Serializable]attribute.