Hi all,
Spent the last couple of hours trying to debug this to no avail.
My traits don’t impact my actual health / mana (I’m guessing the rest of the stats as well), despite being changed in the UI (and the committed changes being persistent through saves).
I followed the advice in the following threads:
IMPORTANT/Puzzling: When I have a value in my additive value, the value DOES get changed, and the additive value is being multiplied by percentage apparently. That happens with the code from the github as well, and i can’t really find any differences.
What I Tried:
-I added “[DisallowMultipleComponent]”
- switched my Awake() with the suggested awake with the Debug logs (from brian’s post), getting my awake called Twice.
-Deleted saves,
-Opened and closed Unity,
-Redid the lesson entirely,
-Made sure my player has a single Instance of TraitStore.cs on it,
-Made sure I have a single instance of Player in the scene, and it is the only TraitStore component in the scene,
-Made sure the player’s BaseStats are the only once with “Use Modifiers” checked,
-Removed and reapplied TraitStore.cs / BonusConfigs to the prefab
-getting the code from the github
Don’t know what else could cause this, perhaps I am getting some weird race condition?
(Unity 2022.3.10f1)
Any help in resolving would be greatly appreciated.
using System;
using System.Collections.Generic;
using GameDevTV.Saving;
using UnityEngine;
namespace RPG.Stats
{
[DisallowMultipleComponent] //Prevents multiple components on your GameObject
public class TraitStore : MonoBehaviour, IModifierProvider, ISaveable
{
[SerializeField] private TraitBonus[] bonusConfig;
[System.Serializable]
class TraitBonus
{
public Trait trait;
public Stat stat;
public float additiveBonusPerPoint = 0;
public float percentageBonusPerPoint = 0;
}
private Dictionary<Trait, int> assignedPoints = new Dictionary<Trait, int>();
private Dictionary<Trait, int> stagedPoints = new Dictionary<Trait, int>();
private Dictionary<Stat, Dictionary<Trait, float>> additiveBonusCache;
private Dictionary<Stat, Dictionary<Trait, float>> percentageBonusCache;
// private void Awake()
// {
// additiveBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
// percentageBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
//
// foreach (var bonus in bonusConfig)
// {
// if (!additiveBonusCache.ContainsKey(bonus.stat))
// {
// additiveBonusCache[bonus.stat] = new Dictionary<Trait, float>();
// }
//
// if (!percentageBonusCache.ContainsKey(bonus.stat))
// {
// percentageBonusCache[bonus.stat] = new Dictionary<Trait, float>();
// }
//
// additiveBonusCache[bonus.stat][bonus.trait] = bonus.additiveBonusPerPoint;
// percentageBonusCache[bonus.stat][bonus.trait] = bonus.percentageBonusPerPoint;
// }
// }
private void Awake()
{
additiveBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
percentageBonusCache = new Dictionary<Stat, Dictionary<Trait, float>>();
foreach (var bonus in bonusConfig)
{
Debug.Log(
$"Processing Bonus {bonus.stat}/{bonus.trait} +{bonus.additiveBonusPerPoint} +{bonus.percentageBonusPerPoint}% + {gameObject.name}");
if (!additiveBonusCache.ContainsKey(bonus.stat))
{
Debug.Log($"Creating Additive lookup for {bonus.stat}");
additiveBonusCache[bonus.stat] = new Dictionary<Trait, float>();
}
if (!percentageBonusCache.ContainsKey(bonus.stat))
{
Debug.Log($"Creating Percentage lookup for {bonus.stat}");
percentageBonusCache[bonus.stat] = new Dictionary<Trait, float>();
}
additiveBonusCache[bonus.stat][bonus.trait] = bonus.additiveBonusPerPoint;
percentageBonusCache[bonus.stat][bonus.trait] = bonus.percentageBonusPerPoint;
Debug.Log(
$"Setting Additive [{bonus.stat}][{bonus.trait}] to {additiveBonusCache[bonus.stat][bonus.trait]}");
Debug.Log(
$"Setting Percentage [{bonus.stat}][{bonus.trait}] to {percentageBonusCache[bonus.stat][bonus.trait]}");
}
}
public int GetProposedPoints(Trait trait)
{
return GetPoints(trait) + GetStagedPoints(trait);
}
public int GetPoints(Trait trait)
{
return assignedPoints.ContainsKey(trait) ? assignedPoints[trait] : 0;
}
public int GetStagedPoints(Trait trait)
{
return stagedPoints.ContainsKey(trait) ? stagedPoints[trait] : 0;
}
public void AssignPoints(Trait trait, int points)
{
if (!CanAssignPoints(trait, points))
{
return;
}
stagedPoints[trait] = GetStagedPoints(trait) + points;
}
public bool CanAssignPoints(Trait trait, int points)
{
if (GetStagedPoints(trait) + points < 0)
{
return false;
}
if (GetUnassignedPoints() < points)
{
return false;
}
return true;
}
public int GetUnassignedPoints()
{
return GetAssignablePoints() - GetTotalProposedPoints();
}
public int GetTotalProposedPoints()
{
int total = 0;
foreach (int points in assignedPoints.Values)
{
total += points;
}
foreach (int points in stagedPoints.Values)
{
total += points;
}
return total;
}
public void Commit()
{
foreach (Trait trait in stagedPoints.Keys)
{
assignedPoints[trait] = GetProposedPoints(trait);
}
stagedPoints.Clear();
}
public int GetAssignablePoints()
{
return (int)GetComponent<BaseStats>().GetStat(Stat.TotalTraitPoints);
}
public IEnumerable<float> GetAdditiveModifiers(Stat stat)
{
if (!additiveBonusCache.ContainsKey(stat))
{
yield break;
}
foreach (Trait trait in additiveBonusCache[stat].Keys)
{
float bonus = additiveBonusCache[stat][trait];
yield return bonus * GetPoints(trait);
}
}
public IEnumerable<float> GetPercentageModifiers(Stat stat)
{
if (!percentageBonusCache.ContainsKey(stat))
{
yield break;
}
foreach (Trait trait in percentageBonusCache[stat].Keys)
{
float bonus = percentageBonusCache[stat][trait];
yield return bonus * GetPoints(trait);
}
}
public object CaptureState()
{
return assignedPoints;
}
public void RestoreState(object state)
{
assignedPoints = new Dictionary<Trait, int>((IDictionary<Trait, int>)state);
}
}
}