Search code examples
c#unity-game-enginecalculationscriptable-object

Calculate amount with value and calculation type (set, fixed, seconds, persentages, second persentages) and have the correct stat changed


I need help with the following.

Calculate with only a amount variable and an enum to set what type of calculation so i can set the correct stat value to a stat.

Make sure the correct stat gets changed.

So in other words make sure the correct stat gets changed by the correct amount.

Here is the code i have so far (the only script that i think needs to change is the PlayerStatCalculator script)

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using UnityEngine;

public class PlayerStatCalculator : MonoBehaviour
{
    public CardSO collectedCard;
    public PlayerStats playerStatToChange;


    public void OnCardCollected()
    {
        //piece of code to activate abilities

        foreach (var statChanges in collectedCard.StatChanges)
        {
            SetStats(statChanges.statChangeAmount, statChanges.changeType);
            //statChanges.statName

        }
    }

    void SetStats(float amount, EStatChangeType type)
    {
        float statToChange = 0;// this needs to become the stat that needs to be changed in playerStatToChange


        switch (type)
        {
            case EStatChangeType.Fixed:
                statToChange += amount;
                break;
            case EStatChangeType.Persentage:
                
                break;
            case EStatChangeType.Set:
                statToChange = amount;
                break;
            case EStatChangeType.Second:

                break;
            case EStatChangeType.SecondPersentage:

                break;
        }        
    }
}
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;


[CreateAssetMenu]
public class CardSO : ScriptableObject
{
    public string CardName;

    public bool CanGet = true;

    public bool CanSpawn = true;

    public Image CardBG;

    public ECardRarity rarity;

    public EAbilityType abilityType;


    //need to make it so i can only set this if i give the abilityType the correct value
    public EBlockAbility blockAbility;
    public EBulletAbility bulletAbility;
    public EPlayerAbility playerAbility;

    public CardStat[] StatChanges;
}

public enum EAbilityType
{
    None,
    Block,
    Bullet,
    Player
}

public enum EPlayerAbility
{
    None
}

public enum EBlockAbility //things like implosion are going in here
{
    None,
    Bombs_Away
}

public enum EBulletAbility //things like poison cloud are going in here
{
    None,
    Poison,
    Parasite
}

public enum ECardRarity
{
    None,
    common,
    uncommon,
    rare,
    epic,
    legendairy,
    mythic
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu]
public class PlayerStats : ScriptableObject
{
    public int Hp = 100;

    public int Damage = 55;

    public float ReloadTime = 1;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class CardStat
{
    public EStatToChange statName;
    public EStatChangeType changeType;
    public float statChangeAmount;
}

public enum EStatChangeType
{
    none,
    Fixed,
    Persentage,
    Set,
    Second,
    SecondPersentage
}

public enum EStatToChange
{
    none,
    Hp,
    Damage,
    ReloadTime
}

Solution

  • For anyone wondering this is the answer i was looking for

    PropertyInfo is a class available in unity just make sure that you are using System.Reflection; at the top

    using System.Reflection
    
    public CardSO collectedCard;
    public PlayerStats playerStatToChange;
    
    public void OnCardCollected()
    {
        //piece of code to activate abilities
    
        foreach (var statChanges in collectedCard.StatChanges)
        {
            CalculateStats(statChanges.statChangeAmount, statChanges.changeType, statChanges.statName);
        }
    }
    
    void CalculateStats(float amount, EStatChangeType type, EStatToChange stat)
    {
        switch (type)
        {
            case EStatChangeType.Add:
                AddStat(amount, stat);
                break;
    
            case EStatChangeType.Persentage:
                PersentageStat(amount, stat);
                break;
    
            case EStatChangeType.Set:
                SetStat(amount, stat);
                break;
    
        }
    }
    
    void SetStat(float floatAmount, EStatToChange stat)
    {
        int intAmount = Mathf.RoundToInt(floatAmount);
    
        string statName = Enum.GetName(typeof(EStatToChange), stat);
        if (statName == null || statName == "none") return;
    
        PropertyInfo propertyInfo = typeof(PlayerStats).GetProperty(statName);
        if (propertyInfo == null) return;
    
        if (propertyInfo.PropertyType == typeof(int))
        {
            int currentValue = (int)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, intAmount);
        }
        else if (propertyInfo.PropertyType == typeof(float))
        {
            float currentValue = (float)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, floatAmount);
        }
        else
        {
            Debug.LogWarning($"Unsupported property type for stat {statName}.");
        }
    }
    
    void PersentageStat(float amount, EStatToChange stat)
    {
        float persentageAmount = 1 + (amount / 100);
    
        string statName = Enum.GetName(typeof(EStatToChange), stat);
        if (statName == null || statName == "none") return;
    
        PropertyInfo propertyInfo = typeof(PlayerStats).GetProperty(statName);
        if (propertyInfo == null) return;
    
        if (propertyInfo.PropertyType == typeof(int))
        {
            int currentValue = (int)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, currentValue * 100 * persentageAmount / 100);
        }
        else if (propertyInfo.PropertyType == typeof(float))
        {
            float currentValue = (float)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, currentValue *= persentageAmount);
        }
        else
        {
            Debug.LogWarning($"Unsupported property type for stat {statName}.");
        }
    }
    
    void AddStat(float floatAmount, EStatToChange stat)
    {
        int intAmount = Mathf.RoundToInt(floatAmount);
    
        string statName = Enum.GetName(typeof(EStatToChange), stat);
        if (statName == null || statName == "none") return;
    
        PropertyInfo propertyInfo = typeof(PlayerStats).GetProperty(statName);
        if (propertyInfo == null) return;
    
        if (propertyInfo.PropertyType == typeof(int))
        {
            int currentValue = (int)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, currentValue += intAmount);
        }
        else if (propertyInfo.PropertyType == typeof(float))
        {
            float currentValue = (float)propertyInfo.GetValue(playerStatToChange);
            propertyInfo.SetValue(playerStatToChange, currentValue += floatAmount);
        }
        else
        {
            Debug.LogWarning($"Unsupported property type for stat {statName}.");
        }
    }