Forum begins after the advertisement:
[Part 12] The map is automatically enabled after interacting with the save point
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 12] The map is automatically enabled after interacting with the save point
- This topic has 13 replies, 3 voices, and was last updated 1 week ago by Terence.
-
AuthorPosts
-
January 7, 2025 at 10:11 pm #17077::
I asked about this problem a long time ago. It seemed to have been repaired at that time, but after new teaching, it seemed to be broken again. I am not sure whether it was not completely repaired in the first place.
Anyway, I did a test.
Once I interact with the save point once, the map I walked through will be automatically activated, instead of being activated after interacting with the save point of the new map.
I also tested whether other functions are normal. If I go directly from Stage_1 to Stage_4, Stage_2 and Stage_3 will not be automatically enabled, only 1 and 4 will be enabled. This functionality should be normal.
If I go all the way from Stage_1 to Stage_3 before using the save point, 1~3 will be enabled normally.
In addition, I don’t know why. There is a chance that the player will freeze when I switch scenes. I saw that the player’s status is CutScene and Invincible. I’m still looking for the correct trigger
January 8, 2025 at 10:38 pm #17079::For the
GameManager
, can you try adding this line to theAwake()
function and see if this fixes the map issue? Currently, whenever you enter a new Scene, the Game Manager’sAwake()
function triggers and adds the map to the scene names list.private void Awake() { SaveData.Instance.Initialize(); if (Instance != null && Instance != this) { Destroy(gameObject); return; } else { Instance = this; } if (PlayerController.Instance != null) { if (PlayerController.Instance.halfMana) { SaveData.Instance.LoadShadeData(); if (SaveData.Instance.sceneWithShade == SceneManager.GetActiveScene().name || SaveData.Instance.sceneWithShade == "") { Instantiate(shade, SaveData.Instance.shadePos, SaveData.Instance.shadeRot); } } } SaveScene(); DontDestroyOnLoad(gameObject); bench = FindObjectOfType<Bench>(); SaveData.Instance.LoadBossData(); }
For the player freezing, it is because
WalkIntoNewScene()
doesn’t finish playing. Can you check whether the “cutscene played” message below doesn’t show up when your player freezes? We need to figure out why the coroutine does not finish playing.public IEnumerator WalkIntoNewScene(Vector2 _exitDir, float _delay) { pState.invincible = true; //If exit direction is upwards if (_exitDir.y != 0) { rb.velocity = jumpForce * _exitDir; } //If exit direction requires horizontal movement if (_exitDir.x != 0) { xAxis = _exitDir.x > 0 ? 1 : -1; Move(); } Flip(); yield return new WaitForSeconds(_delay); print("cutscene played"); pState.invincible = false; pState.cutscene = false; }
@ser.apustaja, if you have any idea what the issue is, please chime in.
January 9, 2025 at 12:11 am #17080::It looks like you’re working on a Unity project and you’re dealing with a couple of issues related to scene management and player freezing. Let’s break down both issues you’ve mentioned.
1. Adding a Line to
Awake()
You mentioned a line that should be added to the
Awake()
method in theGameManager
. The line you indicated (return;
) is already included in the code snippet you provided. This line is crucial because it prevents the rest of theAwake()
method from executing if an instance of theGameManager
already exists.Here’s the relevant part of your
Awake()
method for context:if (Instance != null && Instance != this) { Destroy(gameObject); return; // This prevents further execution if another instance exists }
If you’re still facing issues with the map being added to the scene name list, ensure that you’re checking the logic that handles adding map names. You might want to add debugging statements to track when and how this occurs.
2. The
WalkIntoNewScene
CoroutineFor your issue with the player freezing, you should check a few things:
-
Coroutine Execution: Ensure that
WalkIntoNewScene()
is being called correctly and that the coroutine is not prematurely stopped. You can add debug logs at the start of the coroutine and before theyield return
line to see if it’s being reached. -
State Management: You might want to ensure that
pState.invincible
andpState.cutscene
are being reset appropriately after the coroutine finishes. If there’s any logic that could cause the coroutine to exit before reaching the print statement, that might explain the freezing.
Here’s a modified version of your coroutine with additional debug statements:
public IEnumerator WalkIntoNewScene(Vector2 _exitDir, float _delay) { Debug.Log("Starting WalkIntoNewScene coroutine"); pState.invincible = true; // If exit direction is upwards if (_exitDir.y != 0) { rb.velocity = jumpForce * _exitDir; } // If exit direction requires horizontal movement if (_exitDir.x != 0) { xAxis = _exitDir.x > 0 ? 1 : -1; Move(); } Flip(); yield return new WaitForSeconds(_delay); Debug.Log("Cutscene completed, setting states"); print("cutscene played"); pState.invincible = false; pState.cutscene = false; }
Debugging Steps
-
Check Logs: Make sure to check the Unity console logs to see if “Starting WalkIntoNewScene coroutine” and “Cutscene completed, setting states” are printed in the correct order.
-
Check for Errors: Look for any errors in the console that might hint towards exceptions being thrown that could interrupt the coroutine.
-
Ensure Proper Calls: Verify where and how
WalkIntoNewScene()
is called. If it’s called from a different coroutine or method, ensure that the flow allows it to complete. -
Movement Logic: If the player is still freezing, ensure that there’s no other logic affecting player movement during this coroutine.
If you check these points and still face issues, feel free to share more context or code, and I can assist further!
- 1 anonymous person
January 9, 2025 at 7:38 pm #17086::After adding
return;
, the map will only update Stage_1, no matter which scene I save from.cutscene played
will appear when switching scenesJanuary 10, 2025 at 11:52 am #17088::In that case, let’s remove the
return;
, and move theSaveScene()
function call fromAwake()
intoSaveBench()
. That way, the map will add the scene you are in whenever you sit at a bench.If you want to have it add all newly visited scenes, you will need to create another variable in the
GameManager
to track this.The save system up to part 12 has a few shortcomings. I’m planning to fix it with a part about the save system revamp.
The “cutscene played” message appears even if the player freezes?
January 10, 2025 at 12:53 pm #17090::I’m testing it again now, and if it freezes,
cutscene played
will not appear. I’m not sure if I made a mistake in the first test.January 10, 2025 at 4:52 pm #17091January 10, 2025 at 5:12 pm #17092::After exiting the scene, for example: when I go from Stage_1 to Stage_2. Will freeze in Stage_2
January 11, 2025 at 1:57 am #17093::Do you freeze after finishing your walk into stage 2? Or before?
If you can make a clip of this that will be great.
January 11, 2025 at 10:20 am #17094January 11, 2025 at 4:38 pm #17095::It is likely that the
WalkIntoNewScene()
coroutine is stopped when the player fails to regain control. We’ll have to recode how it works to prevent this bug from happening in a future part.For now, you can put this in
SceneTransition.Start()
to unlock the player whenever the scene starts:private void Start() { if(GameManager.Instance.transitionedFromScene == transitionTo) { PlayerController.Instance.transform.position = startPoint.position; StartCoroutine(PlayerController.Instance.WalkIntoNewScene(exitDirection, exitTime)); PlayerController.InstancepState.invincible = false; PlayerController.InstancepState.cutscene = false; } StartCoroutine(UIScreen.FadeTo(fadeColor, -1, fadeTime)); }
This will allow the player to be controlled when he is walking into the Scene. But you can introduce a delay before the
invincible
andcutscene
is set.January 11, 2025 at 11:22 pm #17096::I made the above modifications, but it did not solve my problem. Invincibility and cutscene did not become false.
January 12, 2025 at 1:19 pm #17097::Try introducing a counter like this:
float exitTimeCounter = 0; private void Start() { if(GameManager.Instance.transitionedFromScene == transitionTo) { PlayerController.Instance.transform.position = startPoint.position; StartCoroutine(PlayerController.Instance.WalkIntoNewScene(exitDirection, exitTime));
PlayerController.InstancepState.invincible = false; PlayerController.InstancepState.cutscene = false;} StartCoroutine(UIScreen.FadeTo(fadeColor, -1, fadeTime)); } void Update() { if(exitTimeCounter > 0) { exitTimeCounter -= Time.deltaTime; if(exitTimeCounter <= 0) { PlayerController.InstancepState.invincible = false; PlayerController.InstancepState.cutscene = false; } } }January 12, 2025 at 3:01 pm #17098::It didn’t work. I’m curious why this problem doesn’t occur in other scenes. Is it a problem with my settings in Unity?
January 13, 2025 at 10:15 pm #17104::It is possible that it is a problem with your Scene. The cause of the problem is most likely from the Coroutine. The highlighted portion below won’t finish if the GameObject running the coroutine gets disabled before the time elapses.
public IEnumerator WalkIntoNewScene(Vector2 _exitDir, float _delay) { pState.invincible = true; //If exit direction is upwards if (_exitDir.y != 0) { rb.velocity = jumpForce * _exitDir; } //If exit direction requires horizontal movement if (_exitDir.x != 0) { xAxis = _exitDir.x > 0 ? 1 : -1; Move(); } Flip(); yield return new WaitForSeconds(_delay); print("cutscene played"); pState.invincible = false; pState.cutscene = false; }
-
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: