Как использовать [SerializeField] в сетке лабиринта, чтобы использовать сетку существующего лабиринта без создания новогC#

Место общения программистов C#
Ответить
Anonymous
 Как использовать [SerializeField] в сетке лабиринта, чтобы использовать сетку существующего лабиринта без создания новог

Сообщение Anonymous »

скрипт, создающий лабиринт.

Код: Выделить всё

using UnityEngine;
using Unity.AI.Navigation;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif

[ExecuteAlways]
public class MazeGenerator : MonoBehaviour
{
/// 
/// Defines the generation state of the maze.
/// 
public enum MazeState
{
NotStarted,
InProgress,
Done
}

[Header("Maze Size")]
public int width = 30;
public int height = 30;

// Read-only properties for external use
public int Width => width;
public int Height => height;

[Header("Prefabs")]
public GameObject wallPrefab;
public GameObject floorPrefab;
public GameObject entranceMarkerPrefab;
public GameObject exitMarkerPrefab;
public GameObject deadEndMarkerPrefab;

[Header("Options")]
public bool generateEntranceAndExit = true;

// Expose this list to other scripts.
public List DeadEndMarkers { get; private set; } = new List();

// Public property to check the current state of the maze generation
public MazeState CurrentState { get; private set; } = MazeState.NotStarted;

#if UNITY_EDITOR
[Tooltip("If true, the maze generated in Play Mode will persist in the editor after stopping Play Mode.")]
public bool persistRuntimeMazeOnStop = false;
#endif

// maze[x,y] == true  => wall
// maze[x,y] == false => walkable path
// Add [SerializeField] to ensure this data is saved with the scene!
[SerializeField]
private bool[,] grid;
public bool[,] Grid => grid;
тогда у меня есть этот метод

Код: Выделить всё

public void GenerateAndBuildMaze()
{
CurrentState = MazeState.InProgress;
ClearMaze();
ValidateMazeDimensions();
GenerateMaze();
BuildMaze();
CurrentState = MazeState.Done;
}
и внутри GenerateMaze() я использую и создаю экземпляр сетки.

Код: Выделить всё

public void GenerateMaze()
{
grid = new bool[width, height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
grid[x, y] = true;

int startX = 1, startY = 1;
grid[startX, startY] = false;
CarvePath(startX, startY);

if (generateEntranceAndExit)
AddRandomEntranceAndExit();
}
теперь, когда я запускаю игру, я не хочу создавать новый лабиринт. Я уже однажды создал новый лабиринт с помощью сценария редактора и кнопки и хочу использовать существующий лабиринт в другом сценарии.
Сценарий редактора:

Код: Выделить всё

using UnityEditor;
using UnityEditor.SceneManagement; // Added this using directive for MarkSceneDirty
using UnityEngine;

[CustomEditor(typeof(MazeGenerator))]
public class MazeGeneratorEditor : Editor
{
public override void OnInspectorGUI()
{
// Draw default inspector fields
DrawDefaultInspector();

MazeGenerator mazeGen = (MazeGenerator)target;

serializedObject.Update();

GUILayout.Space(10);

if (GUILayout.Button("Generate New Maze"))
{
Undo.RecordObject(mazeGen, "Generate New Maze");

mazeGen.GenerateAndBuildMaze();

// 
// FIX: Pass the transform of the MazeGenerator object (this is the parent transform)
if (mazeGen.generateEntranceAndExit && mazeGen.Grid != null)
{
// We need to use the transform of the MazeGenerator itself here,
// as that's the parent transform for the visualization in the Editor.
// NOTE: When running the game, MazeGenerator.GenerateNewMaze() passes _currentMaze.transform.
// For Editor visualization, using mazeGen.transform is correct.
MazePathfinder.FindPath(
mazeGen.Grid,
mazeGen.EntranceGridPos,
mazeGen.ExitGridPos,
mazeGen.transform
);
}
// 

// The NPC Spawner logic might be redundant if the new MazeGenerator.GenerateNewMaze()
// already handles the NPC, but keeping it here as a placeholder for external spawning:

MarkSceneDirty(mazeGen);
}

if (GUILayout.Button("Clear Maze"))
{
Undo.RecordObject(mazeGen, "Clear Maze");

mazeGen.ClearMaze();

MazePathfinder.LastGeneratedPath.Clear();

MarkSceneDirty(mazeGen);
}

serializedObject.ApplyModifiedProperties();

SceneView.RepaintAll();
}

private void MarkSceneDirty(MazeGenerator mazeGen)
{
if (!Application.isPlaying)
{
EditorUtility.SetDirty(mazeGen);
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(mazeGen.gameObject.scene);
}
}
}
и сценарий, в котором я пытаюсь использовать переменную сетки.

Код: Выделить всё

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

public class NPCMovement : MonoBehaviour
{
[Header("Movement Settings")]
public float MoveSpeed = 5f;
public float RotationSpeed = 720f;

[Header("Automatic Start")]
[Tooltip("If true, the NPC will automatically try to find the maze path and start moving upon scene load.")]
public bool StartMovementOnStart = true;

[Header("Path Visualization")]
[Tooltip("If true, draws a cyan line trail behind the NPC in the Scene View (runtime only).")]
public bool DrawTrailGizmo = true;

private List _path;
private int _pathIndex = 0;
private List _trailHistory = new List();

private bool _isMoving = false;
private Vector3 _targetPosition;

// --- Core Logic: Check for and initiate movement on start ---
private void Start()
{
// 1. Check the control flag set in the Inspector
if (!StartMovementOnStart) return;

// 2. Find the MazeGenerator in the scene
MazeGenerator mazeGen = Object.FindFirstObjectByType();

if (mazeGen == null)
{
Debug.LogError("NPCMovement: Cannot find MazeGenerator in the scene. Movement aborted.");
return;
}

// 3. Ensure the maze grid data is available
if (mazeGen.Grid == null)
{
Debug.LogWarning("NPCMovement: MazeGenerator grid is null. Cannot calculate path at runtime.  Please ensure the maze has been generated and persisted in the scene.");
return;
}
но в этом скрипте сетка равна нулю.
я думал, что использую [SerializeField], а затем, как только вы нажмете кнопку для создания нового лабиринта, сетка будет сохранена, и я смогу затем использовать ее в последнем скрипте, и она не будет нулевой.
потому что я сгенерировал в режиме редактора скрипт один раз, а лабиринт существует в редакторе перед запуском игры, я хочу использовать существующий лабиринт и сетка в сценарии движения при запуске игры без создания нового лабиринта.
Изображение


Подробнее здесь: https://stackoverflow.com/questions/798 ... -maze-with
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»