Wie verwende ich [SerializeField] im Labyrinthraster, um das Raster eines vorhandenen Labyrinths zu verwenden, ohne ein C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Wie verwende ich [SerializeField] im Labyrinthraster, um das Raster eines vorhandenen Labyrinths zu verwenden, ohne ein

Post by Anonymous »

das Skript, das ein Labyrinth erzeugt.

Code: Select all

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;
Dann habe ich diese Methode

Code: Select all

public void GenerateAndBuildMaze()
{
CurrentState = MazeState.InProgress;
ClearMaze();
ValidateMazeDimensions();
GenerateMaze();
BuildMaze();
CurrentState = MazeState.Done;
}
und innerhalb von GenerateMaze() verwende und erstelle ich eine Instanz für das Raster.

Code: Select all

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();
}
Wenn ich jetzt das Spiel starte, möchte ich kein neues Labyrinth erstellen. Ich habe schon einmal ein neues Labyrinth mit einem Editor-Skript und einer Schaltfläche erstellt und möchte das vorhandene Labyrinth in einem anderen Skript verwenden.
das Editor-Skript:

Code: Select all

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);
}
}
}
und das Skript, das ich versuche, die Rastervariable zu verwenden.

Code: Select all

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;
}
aber in diesem Skript ist das Gitter null.
Ich dachte, wenn ich [SerializeField] verwende und dann einmal die Schaltfläche zum Generieren eines neuen Labyrinths verwende, wird das Gitter gespeichert und ich kann es dann im letzten Skript verwenden, und es wird nicht null sein.
Da ich das Skript einmal im Editormodus und das im Editor vorhandene Labyrinth erstellt habe, bevor ich das Spiel starte, möchte ich das vorhandene Labyrinth und Gitter verwenden das Bewegungsskript, wenn das Spiel ausgeführt wird, ohne ein neues Labyrinth zu erstellen.
Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post