Jo Jo funguje Kappa

This commit is contained in:
Dominik G.
2025-10-06 18:15:27 +02:00
parent 807e8fc5f3
commit 515160b1ec
11 changed files with 3103 additions and 76 deletions

View File

@@ -0,0 +1,133 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
// Project namespaces
using MegaKoop.Steam; // SteamManager, SteamLobbyService
using MegaKoop.Game.Networking; // SteamCoopNetworkManager, SteamP2PTransport, LobbyGameSceneCoordinator
public static class CharacterSceneSetupGenerator
{
private const string WizardPrefabPath = "Assets/Game/Hero/Wizard.prefab";
[MenuItem("Tools/MegaKoop/Setup Character Scene Objects", priority = 1000)]
public static void SetupCharacterScene()
{
var scene = SceneManager.GetActiveScene();
if (!scene.IsValid())
{
EditorUtility.DisplayDialog("Character Scene Setup", "No valid scene is open. Please open your CharacterScene and run again.", "OK");
return;
}
Undo.IncrementCurrentGroup();
int group = Undo.GetCurrentGroup();
// 1) Ensure SteamServices root and required components
var servicesRoot = GameObject.Find("SteamServices");
if (servicesRoot == null)
{
servicesRoot = new GameObject("SteamServices");
Undo.RegisterCreatedObjectUndo(servicesRoot, "Create SteamServices");
}
EnsureComponent<SteamManager>(servicesRoot, "Add SteamManager");
var lobby = EnsureComponent<SteamLobbyService>(servicesRoot, "Add SteamLobbyService");
var coop = EnsureComponent<SteamCoopNetworkManager>(servicesRoot, "Add SteamCoopNetworkManager");
EnsureComponent<SteamP2PTransport>(servicesRoot, "Add SteamP2PTransport");
var coordinator = EnsureComponent<LobbyGameSceneCoordinator>(servicesRoot, "Add LobbyGameSceneCoordinator");
// Keep servicesRoot persistent across scenes to match runtime behavior
if (!Application.isPlaying)
{
// Editor-time: mark as DontSaveInBuild is not needed; users expect this object in scene.
// At runtime, code calls DontDestroyOnLoad itself.
}
// 2) Ensure Wizard template exists in scene root
var wizardInScene = GameObject.Find("Wizard");
if (wizardInScene == null)
{
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(WizardPrefabPath);
if (prefab != null)
{
var instantiated = PrefabUtility.InstantiatePrefab(prefab, scene) as GameObject;
if (instantiated != null)
{
Undo.RegisterCreatedObjectUndo(instantiated, "Instantiate Wizard Template");
instantiated.name = "Wizard"; // Ensure exact name for coordinator lookup
instantiated.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
}
}
else
{
// Fallback: create a simple placeholder
var placeholder = GameObject.CreatePrimitive(PrimitiveType.Capsule);
Undo.RegisterCreatedObjectUndo(placeholder, "Create Wizard Placeholder");
placeholder.name = "Wizard";
placeholder.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
// Controller components are optional for template; coordinator will add bridges on clones.
placeholder.AddComponent<CharacterController>();
placeholder.AddComponent<MegaKoop.Game.ThirdPersonCharacterController>();
}
}
// 3) Optional: ensure a basic ground so CharacterController can stand
if (GameObject.Find("Ground") == null)
{
var ground = GameObject.CreatePrimitive(PrimitiveType.Plane);
Undo.RegisterCreatedObjectUndo(ground, "Create Ground");
ground.name = "Ground";
ground.transform.position = Vector3.zero;
ground.transform.localScale = Vector3.one * 2f;
}
// 4) Optional: ensure there is at least one light
if (Object.FindObjectOfType<Light>() == null)
{
var lightGO = new GameObject("Directional Light");
Undo.RegisterCreatedObjectUndo(lightGO, "Create Directional Light");
var light = lightGO.AddComponent<Light>();
light.type = LightType.Directional;
light.intensity = 1.1f;
lightGO.transform.rotation = Quaternion.Euler(50f, -30f, 0f);
}
// 5) Hint coordinator to use current scene name if it differs
if (coordinator != null)
{
// If you want the coordinator to target this scene specifically, uncomment the next line:
// SetPrivateField(coordinator, "characterSceneName", scene.name);
}
EditorSceneManager.MarkSceneDirty(scene);
Undo.CollapseUndoOperations(group);
EditorUtility.DisplayDialog("Character Scene Setup", "Character scene objects have been set up successfully.", "OK");
}
private static T EnsureComponent<T>(GameObject go, string undoName) where T : Component
{
var c = go.GetComponent<T>();
if (c == null)
{
c = Undo.AddComponent<T>(go);
}
return c;
}
// Example helper if you later want to set private serialized fields via reflection
private static void SetPrivateField(object target, string fieldName, object value)
{
var t = target.GetType();
var f = t.GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (f != null)
{
f.SetValue(target, value);
EditorUtility.SetDirty((Object)target);
}
}
}
#endif