Forum begins after the advertisement:
[Part 2] Error cannot generate map
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 2] Error cannot generate map
- This topic has 1 reply, 3 voices, and was last updated 2 weeks, 4 days ago by
Terence.
-
AuthorPosts
-
April 22, 2025 at 9:47 pm #17988::
I am having problem with generating new map when running game, can someone help me. Here is the source code with video when I run game: MapController:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MapController : MonoBehaviour { public List<GameObject> terrainChunks; public GameObject player; public float checkerRadius; public Vector3 noTerrainPosition; public LayerMask terrainMask; public GameObject currentChunk; PlayerMovement pm; [Header("Optimization")] public List<GameObject> spawnedChunks; GameObject latestChunk; public float maxOpDist; //Must be greater than the length and width of the tilemap float opDist; float optimizerCooldown; public float optimizerCooldownDur; void Start() { pm = FindAnyObjectByType<PlayerMovement>(); } void Update() { ChunkChecker(); ChunkOptimzer(); } void ChunkChecker() { if (!currentChunk) { return; } if (pm.moveDir.x > 0 && pm.moveDir.y == 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Right").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Right").position; //Right SpawnChunk(); } } else if (pm.moveDir.x < 0 && pm.moveDir.y == 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Left").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Left").position; //Left SpawnChunk(); } } else if (pm.moveDir.y > 0 && pm.moveDir.x == 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Up").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Up").position; //Up SpawnChunk(); } } else if (pm.moveDir.y < 0 && pm.moveDir.x == 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Down").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Down").position; //Down SpawnChunk(); } } else if (pm.moveDir.x > 0 && pm.moveDir.y > 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Right Up").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Right Up").position; //Right up SpawnChunk(); } } else if (pm.moveDir.x > 0 && pm.moveDir.y < 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Right Down").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Right Down").position; //Right down SpawnChunk(); } } else if (pm.moveDir.x < 0 && pm.moveDir.y > 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Left Up").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Left Up").position; //Left up SpawnChunk(); } } else if (pm.moveDir.x < 0 && pm.moveDir.y < 0) { if (!Physics2D.OverlapCircle(currentChunk.transform.Find("Left Down").position, checkerRadius, terrainMask)) { noTerrainPosition = currentChunk.transform.Find("Left Down").position; //Left down SpawnChunk(); } } } void SpawnChunk() { int rand = Random.Range(0, terrainChunks.Count); latestChunk = Instantiate(terrainChunks[rand], noTerrainPosition, Quaternion.identity); spawnedChunks.Add(latestChunk); } void ChunkOptimzer() { optimizerCooldown -= Time.deltaTime; if (optimizerCooldown <= 0f) { optimizerCooldown = optimizerCooldownDur; //Check every 1 second to save cost, change this value to lower to check more times } else { return; } foreach (GameObject chunk in spawnedChunks) { opDist = Vector3.Distance(player.transform.position, chunk.transform.position); if (opDist > maxOpDist) { chunk.SetActive(false); } else { chunk.SetActive(true); } } } }
ChunkTrigger:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ChunkTrigger : MonoBehaviour { MapController mc; public GameObject targetMap; void Start() { mc = FindAnyObjectByType<MapController>(); } private void OnTriggerStay2D(Collider2D col) { if (col.CompareTag("Player")) { mc.currentChunk = targetMap; } } private void OnTriggerExit2D(Collider2D col) { if (col.CompareTag("Player")) { if (mc.currentChunk == targetMap) { mc.currentChunk = null; } } } }
Video running:
View post on imgur.com
@TerenceApril 22, 2025 at 9:56 pm #17989::Based on the code you provided and the issue you’re facing with generating new maps, here are a few things you can check and potential fixes:
-
Layer Mask Setup: Ensure that the
terrainMask
is properly set up in the Unity Inspector. This mask should include the layers that your terrain chunks are assigned to. If the mask does not include the correct layers, thePhysics2D.OverlapCircle
checks may always return false, preventing new chunks from being spawned. -
Chunk Positioning: In the
SpawnChunk()
method, double-check that thenoTerrainPosition
is being set correctly. If the position is incorrect or overlaps with existing terrain chunks, it may create issues. You may want to log thenoTerrainPosition
to ensure it’s being set as expected.void SpawnChunk() { int rand = Random.Range(0, terrainChunks.Count); latestChunk = Instantiate(terrainChunks[rand], noTerrainPosition, Quaternion.identity); spawnedChunks.Add(latestChunk); Debug.Log("Spawned chunk at position: " + noTerrainPosition); }
-
Direction Logic: Ensure that the logic in
ChunkChecker()
is correctly identifying the direction of the player’s movement. You can log thepm.moveDir
values to verify that they are set correctly from thePlayerMovement
script. -
Optimization Logic: In the
ChunkOptimzer()
method, ensure that theoptimizerCooldown
is being reset correctly. If the cooldown is set to a very low value, it might not allow chunks to spawn frequently enough. Consider logging theoptimizerCooldown
to see how it changes over time. -
Check for Null References: Make sure that
currentChunk
is being set correctly inChunkTrigger
. If it’s not being set,ChunkChecker
will return early without spawning new chunks. You can add debug logs to check if the player is entering and exiting the triggers correctly. -
Debugging: Add debug statements throughout your code to track the flow of execution and the values of variables. This can help identify where the issue occurs.
-
Unity Version Issues: If you are using a newer version of Unity, ensure that there are no breaking changes related to the physics system or instantiation methods that may affect your code.
Here’s an example of how to add some debug logs in the
ChunkChecker()
method:void ChunkChecker() { if (!currentChunk) { Debug.Log("Current chunk is null."); return; } Debug.Log("Checking chunks based on player movement: " + pm.moveDir); // Existing checks... }
By implementing these checks and debug logs, you should be able to identify the cause of the issue more easily and ensure that new chunks are generated as expected. If the problem persists, please provide any specific errors or unexpected behavior you encounter.
April 23, 2025 at 7:34 pm #17991 -
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: