15.7 C
New York
Friday, October 3, 2025

unity – Static occasion not engaged on scene reload(SceneManager.LoadScene();)


(Possibly good to know, this recreation is a part of a recreation dev course the place we needed to make a Vampire Survivors like recreation)

I believed SceneManager.LoadScene() reloaded EVERYTHING in a scene, like a clear state, nothing stays of the outdated information (besides when you use the DontDestroyOnLoad mum or dad)

However after I used a static occasion with a non static dictionary in a non static class some bizarre stuff occurs on Scene load. I’ve a PlayerUpgrade class which accommodates:

  • the participant’s expertise factors,
  • upgrades for every stage up,
  • and a PlayerStat Dictionary.

(This class must be refactored into a special class, however I’m not positive how).

This PlayerStat Dictionary accommodates the present stats of the participant:

personal void CreateAbilityUpgrades() {
    abilityUpgrades = new Dictionary() {
        ["Dash"]    =  new(boolData: false),
        ["Dodge"]   =  new(boolData: false),
        ["Sprint"]  =  new(boolData: false),
        ["Health"]  =  new(floatData: 100),
        ["Speed"]   =  new(floatData: 5)
    };
}

The PlayerStat class simply accommodates 3 variables for float, bool and string values. I then use these values for PlayerMovement, PlayerHealth and later for different participant associated issues. I did not know the way to retailer the participant’s stats in some other manner.

The participant’s parts use this dictionary to get the appropriate values. When the participant chooses an improve, this listing will get up to date if the improve is a ChangeAbilityUpgrade.

I’ll attempt to clarify how the code works:

  1. PlayerUpgrade class accommodates an abilityUpgrades dictionary.
  2. PlayerMovement and PlayerHealth use the values in abilityUpgrades to get the appropriate values.
  3. If you select an improve that adjustments values in your participant, the abilityUpgrades Dictionary will get up to date. This causes a ChangeAbilityEvent to fireside:
public static occasion Motion> OnChangeAbility;

personal Dictionary abilityUpgrades;
public Dictionary AbilityUpgrades {
    get { return abilityUpgrades; }
    set { 
        abilityUpgrades = worth; 
        OnChangeAbility?.Invoke(abilityUpgrades);
    }
}

PlayerMovement and PlayerHealth subscribe to this static occasion in their very own Awake() strategies. I then name this occasion at the beginning of the sport and when a capability is up to date.

NOW to the issue:

  1. Beginning the sport provides you the appropriate values.
  2. Choosing an improve provides you the appropriate values.
  3. After I die within the recreation and reload the scene, my participant doesn’t obtain the default values from the dictionary. Their subscribed strategies don’t run, and as an alternative the participant will get the inspector values.

Why is that? Eradicating the static from the occasion fixes it. However why?

Right here is the code I am utilizing:

Participant Improve

public int GetTotalExperiencePoints => totalExperiencePoints;
public int GetCurrentLevel => currentLevel;

public static occasion Motion> OnChangeAbility;

personal Dictionary abilityUpgrades;

public Dictionary AbilityUpgrades {
    get { return abilityUpgrades; }
    set {
        abilityUpgrades = worth;
        OnChangeAbility?.Invoke(abilityUpgrades);
    }
}

public void FireChangeAbility() {
    OnChangeAbility?.Invoke(abilityUpgrades);
}

personal void Awake() {
    CreateAbilityUpgrades();
    int subsequent = currentLevel + 1;
    UpdateUpgradeBar(currentExperiencePoints, levelUps[next].ExperiencePoints);
}

personal void CreateAbilityUpgrades() {
    abilityUpgrades = new Dictionary() {
        ["Dash"] = new(boolData: false),
        ["Dodge"] = new(boolData: false),
        ["Sprint"] = new(boolData: false),
        ["Health"] = new(floatData: 100),
        ["Speed"] = new(floatData: 5),
    };
}

Participant Controller

personal void Begin() {
    playerUpgrade.FireChangeAbility();
}

public void Save(GameData rating) {
    var newestScore = rating.scores[(score.scores.Count - 1)];
    newestScore.Stage = playerUpgrade.GetCurrentLevel;
    newestScore.ExperiencePoints = playerUpgrade.GetTotalExperiencePoints;
}

public void UpdatePlayer() {
    playerMovement.UpdateMovement();
    playerRotater?.Rotate();
    playerShooter.UpdateShooting();
}

public void LateUpdatePlayer() {
    cameraFollow?.LateUpdateCamera();
}

Participant Motion

personal void Awake() {
    PlayerUpgrade.OnChangeAbility += PlayerMovement_OnValuesChanged;
}

public void PlayerMovement_OnValuesChanged(Dictionary stats) {
    canDash = stats["Dash"].boolData;
    canDodge = stats["Dodge"].boolData;
    canSprint = stats["Sprint"].boolData;
    moveSpeed = stats["Speed"].floatData;
}

Participant Well being

protected override void Awake() {
    base.Awake();
    PlayerUpgrade.OnChangeAbility += PlayerHealth_OnValuesChanged;
}

public void PlayerHealth_OnValuesChanged(Dictionary stats) {
    maxHealth = stats["Health"].floatData;
    currentHealth = maxHealth;
    UpdateHealthBar();
}
public class ChangeAbilityUpgrade : Improve {

    personal ChangeUpgradeSO _changeUpgradeSO;
 
    public ChangeUpgradeSO {
        get => _changeUpgradeSO; 
        set => _changeUpgradeSO = worth; 
    }

    [SerializeField] personal PlayerUpgrade playerUpgrade;
    
    public override void Awake() {
        base.Awake(); 
        playerUpgrade = FindAnyObjectByType();
    }

    public override void ActivateAbiIity() {
        string key = _changeUpgradeSO.ChangeAbilityType.ToString();
        playerUpgrade.AbilityUpgrades[key] = _changeUpgradeSO.playerStat;
     
        GameManager.Occasion.SwitchState(); 
        Debug.Log("Modified potential"); 
    }

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles