Forum begins after the advertisement:
[Part 16] Adding a buff system to the game
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 16] Adding a buff system to the game
- This topic has 5 replies, 2 voices, and was last updated 7 months, 4 weeks ago by Cam.
-
AuthorPosts
-
March 28, 2024 at 1:30 pm #13637::
i managed to get some time today had a play with buff system with a freind, stll not working yet but you love for you to have a look (also when can we watch the live Stream from last night would love to look back at it
Buff.cs
using System; public class Buff { public string StatAffected { get; private set; } public float Modifier { get; private set; } public float Duration { get; private set; } private float remainingDuration; public Buff(string statAffected, float modifier, float duration) { StatAffected = statAffected; Modifier = modifier; Duration = duration; remainingDuration = duration; } // Method to update the remaining duration of the buff public void UpdateDuration(float deltaTime) { remainingDuration -= deltaTime; if (remainingDuration <= 0) { // Buff expired // Optionally: Trigger an event to notify listeners that the buff expired } } }
BuffData.cs
using System.Collections.Generic; using UnityEngine; public class BuffData : MonoBehaviour { private List<Buff> activeBuffs = new List<Buff>(); // Method to apply a buff to an entity public void ApplyBuff(Buff buff) { activeBuffs.Add(buff); // Optionally: Trigger an event to notify listeners that a new buff was applied } // Method to remove a specific type of buff public void RemoveBuff(string statAffected) { for (int i = activeBuffs.Count - 1; i >= 0; i--) { if (activeBuffs[i].StatAffected == statAffected) { activeBuffs.RemoveAt(i); // Optionally: Trigger an event to notify listeners that a buff was removed break; // Stop after removing the first matching buff } } } // Method to update active buffs public void UpdateBuffs(float deltaTime) { for (int i = activeBuffs.Count - 1; i >= 0; i--) { activeBuffs[i].UpdateDuration(deltaTime); if (activeBuffs[i].Duration <= 0) { // Buff duration expired, remove it activeBuffs.RemoveAt(i); // Optionally: Trigger an event to notify listeners that a buff expired } } } // Method to recalculate entity stats based on active buffs public void RecalculateStats() { // Logic to recalculate entity stats based on active buffs } }
WeaponDamageBuff.cs
public class WeaponDamageBuff : Buff { public WeaponDamageBuff(float modifier, float duration) : base("WeaponDamage", modifier, duration) { // The "WeaponDamage" string indicates that this buff affects weapon damage } }
and lastly when im putting it on my “rage System”
private void ToggleDrunkState() { IsDrunk = !IsDrunk; if (IsDrunk) { drunkParticle.Play(); ApplyBuffs(); } else { drunkParticle.Stop(); } if (!IsDrunk) { drunkParticle.Stop(); RemoveBuffs(); } } private void Drunk() { currentDrunk -= player.Stats.soberRate * Time.deltaTime; if (currentDrunk < 0) { currentDrunk = 0; } } private void ApplyBuffs() { // Apply weapon damage buff Buff weaponDamageBuff = new Buff("WeaponDamage", WeaponDamageBuffAmount, float.MaxValue); buffData.ApplyBuff(weaponDamageBuff); // Recalculate stats after applying buffs buffData.RecalculateStats(); } private void RemoveBuffs() { // Remove weapon damage buff buffData.RemoveBuff("WeaponDamage"); // Recalculate stats after removing buffs buffData.RecalculateStats(); }
March 29, 2024 at 2:55 am #13639::Hey Cam, the stream is here. I’ve timestamped it to make it easier for you to find the part.
I’ll have a look at your code tomorrow.
March 29, 2024 at 5:12 am #13641::the video you link here says “Video unavailable”
and its not showing up on your youtube channel under liveMarch 29, 2024 at 3:47 pm #13642::Hey Cam, here’s how I would organise the Buff class. It should store all of its data in
BuffData
and just have a reference to it.using System; public class Buff {
public string StatAffected { get; private set; } public float Modifier { get; private set; } public float Duration { get; private set; } private float remainingDuration;public BuffData data; float remainingDuration; ... }The BuffData script should be a scriptable object, so you can use it to create different buffs in the project window. In it, you should store all attributes of the buff, e.g. name, duration, stat modifiers, etc.
using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "Data", menuName = "Your Game Name/Buff Data", order = 1)] public class BuffData : MonoBehaviour { public string name; public CharacterData.Stats modifier; public float duration; // These shouldn't be here. They should be somewhere else, preferrably in the player script
private List<Buff> activeBuffs = new List<Buff>(); // Method to apply a buff to an entity public void ApplyBuff(Buff buff) { activeBuffs.Add(buff); // Optionally: Trigger an event to notify listeners that a new buff was applied } // Method to remove a specific type of buff public void RemoveBuff(string statAffected) { for (int i = activeBuffs.Count - 1; i >= 0; i--) { if (activeBuffs[i].StatAffected == statAffected) { activeBuffs.RemoveAt(i); // Optionally: Trigger an event to notify listeners that a buff was removed break; // Stop after removing the first matching buff } } } // Method to update active buffs public void UpdateBuffs(float deltaTime) { for (int i = activeBuffs.Count - 1; i >= 0; i--) { activeBuffs[i].UpdateDuration(deltaTime); if (activeBuffs[i].Duration <= 0) { // Buff duration expired, remove it activeBuffs.RemoveAt(i); // Optionally: Trigger an event to notify listeners that a buff expired } } } // Method to recalculate entity stats based on active buffs public void RecalculateStats() { // Logic to recalculate entity stats based on active buffs }}Your
PlayerStats
script is where you put the functions to add / remove buffs:public class PlayerStats : MonoBehaviour { ... public List<Buff> buffs = new List<Buff>(); // aka the buff list. ... // The update function will reduce the duration of the buffs and remove expired buffs. void Update() { ... // Counts down duration of buffs. List<Buff> expiredBuffs = new List<Buff>(); foreach(Buff b in buffs) { b.duration -= Time.deltaTime; if(b.duration <= 0) expiredBuffs.Add(b); } // Create a new list excluding expired buffs. if(expiredBuffs.Count > 0) buffs = buffs.Except(expiredBuffs).ToList(); ... } public Buff AddBuff(BuffData buffData) { // You can also create a constructor for buff and use that. Buff b = new Buff { data = buffData, remainingDuration = buffData.duration }; buffs.Add(b); RecalculateStats(); // Calls the function from PlayerStats added in Part 15. This is very important. return b; } // Removes all copies of a certain type of buff. public Buff RemoveBuff(BuffData data) { List<Buff> toRemove = new List<Buff>(); foreach(Buff b in buffs) { if(b.data.name == data.name) toRemove.Add(b); } buffList = buffList.Except(toRemove).ToList(); RecalculateStats(); // Whenever we modify the buff list, we need to recalculate stats. } // Remember that you also need to get RecalculateStats() to add buffs to your stats. // This is equally important as calling RecalculateStats() above. public void RecalculateStats() { actualStats = baseStats; foreach(PlayerInventory.Slot s in inventory.passiveSlots) { Passive p = s.item as Passive; if(p) { actualStats += p.GetBoosts(); } } foreach(Buff b in buffList) { actualStats += b.data.modifier; } } }
I hope this makes sense! It is quite a lot to digest, but feel free to ask if you have any further questions.
March 29, 2024 at 4:18 pm #13644::It looks like the coding stream #20 video has been blocked by YouTube because the BGM I used was not copyright free. I’ve clipped the part where I talked about the buff system here: https://www.patreon.com/posts/101282948
March 30, 2024 at 6:05 am #13648 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: