using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public GameObject[] enemyPrefabArray;
public GameObject player;
[SerializeField] MapGenerator mapGeneratorScript;
void OnEnable() => mapGeneratorScript.OnGeneratedMap += SpawnMobs;
void OnDisable() => mapGeneratorScript.OnGeneratedMap -= SpawnMobs;
void SpawnMobs()
{
StartCoroutine(SpawnEnemies(enemyPrefabArray[0], 0.1f, 0.2f, 20, 6));
}
IEnumerator SpawnEnemies(GameObject enemyPrefab, float minInterval, float maxInterval, int maxEnemyCount, int withinRangeOfPlayer)
{
int numOfEnemies = 0;
while (numOfEnemies < maxEnemyCount)
{
Vector3 playerPos = player.transform.position;
yield return new WaitForSeconds(Random.Range(minInterval, maxInterval));
int randomXCoord = Mathf.RoundToInt(playerPos.x) + Random.Range(-withinRangeOfPlayer, withinRangeOfPlayer + 1);
int randomYCoord = Mathf.RoundToInt(playerPos.y) + Random.Range(-withinRangeOfPlayer, withinRangeOfPlayer + 1);
if (randomXCoord >= 0 && randomXCoord < mapGeneratorScript.map.GetLength(0) && randomYCoord >= 0 && randomYCoord < mapGeneratorScript.map.GetLength(0))
{
// Avoiding spawns in water tile
bool isWaterTile = mapGeneratorScript.map[randomXCoord, randomYCoord] == 1;
if (!isWaterTile)
{
Instantiate(enemyPrefab, new Vector3(randomXCoord, randomYCoord, 0), Quaternion.identity);
numOfEnemies++;
Debug.Log($"Player X: {playerPos.x} Player Y: {playerPos.y}, X: {randomXCoord} Y: {randomYCoord}, {mapGeneratorScript.map[randomXCoord, randomYCoord]}");
}
else
{
Debug.Log("Avoided Spawn on Water");
}
}
}
}
}
我的代码问题是,当我在游戏中生成后保持静止时,敌人会正确生成,敌人生成在 1 个瓷砖中,也避免在水瓷砖中生成,但是每当我开始在地图上移动时,敌人的生成打破它们产生偏离中心或在 2 个或更多瓷砖之间,敌人也会在水瓷砖中产生。调试控制台中的坐标和值与地图中的实际预制件不匹配,我很困惑为什么会这样?
玩家的位置在敌方生成协程运行的同时不断变化。当玩家移动时,新生成位置的坐标计算不准确。
我更新了 Vector3、StartCoroutine 和 IEnumerator。运行它,看看它是否有效
void SpawnMobs()
{
Vector3 currentPlayerPosition = player.transform.position;
StartCoroutine(SpawnEnemies(enemyPrefabArray[0], 0.1f, 0.2f, 20, 6, currentPlayerPosition));
}
IEnumerator SpawnEnemies(GameObject enemyPrefab, float minInterval, float maxInterval, int maxEnemyCount, int withinRangeOfPlayer, Vector3 currentPlayerPosition)
{
int numOfEnemies = 0;
while (numOfEnemies < maxEnemyCount)
{
yield return new WaitForSeconds(Random.Range(minInterval, maxInterval));
int randomXCoord = Mathf.RoundToInt(currentPlayerPosition.x) + Random.Range(-withinRangeOfPlayer, withinRangeOfPlayer + 1);
int randomYCoord = Mathf.RoundToInt(currentPlayerPosition.y) + Random.Range(-withinRangeOfPlayer, withinRangeOfPlayer + 1);
if (randomXCoord >= 0 && randomXCoord < mapGeneratorScript.map.GetLength(0) && randomYCoord >= 0 && randomYCoord < mapGeneratorScript.map.GetLength(0))
{
// Avoiding spawns in water tile
bool isWaterTile = mapGeneratorScript.map[randomXCoord, randomYCoord] == 1;
if (!isWaterTile)
{
Instantiate(enemyPrefab, new Vector3(randomXCoord, randomYCoord, 0), Quaternion.identity);
numOfEnemies++;
Debug.Log($"Player X: {currentPlayerPosition.x} Player Y: {currentPlayerPosition.y}, X: {randomXCoord} Y: {randomYCoord}, {mapGeneratorScript.map[randomXCoord, randomYCoord]}");
}
else
{
Debug.Log("Avoided Spawn on Water");
}
}
}
}