Search code examples
c#unity-game-engineexceptionoverflowstack-overflow

StackOverflowException: The requested operation caused a stack overflow


I've made some code in Unity2d with c# and interface. LevelingSystem.cs is putted in empty gameobject.

And i getting error:

StackOverflowException: The requested operation caused a stack overflow.
PlayerCap.get_actExp () (at Assets/Scripts/player/PlayerCap.cs:17)
PlayerCap.get<message truncated>

CapLevel.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


interface ICapLevel
{

    float multiplierA { get; set; }
    float multiplierB { get; set; }
    float multiplierC { get; set; }
    float multiplierD { get; set; }

    int lvlCap { get; set; }
    List<double> expCap { get; set; }
    float actExp { get; set; }

    void GenerateExpPerLvl();
    float RequiredExp(int level);
}

PlayerCap.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCap : ICapLevel
{

    public float multiplierA { get { return multiplierA; } set { multiplierA = 280f; } }
    public float multiplierB { get { return multiplierB; } set { multiplierB = 100f; } }
    public float multiplierC { get { return multiplierC; } set { multiplierA = 1.15f; } }
    public float multiplierD { get { return multiplierD; } set { multiplierD = 2.3f; } }

    public int lvlCap { get { return lvlCap; } set { lvlCap = 210; } }

    public List<double> expCap { get { return expCap; } set { expCap = new List<double>(); } }
    public float actExp { get { return actExp; } set { actExp = 0f; } }

    public void GenerateExpPerLvl()
    {
        Debug.Log("implementation successful");

        for (int expLevel = 1; expLevel <= lvlCap; expLevel++)
        {
            expCap.Add(RequiredExp(expLevel - 1));
        }

    }

    public float RequiredExp(int level)
    {
        double formulaRounded;
        var formula = multiplierB * (Mathf.Pow(multiplierC, level - 1)) + multiplierA * (Mathf.Pow(level, multiplierD));
        if (formula < 1000)
        {
            if ((formula % 10) == 0)
            {
                formulaRounded = formula;
                return (float)formulaRounded;
            }
            else
            {
                formulaRounded = Math.Round((formula / 1000), 1, MidpointRounding.AwayFromZero);
            }
        }
        else
        {
            formulaRounded = Math.Round((formula / 1000), 0, MidpointRounding.AwayFromZero);
        }
        return (float)formulaRounded * 1000;

    }
}

LevelingSystem.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevelingSystem : MonoBehaviour
{
    //interface implementation
    private PlayerCap _pCap;
    private ICapLevel _ICap;

    private List<double> _pExpCap;

    private int pLvl;
    private float _pActExp;

    public void Awake()
    {
        _pCap = new PlayerCap();
        _ICap = _pCap;


    }

    private void Start()
    {
        _pActExp = _ICap.actExp;
        _ICap.GenerateExpPerLvl();
        _pExpCap = _ICap.expCap;
    }



    public void AddExp(float amount)
    {
        _pActExp += amount;
        StartCoroutine(CapLevelCheck(amount));
    }

    private IEnumerator CapLevelCheck(float amount)
    {
        while (true)
        {
            if (_pActExp >= _pExpCap[pLvl])
            {
                _pActExp -= (float)_pExpCap[pLvl];
                AddLevel(1);
            } else
            {
                Debug.Log("You Get " + amount + " Experience and you have " + pLvl + " Lvl. *Click noice!");
                break; //otherwise loop will do in infinite
            }
            yield return 0;
        }
    }

    public void AddLevel(int amount)
    {
        pLvl += amount;
    }
    public int GetActualLevel()
    {
        return pLvl;
    }
}

Im try few things like get rid off for in method GenerateExpPerLvl() and error gones away so my suspicious thing is list variable but maybe im wrong.

Thanks for help :)


Solution

  • The problem is here:

    public float actExp { get { return actExp; } set { actExp = 0f; } }
                                    // ^ Problem here & ^ same problem here
    

    You are calling your Property inside its own getter and setter. It creates an infinite loop... (everytime you call actExp it will call itself)

    Instead you should just write (if there is no logic inside accessors):

    public float actExp { get; set; }