From b95c5bdb1370baeb2c91f20934998981c5038f81 Mon Sep 17 00:00:00 2001 From: dal4segno Date: Tue, 1 Sep 2026 08:56:15 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B8=B0=EC=A1=B4=20=EC=8B=9C=EC=8A=A4?= =?UTF-8?q?=ED=85=9C=20=EC=9E=AC=EC=82=AC=EC=9A=A9=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=86=A0=ED=83=80=EC=9E=85=20=EB=B3=B4=EC=A1=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assembly-CSharp.csproj | 6 +- Assets/DefaultNetworkPrefabs.asset | 5 + .../Editor/PrototypePlayModeSmoke.cs | 5 + .../Editor/PrototypeSceneBuilder.cs | 267 +++++----- .../Generated/Materials/Core.mat | 137 ----- .../Generated/Materials/Core.mat.meta | 8 - .../Generated/Materials/Digger.mat | 137 ----- .../Generated/Materials/Digger.mat.meta | 8 - .../Generated/Materials/Elite.mat | 137 ----- .../Generated/Materials/Elite.mat.meta | 8 - .../Generated/Materials/Enemy.mat | 137 ----- .../Generated/Materials/Enemy.mat.meta | 8 - .../Generated/Materials/Player.mat | 137 ----- .../Generated/Materials/Player.mat.meta | 8 - .../Generated/Materials/Raider.mat | 137 ----- .../Generated/Materials/Raider.mat.meta | 8 - .../Generated/Materials/Ruined.mat | 137 ----- .../Generated/Materials/Ruined.mat.meta | 8 - .../Generated/Prefabs/BasicTower.prefab | 306 ----------- .../Generated/Prefabs/BasicTower.prefab.meta | 7 - .../Generated/Prefabs/Enemy_Digger.prefab | 242 --------- .../Prefabs/Enemy_Digger.prefab.meta | 7 - .../Generated/Prefabs/Enemy_Elite.prefab | 242 --------- .../Generated/Prefabs/Enemy_Elite.prefab.meta | 7 - .../Generated/Prefabs/Enemy_Grunt.prefab | 242 --------- .../Generated/Prefabs/Enemy_Grunt.prefab.meta | 7 - .../Generated/Prefabs/Enemy_Raider.prefab | 242 --------- .../Prefabs/Enemy_Raider.prefab.meta | 7 - .../Generated/Prefabs/Player.prefab | 481 ++++++------------ .../Generated/PrototypeNetworkPrefabs.asset | 17 +- .../Scenes/NorthboundGameplayPrototype.unity | Bin 97344 -> 338464 bytes .../NorthboundPrototype/Scripts/PortalSite.cs | 120 +++-- .../Scripts/PrototypeCameraRig.cs | 19 - .../Scripts/PrototypeCameraRig.cs.meta | 2 - .../Scripts/PrototypeCore.cs | 23 - .../Scripts/PrototypeCore.cs.meta | 2 - .../Scripts/PrototypeCrystalOutpost.cs | 63 ++- .../Scripts/PrototypeDefenseSlot.cs | 35 +- .../Scripts/PrototypeEnemy.cs | 105 ---- .../Scripts/PrototypeEnemy.cs.meta | 2 - .../Scripts/PrototypeGameState.cs | 6 + .../Scripts/PrototypeHud.cs | 10 +- .../Scripts/PrototypeNetworkLauncher.cs | 3 + .../Scripts/PrototypePlayer.cs | 135 ----- .../Scripts/PrototypePlayer.cs.meta | 2 - .../Scripts/PrototypeSmokeRunner.cs | 39 +- .../Scripts/PrototypeSpecialAttack.cs | 55 ++ .../Scripts/PrototypeSpecialAttack.cs.meta | 2 + .../Scripts/PrototypeTower.cs | 27 - .../Scripts/PrototypeTower.cs.meta | 2 - .../Scripts/PrototypeTypes.cs | 9 - .../Scripts/PrototypeWaveManager.cs | 90 ++-- Assets/Scripts/AttackAction.cs | 12 +- Assets/Scripts/EnemyPortal.cs | 52 +- Assets/Scripts/NetworkConnectionHandler.cs | 38 +- Assets/Scripts/NetworkPlayerController.cs | 27 +- Assets/Scripts/PlayerActionSystem.cs | 16 + Assets/Scripts/SimpleCameraZFollow.cs | 11 +- 58 files changed, 714 insertions(+), 3298 deletions(-) delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Core.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Core.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Digger.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Digger.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Elite.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Elite.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Enemy.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Enemy.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Player.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Player.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Raider.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Raider.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Ruined.mat delete mode 100644 Assets/NorthboundPrototype/Generated/Materials/Ruined.mat.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab.meta delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab delete mode 100644 Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab.meta delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs.meta delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeCore.cs delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeCore.cs.meta delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs.meta delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs.meta create mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs create mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs.meta delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeTower.cs delete mode 100644 Assets/NorthboundPrototype/Scripts/PrototypeTower.cs.meta diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj index ba1b199..9cde786 100644 --- a/Assembly-CSharp.csproj +++ b/Assembly-CSharp.csproj @@ -58,9 +58,7 @@ - - @@ -71,7 +69,6 @@ - @@ -85,7 +82,6 @@ - @@ -119,7 +115,6 @@ - @@ -130,6 +125,7 @@ + diff --git a/Assets/DefaultNetworkPrefabs.asset b/Assets/DefaultNetworkPrefabs.asset index 43d0f17..efdbbed 100644 --- a/Assets/DefaultNetworkPrefabs.asset +++ b/Assets/DefaultNetworkPrefabs.asset @@ -214,3 +214,8 @@ MonoBehaviour: SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 4054730026397922910, guid: 2a0bac19258f9514691bd9aff479dfea, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} diff --git a/Assets/NorthboundPrototype/Editor/PrototypePlayModeSmoke.cs b/Assets/NorthboundPrototype/Editor/PrototypePlayModeSmoke.cs index 6c677d1..e8b1a33 100644 --- a/Assets/NorthboundPrototype/Editor/PrototypePlayModeSmoke.cs +++ b/Assets/NorthboundPrototype/Editor/PrototypePlayModeSmoke.cs @@ -5,8 +5,13 @@ namespace Northbound.Prototype.Editor { public static class PrototypePlayModeSmoke { + public const string SessionKey = "Northbound.Prototype.InteractiveSmoke"; + + [MenuItem("Northbound/Run Gameplay Prototype Smoke Test")] public static void Start() { + bool commandLineSmoke = System.Array.Exists(System.Environment.GetCommandLineArgs(), argument => argument == "-prototypeSmoke"); + if (!commandLineSmoke) SessionState.SetBool(SessionKey, true); EditorSceneManager.OpenScene("Assets/NorthboundPrototype/Scenes/NorthboundGameplayPrototype.unity"); EditorApplication.isPlaying = true; } diff --git a/Assets/NorthboundPrototype/Editor/PrototypeSceneBuilder.cs b/Assets/NorthboundPrototype/Editor/PrototypeSceneBuilder.cs index 8dd1091..7d6d707 100644 --- a/Assets/NorthboundPrototype/Editor/PrototypeSceneBuilder.cs +++ b/Assets/NorthboundPrototype/Editor/PrototypeSceneBuilder.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.IO; +using Unity.AI.Navigation; using Unity.Netcode; -using Unity.Netcode.Components; using Unity.Netcode.Transports.UTP; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; +using UnityEngine.AI; using UnityEngine.SceneManagement; namespace Northbound.Prototype.Editor @@ -24,72 +25,81 @@ namespace Northbound.Prototype.Editor public static void Build() { EnsureFolders(); + CleanupObsoletePrototypeAssets(); var palette = CreatePalette(); - GameObject playerPrefab = CreatePlayerPrefab(palette["Player"]); - var enemyPrefabs = new[] + GameObject playerPrefab = CreatePlayerVariant(); + GameObject[] enemyPrefabs = LoadPrefabs(new[] { - CreateEnemyPrefab("Enemy_Grunt", EnemyRole.Grunt, 55f, 8f, 2.4f, palette["Enemy"]), - CreateEnemyPrefab("Enemy_Raider", EnemyRole.Raider, 48f, 7f, 2.9f, palette["Raider"]), - CreateEnemyPrefab("Enemy_Digger", EnemyRole.Digger, 75f, 10f, 2f, palette["Digger"]), - CreateEnemyPrefab("Enemy_Elite", EnemyRole.Elite, 150f, 18f, 1.8f, palette["Elite"]) - }; - GameObject towerPrefab = CreateTowerPrefab(palette["Allied"]); + "Assets/Prefabs/Monster/Monster101.prefab", "Assets/Prefabs/Monster/Monster102.prefab", + "Assets/Prefabs/Monster/Monster103.prefab", "Assets/Prefabs/Monster/Monster104.prefab", + "Assets/Prefabs/Monster/Monster105.prefab" + }); + GameObject towerPrefab = LoadRequired("Assets/Prefabs/Tower/Tower1.prefab"); + GameObject corePrefab = LoadRequired("Assets/Prefabs/Core.prefab"); Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); scene.name = "NorthboundGameplayPrototype"; CreateEnvironment(palette); + CreateSpawnPoints(); var networkRoot = new GameObject("Network Runtime"); var manager = networkRoot.AddComponent(); var transport = networkRoot.AddComponent(); + networkRoot.AddComponent(); var launcher = networkRoot.AddComponent(); networkRoot.AddComponent(); manager.NetworkConfig.NetworkTransport = transport; manager.NetworkConfig.PlayerPrefab = playerPrefab; + manager.NetworkConfig.ConnectionApproval = true; var spawnables = new List(enemyPrefabs) { towerPrefab }; ConfigureNetworkPrefabs(manager, playerPrefab, spawnables); launcher.EditorConfigure(playerPrefab, spawnables); - var state = CreateNetworkSceneObject("Game State", Vector3.zero); + CreateNetworkSceneObject("Game State", Vector3.zero); + var timer = CreateNetworkSceneObject("Global Wave Timer", Vector3.zero); + timer.cycleLength = 90f; timer.exceptionalFirstCycleLength = 15f; timer.autoStart = true; var wave = CreateNetworkSceneObject("Wave Manager", Vector3.zero); - var enemyComponents = Array.ConvertAll(enemyPrefabs, item => item.GetComponent()); - wave.EditorConfigure(enemyComponents); + wave.EditorConfigure(timer, enemyPrefabs); - CreateCore(palette["Core"]); + CreateCore(corePrefab); PortalSite[] portals = CreatePortals(palette); var crystals = CreateCrystals(palette["Crystal"]); - CreateDefenseSlots(crystals, towerPrefab.GetComponent(), palette["Slot"]); + CreateDefenseSlots(crystals, towerPrefab, palette["Slot"]); CreateCameraAndHud(launcher, wave); EditorSceneManager.MarkSceneDirty(scene); EditorSceneManager.SaveScene(scene, ScenePath); + BuildNavigation(); + EditorSceneManager.SaveScene(scene, ScenePath); AddToBuildSettings(ScenePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); - Validate(playerPrefab, enemyPrefabs, towerPrefab, portals, crystals); - Debug.Log($"[Northbound Prototype] Built successfully: {ScenePath}"); + Debug.Log($"[Northbound Prototype] Built from reusable project systems: {ScenePath}"); } private static void EnsureFolders() { - Directory.CreateDirectory(Root + "/Scenes"); - Directory.CreateDirectory(Prefabs); - Directory.CreateDirectory(Materials); + Directory.CreateDirectory(Root + "/Scenes"); Directory.CreateDirectory(Prefabs); Directory.CreateDirectory(Materials); AssetDatabase.Refresh(); } + private static void CleanupObsoletePrototypeAssets() + { + string[] obsolete = { "BasicTower.prefab", "Enemy_Grunt.prefab", "Enemy_Raider.prefab", "Enemy_Digger.prefab", "Enemy_Elite.prefab" }; + foreach (string file in obsolete) AssetDatabase.DeleteAsset($"{Prefabs}/{file}"); + string[] obsoleteMaterials = { "Core.mat", "Digger.mat", "Elite.mat", "Enemy.mat", "Player.mat", "Raider.mat", "Ruined.mat" }; + foreach (string file in obsoleteMaterials) AssetDatabase.DeleteAsset($"{Materials}/{file}"); + } + private static Dictionary CreatePalette() { var colors = new Dictionary { ["Ground"] = new(0.08f, 0.11f, 0.14f), ["Road"] = new(0.16f, 0.2f, 0.23f), - ["Wall"] = new(0.08f, 0.3f, 0.34f), ["Player"] = new(0.15f, 0.85f, 1f), - ["Enemy"] = new(0.85f, 0.16f, 0.24f), ["Raider"] = new(1f, 0.42f, 0.12f), - ["Digger"] = new(0.65f, 0.28f, 0.13f), ["Elite"] = new(0.85f, 0.1f, 0.75f), - ["Allied"] = new(0.1f, 0.72f, 1f), ["PortalEnemy"] = new(0.8f, 0.1f, 0.65f), - ["Ruined"] = new(0.25f, 0.25f, 0.28f), ["Core"] = new(0.15f, 0.95f, 0.65f), - ["Crystal"] = new(0.4f, 0.25f, 0.9f), ["Slot"] = new(0.25f, 0.38f, 0.42f) + ["Wall"] = new(0.08f, 0.3f, 0.34f), ["Allied"] = new(0.1f, 0.72f, 1f), + ["PortalEnemy"] = new(0.8f, 0.1f, 0.65f), ["Crystal"] = new(0.4f, 0.25f, 0.9f), + ["Slot"] = new(0.25f, 0.38f, 0.42f) }; var result = new Dictionary(); Shader shader = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"); @@ -98,78 +108,70 @@ namespace Northbound.Prototype.Editor string path = $"{Materials}/{pair.Key}.mat"; var material = AssetDatabase.LoadAssetAtPath(path); if (material == null) { material = new Material(shader); AssetDatabase.CreateAsset(material, path); } - material.color = pair.Value; - EditorUtility.SetDirty(material); - result[pair.Key] = material; + material.color = pair.Value; EditorUtility.SetDirty(material); result[pair.Key] = material; } return result; } - private static GameObject CreatePlayerPrefab(Material material) + private static GameObject CreatePlayerVariant() { string path = Prefabs + "/Player.prefab"; - var root = new GameObject("Prototype Player"); - root.AddComponent(); - root.AddComponent(); - root.AddComponent(); - root.AddComponent(); - var body = CreatePrimitive("Body", PrimitiveType.Capsule, root.transform, Vector3.zero, new Vector3(0.8f, 0.8f, 0.8f), material, false); - CreatePrimitive("Facing", PrimitiveType.Cube, root.transform, new Vector3(0f, 0.15f, 0.75f), new Vector3(0.25f, 0.25f, 0.75f), material, false); - var prefab = PrefabUtility.SaveAsPrefabAsset(root, path); - UnityEngine.Object.DestroyImmediate(root); + GameObject source = LoadRequired("Assets/Prefabs/Player/Player.prefab"); + AssetDatabase.DeleteAsset(path); + var instance = (GameObject)PrefabUtility.InstantiatePrefab(source); + instance.name = "Prototype Player (Player Variant)"; + var controller = instance.GetComponent(); controller.ConfigurePrototypeMode(); + var attack = instance.GetComponent(); + attack.useFacingArc = true; attack.minimumFacingDot = 0.2f; attack.useAnimationEvents = false; + attack.blockDuringAnimation = false; attack.useEquipment = false; attack.attackAnimationTrigger = string.Empty; + var special = instance.AddComponent(); + var actions = instance.GetComponent(); + actions.actionComponents.Clear(); actions.actionComponents.Add(attack); actions.actionComponents.Add(special); + actions.secondaryActionName = "SpecialAttack"; actions.playAnimations = false; + var interaction = instance.GetComponent(); + interaction.playAnimations = false; interaction.useAnimationEvents = false; interaction.useEquipment = false; + interaction.blockDuringAnimation = false; interaction.showDebugRay = false; + Disable(instance); Disable(instance); + Disable(instance); Disable(instance); + var prefab = PrefabUtility.SaveAsPrefabAsset(instance, path); + UnityEngine.Object.DestroyImmediate(instance); return prefab; } - private static GameObject CreateEnemyPrefab(string name, EnemyRole role, float health, float damage, float speed, Material material) + private static void Disable(GameObject gameObject) where T : Behaviour { - string path = $"{Prefabs}/{name}.prefab"; - var root = new GameObject(name); - root.AddComponent(); - root.AddComponent(); - var collider = root.AddComponent(); collider.height = 1.4f; collider.radius = 0.45f; - var enemy = root.AddComponent(); enemy.EditorConfigure(role, health, damage, speed); - float scale = role == EnemyRole.Elite ? 1.35f : 0.75f; - CreatePrimitive("Body", PrimitiveType.Capsule, root.transform, Vector3.zero, Vector3.one * scale, material, false); - var prefab = PrefabUtility.SaveAsPrefabAsset(root, path); - UnityEngine.Object.DestroyImmediate(root); - return prefab; - } - - private static GameObject CreateTowerPrefab(Material material) - { - string path = Prefabs + "/BasicTower.prefab"; - var root = new GameObject("Basic Tower"); - root.AddComponent(); - root.AddComponent(); - root.AddComponent(); - CreatePrimitive("Base", PrimitiveType.Cylinder, root.transform, Vector3.zero, new Vector3(0.8f, 0.6f, 0.8f), material, false); - CreatePrimitive("Head", PrimitiveType.Cube, root.transform, new Vector3(0f, 1f, 0f), new Vector3(0.55f, 0.35f, 0.8f), material, false); - var prefab = PrefabUtility.SaveAsPrefabAsset(root, path); - UnityEngine.Object.DestroyImmediate(root); - return prefab; + var component = gameObject.GetComponent(); if (component != null) component.enabled = false; } private static void CreateEnvironment(Dictionary palette) { CreatePrimitive("Ground", PrimitiveType.Cube, null, new Vector3(0f, -0.55f, 3f), new Vector3(34f, 1f, 180f), palette["Ground"]); - CreatePrimitive("Northbound Road", PrimitiveType.Cube, null, new Vector3(0f, 0f, 3f), new Vector3(13f, 0.12f, 180f), palette["Road"]); + CreatePrimitive("Northbound Road", PrimitiveType.Cube, null, new Vector3(0f, -0.02f, 3f), new Vector3(13f, 0.08f, 180f), palette["Road"]); CreatePrimitive("West Boundary", PrimitiveType.Cube, null, new Vector3(-17f, 1f, 3f), new Vector3(1f, 3f, 180f), palette["Wall"]); CreatePrimitive("East Boundary", PrimitiveType.Cube, null, new Vector3(17f, 1f, 3f), new Vector3(1f, 3f, 180f), palette["Wall"]); - float[] bandZ = { -62f, -20f, 25f, 70f }; - string[] names = { "본진", "첫 확장", "포탈 전초", "최종 코어" }; - for (int i = 0; i < bandZ.Length; i++) - CreatePrimitive(names[i], PrimitiveType.Cube, null, new Vector3(0f, 0.08f, bandZ[i]), new Vector3(32f, 0.08f, 1f), palette["Wall"]); - + float[] bands = { -62f, -20f, 25f, 70f }; + foreach (float z in bands) CreatePrimitive("Operation Band", PrimitiveType.Cube, null, new Vector3(0f, 0.04f, z), new Vector3(32f, 0.05f, 0.5f), palette["Wall"], false); var lightObject = new GameObject("Directional Light"); var light = lightObject.AddComponent(); light.type = LightType.Directional; light.intensity = 1.3f; lightObject.transform.rotation = Quaternion.Euler(55f, -30f, 0f); } - private static void CreateCore(Material material) + private static void CreateSpawnPoints() { - var core = CreateNetworkSceneObject("South Core", new Vector3(0f, 1.5f, -78f)); - var collider = core.gameObject.AddComponent(); collider.size = new Vector3(5f, 3f, 3f); - CreatePrimitive("Core Visual", PrimitiveType.Cube, core.transform, Vector3.zero, new Vector3(5f, 3f, 3f), material, false); + for (int i = 0; i < 4; i++) + { + var point = new GameObject($"Player Spawn {i + 1}"); + point.transform.position = new Vector3((i - 1.5f) * 2f, 0.1f, -74f); + point.transform.forward = Vector3.forward; + point.AddComponent().spawnIndex = i; + } + } + + private static void CreateCore(GameObject corePrefab) + { + var instance = (GameObject)PrefabUtility.InstantiatePrefab(corePrefab); + instance.name = "South Core (Reused)"; instance.transform.position = new Vector3(0f, 0f, -78f); + var core = instance.GetComponent(); core.maxHealth = 500; core.unlimitedStorage = true; } private static PortalSite[] CreatePortals(Dictionary palette) @@ -179,19 +181,27 @@ namespace Northbound.Prototype.Editor var portals = new PortalSite[z.Length]; for (int i = 0; i < z.Length; i++) { - portals[i] = CreateNetworkSceneObject($"P{i} Portal Site", new Vector3(0f, 0.5f, z[i])); - var trigger = portals[i].gameObject.AddComponent(); - trigger.size = new Vector3(4.5f, 2f, 2.5f); - trigger.isTrigger = true; - var visual = CreatePrimitive("Portal Ring", PrimitiveType.Cylinder, portals[i].transform, Vector3.zero, - new Vector3(2.2f, 0.25f, 2.2f), states[i] == PortalState.Allied ? palette["Allied"] : palette["PortalEnemy"], false); - portals[i].EditorConfigure(i, i == z.Length - 1, states[i], null, null, visual.GetComponent()); + var root = new GameObject($"P{i} Portal Site"); root.transform.position = new Vector3(0f, 0.4f, z[i]); + root.AddComponent(); root.AddComponent(); root.AddComponent(); + portals[i] = root.AddComponent(); + var detection = root.AddComponent(); detection.radius = 2.3f; detection.isTrigger = true; + var southTrigger = root.AddComponent(); southTrigger.center = new Vector3(0f, 0f, -1.35f); southTrigger.size = new Vector3(4.5f, 2f, 0.8f); southTrigger.isTrigger = true; + var northTrigger = root.AddComponent(); northTrigger.center = new Vector3(0f, 0f, 1.35f); northTrigger.size = new Vector3(4.5f, 2f, 0.8f); northTrigger.isTrigger = true; + Transform southArrival = CreateMarker("South Arrival", root.transform, new Vector3(0f, 0.4f, -3f)); + Transform northArrival = CreateMarker("North Arrival", root.transform, new Vector3(0f, 0.4f, 3f)); + var visual = CreatePrimitive("Portal Ring", PrimitiveType.Cylinder, root.transform, Vector3.zero, new Vector3(2.2f, 0.25f, 2.2f), + states[i] == PortalState.Allied ? palette["Allied"] : palette["PortalEnemy"], false); + portals[i].EditorConfigure(i, i == z.Length - 1, states[i], null, null, visual.GetComponent(), southTrigger, northTrigger, southArrival, northArrival); } - for (int i = 0; i < portals.Length; i++) - portals[i].EditorSetNeighbors(i > 0 ? portals[i - 1] : null, i + 1 < portals.Length ? portals[i + 1] : null); + for (int i = 0; i < portals.Length; i++) portals[i].EditorSetNeighbors(i > 0 ? portals[i - 1] : null, i + 1 < portals.Length ? portals[i + 1] : null); return portals; } + private static Transform CreateMarker(string name, Transform parent, Vector3 position) + { + var marker = new GameObject(name); marker.transform.SetParent(parent, false); marker.transform.localPosition = position; return marker.transform; + } + private static PrototypeCrystalOutpost[] CreateCrystals(Material material) { Vector3[] positions = { new(-8f, 0.8f, -43f), new(8f, 0.8f, 2f), new(-8f, 0.8f, 48f) }; @@ -201,87 +211,80 @@ namespace Northbound.Prototype.Editor result[i] = CreateNetworkSceneObject($"Crystal Outpost {i + 1}", positions[i]); var collider = result[i].gameObject.AddComponent(); collider.radius = 1.2f; var visual = CreatePrimitive("Crystal", PrimitiveType.Cube, result[i].transform, Vector3.zero, new Vector3(1.2f, 1.8f, 1.2f), material, false); - visual.transform.rotation = Quaternion.Euler(0f, 45f, 45f); - result[i].EditorConfigure(visual.GetComponent()); + visual.transform.rotation = Quaternion.Euler(0f, 45f, 45f); result[i].EditorConfigure(visual.GetComponent()); } return result; } - private static void CreateDefenseSlots(PrototypeCrystalOutpost[] crystals, PrototypeTower towerPrefab, Material material) + private static void CreateDefenseSlots(PrototypeCrystalOutpost[] crystals, GameObject towerPrefab, Material material) { for (int i = 0; i < crystals.Length; i++) { var visual = CreatePrimitive($"Defense Slot {i + 1}", PrimitiveType.Cylinder, null, crystals[i].transform.position + new Vector3(3.2f, -0.55f, 0f), new Vector3(1.25f, 0.12f, 1.25f), material); - var slot = visual.AddComponent(); - slot.EditorConfigure(crystals[i], towerPrefab); + visual.AddComponent(); + visual.AddComponent().EditorConfigure(crystals[i], towerPrefab); } } private static void CreateCameraAndHud(PrototypeNetworkLauncher launcher, PrototypeWaveManager wave) { - var cameraObject = new GameObject("Main Camera"); - cameraObject.tag = "MainCamera"; + var cameraObject = new GameObject("Main Camera"); cameraObject.tag = "MainCamera"; var camera = cameraObject.AddComponent(); camera.orthographic = true; camera.orthographicSize = 16f; - cameraObject.transform.position = new Vector3(0f, 30f, -62f); - cameraObject.transform.rotation = Quaternion.Euler(90f, 0f, 0f); - cameraObject.AddComponent(); - var hud = cameraObject.AddComponent(); hud.EditorConfigure(launcher, wave); - cameraObject.AddComponent(); + cameraObject.transform.position = new Vector3(0f, 30f, -62f); cameraObject.transform.rotation = Quaternion.Euler(90f, 0f, 0f); + cameraObject.AddComponent().Configure(30f, 6f, 8f); + cameraObject.AddComponent().EditorConfigure(launcher, wave); cameraObject.AddComponent(); + } + + private static void BuildNavigation() + { + var navigation = new GameObject("Navigation (Reused EnemyAI)"); + var surface = navigation.AddComponent(); surface.useGeometry = NavMeshCollectGeometry.PhysicsColliders; + surface.BuildNavMesh(); } private static T CreateNetworkSceneObject(string name, Vector3 position) where T : Component { - var gameObject = new GameObject(name); gameObject.transform.position = position; - gameObject.AddComponent(); - return gameObject.AddComponent(); + var gameObject = new GameObject(name); gameObject.transform.position = position; gameObject.AddComponent(); return gameObject.AddComponent(); } private static GameObject CreatePrimitive(string name, PrimitiveType type, Transform parent, Vector3 position, Vector3 scale, Material material, bool collider = true) { var gameObject = GameObject.CreatePrimitive(type); gameObject.name = name; - if (!collider) - { - var primitiveCollider = gameObject.GetComponent(); - if (primitiveCollider != null) UnityEngine.Object.DestroyImmediate(primitiveCollider); - } - if (parent != null) { gameObject.transform.SetParent(parent, false); gameObject.transform.localPosition = position; } - else gameObject.transform.position = position; - gameObject.transform.localScale = scale; - gameObject.GetComponent().sharedMaterial = material; - return gameObject; + if (!collider) { var primitiveCollider = gameObject.GetComponent(); if (primitiveCollider != null) UnityEngine.Object.DestroyImmediate(primitiveCollider); } + if (parent != null) { gameObject.transform.SetParent(parent, false); gameObject.transform.localPosition = position; } else gameObject.transform.position = position; + gameObject.transform.localScale = scale; gameObject.GetComponent().sharedMaterial = material; return gameObject; + } + + private static T LoadRequired(string path) where T : UnityEngine.Object + { + var asset = AssetDatabase.LoadAssetAtPath(path); if (asset == null) throw new InvalidOperationException($"Required reusable asset is missing: {path}"); return asset; + } + + private static GameObject[] LoadPrefabs(string[] paths) + { + var result = new GameObject[paths.Length]; for (int i = 0; i < paths.Length; i++) result[i] = LoadRequired(paths[i]); return result; } private static void AddToBuildSettings(string path) { var scenes = new List(EditorBuildSettings.scenes); - if (scenes.Exists(item => item.path == path)) return; - scenes.Add(new EditorBuildSettingsScene(path, true)); + if (!scenes.Exists(item => item.path == path)) scenes.Add(new EditorBuildSettingsScene(path, true)); EditorBuildSettings.scenes = scenes.ToArray(); } private static void ConfigureNetworkPrefabs(NetworkManager manager, GameObject player, List spawnables) { var prefabList = AssetDatabase.LoadAssetAtPath(PrefabListPath); - if (prefabList == null) - { - prefabList = ScriptableObject.CreateInstance(); - AssetDatabase.CreateAsset(prefabList, PrefabListPath); - } - var desired = new List { player }; - desired.AddRange(spawnables); - var existing = new List(prefabList.PrefabList); - foreach (var entry in existing) prefabList.Remove(entry); + if (prefabList == null) { prefabList = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(prefabList, PrefabListPath); } + var desired = new List { player }; desired.AddRange(spawnables); + foreach (var entry in new List(prefabList.PrefabList)) prefabList.Remove(entry); foreach (var prefab in desired) prefabList.Add(new NetworkPrefab { Override = NetworkPrefabOverride.None, Prefab = prefab }); - - manager.NetworkConfig.Prefabs.NetworkPrefabsLists.Clear(); - manager.NetworkConfig.Prefabs.NetworkPrefabsLists.Add(prefabList); - + manager.NetworkConfig.Prefabs.NetworkPrefabsLists.Clear(); manager.NetworkConfig.Prefabs.NetworkPrefabsLists.Add(prefabList); var defaultList = AssetDatabase.LoadAssetAtPath("Assets/DefaultNetworkPrefabs.asset"); if (defaultList != null) { - foreach (var entry in new List(defaultList.PrefabList)) - if (desired.Contains(entry.Prefab)) defaultList.Remove(entry); + foreach (var entry in new List(defaultList.PrefabList)) if (desired.Contains(entry.Prefab)) defaultList.Remove(entry); EditorUtility.SetDirty(defaultList); } EditorUtility.SetDirty(prefabList); @@ -289,15 +292,13 @@ namespace Northbound.Prototype.Editor private static void Validate(GameObject player, GameObject[] enemies, GameObject tower, PortalSite[] portals, PrototypeCrystalOutpost[] crystals) { - if (player.GetComponent() == null || player.GetComponent() == null) - throw new InvalidOperationException("Player prefab is incomplete."); + if (player.GetComponent() == null || player.GetComponent() == null || player.GetComponent() == null) + throw new InvalidOperationException("Reusable player variant is incomplete."); foreach (var enemy in enemies) - if (enemy.GetComponent() == null || enemy.GetComponent() == null) - throw new InvalidOperationException($"Enemy prefab is incomplete: {enemy.name}"); - if (tower.GetComponent() == null || portals.Length != 4 || crystals.Length != 3) - throw new InvalidOperationException("Prototype scope validation failed."); - for (int i = 0; i < portals.Length; i++) - if (portals[i].SiteIndex != i) throw new InvalidOperationException("Portal chain ordering is invalid."); + if (enemy.GetComponent() == null || enemy.GetComponent() == null || enemy.GetComponent() == null) + throw new InvalidOperationException($"Reusable enemy prefab is incomplete: {enemy.name}"); + if (tower.GetComponent() == null || portals.Length != 4 || crystals.Length != 3 || UnityEngine.Object.FindAnyObjectByType() == null) + throw new InvalidOperationException("Reusable prototype scope validation failed."); } } } diff --git a/Assets/NorthboundPrototype/Generated/Materials/Core.mat b/Assets/NorthboundPrototype/Generated/Materials/Core.mat deleted file mode 100644 index 66f4605..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Core.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &-8592509938752659209 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Core - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.15, g: 0.95, b: 0.65, a: 1} - - _Color: {r: 0.14999998, g: 0.95, b: 0.65, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Core.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Core.mat.meta deleted file mode 100644 index d559368..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Core.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: bce46cc4fcdf4964db22a043d147b739 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Digger.mat b/Assets/NorthboundPrototype/Generated/Materials/Digger.mat deleted file mode 100644 index 53dd718..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Digger.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Digger - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.65, g: 0.28, b: 0.13, a: 1} - - _Color: {r: 0.65, g: 0.27999997, b: 0.12999997, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 ---- !u!114 &2428008234010919257 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Digger.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Digger.mat.meta deleted file mode 100644 index aca9091..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Digger.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0a698bf6bb63d87478cac34b0f68c142 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Elite.mat b/Assets/NorthboundPrototype/Generated/Materials/Elite.mat deleted file mode 100644 index ed13cdd..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Elite.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Elite - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.85, g: 0.1, b: 0.75, a: 1} - - _Color: {r: 0.85, g: 0.09999997, b: 0.75, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 ---- !u!114 &2328575930398375868 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Elite.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Elite.mat.meta deleted file mode 100644 index ca4ae88..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Elite.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 102393053b60ece44b904614372d6870 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat b/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat deleted file mode 100644 index 25b68d1..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Enemy - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.85, g: 0.16, b: 0.24, a: 1} - - _Color: {r: 0.85, g: 0.15999997, b: 0.23999995, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 ---- !u!114 &6827877772939304228 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat.meta deleted file mode 100644 index 09ad2f0..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Enemy.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a89357393ee87964fa2f7116f9d159de -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Player.mat b/Assets/NorthboundPrototype/Generated/Materials/Player.mat deleted file mode 100644 index 6503c85..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Player.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Player - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.15, g: 0.85, b: 1, a: 1} - - _Color: {r: 0.14999998, g: 0.85, b: 1, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 ---- !u!114 &9142823389044075409 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Player.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Player.mat.meta deleted file mode 100644 index a964da0..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Player.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7731605e2e21ed94fa6f9f66ecad2912 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Raider.mat b/Assets/NorthboundPrototype/Generated/Materials/Raider.mat deleted file mode 100644 index 55881ef..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Raider.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!114 &-3609749111221157630 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Raider - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 1, g: 0.42, b: 0.12, a: 1} - - _Color: {r: 1, g: 0.41999996, b: 0.11999995, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Raider.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Raider.mat.meta deleted file mode 100644 index aa3c8e1..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Raider.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5ea9b08c6c96a5841858a20ccc70924a -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat b/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat deleted file mode 100644 index d6b8648..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat +++ /dev/null @@ -1,137 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: Ruined - m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: - RenderType: Opaque - disabledShaderPasses: - - MOTIONVECTORS - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _BaseMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _BumpMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailAlbedoMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailMask: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _DetailNormalMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _EmissionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MetallicGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _OcclusionMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _ParallaxMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _SpecGlossMap: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_Lightmaps: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_LightmapsInd: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - unity_ShadowMasks: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _AddPrecomputedVelocity: 0 - - _AlphaClip: 0 - - _AlphaToMask: 0 - - _Blend: 0 - - _BlendModePreserveSpecular: 1 - - _BumpScale: 1 - - _ClearCoatMask: 0 - - _ClearCoatSmoothness: 0 - - _Cull: 2 - - _Cutoff: 0.5 - - _DetailAlbedoMapScale: 1 - - _DetailNormalMapScale: 1 - - _DstBlend: 0 - - _DstBlendAlpha: 0 - - _EnvironmentReflections: 1 - - _GlossMapScale: 0 - - _Glossiness: 0 - - _GlossyReflections: 0 - - _Metallic: 0 - - _OcclusionStrength: 1 - - _Parallax: 0.005 - - _QueueOffset: 0 - - _ReceiveShadows: 1 - - _Smoothness: 0.5 - - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 - - _SrcBlend: 1 - - _SrcBlendAlpha: 1 - - _Surface: 0 - - _WorkflowMode: 1 - - _XRMotionVectorsPass: 1 - - _ZWrite: 1 - m_Colors: - - _BaseColor: {r: 0.25, g: 0.25, b: 0.28, a: 1} - - _Color: {r: 0.24999997, g: 0.24999997, b: 0.27999997, a: 1} - - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - m_BuildTextureStacks: [] - m_AllowLocking: 1 ---- !u!114 &3866783289780477995 -MonoBehaviour: - m_ObjectHideFlags: 11 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion - version: 10 diff --git a/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat.meta b/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat.meta deleted file mode 100644 index 45c2442..0000000 --- a/Assets/NorthboundPrototype/Generated/Materials/Ruined.mat.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 92f8ac4e67debf8479c82def6f3836b4 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab deleted file mode 100644 index bc8c6b5..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab +++ /dev/null @@ -1,306 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &768884422563280646 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1075458732215366247} - - component: {fileID: 1096513232555807006} - - component: {fileID: 6801956297213770839} - m_Layer: 0 - m_Name: Head - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1075458732215366247 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 768884422563280646} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: 0} - m_LocalScale: {x: 0.55, y: 0.35, z: 0.8} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 3624323390632565247} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &1096513232555807006 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 768884422563280646} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &6801956297213770839 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 768884422563280646} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 71c34f710814318499d2d5e7cea2a646, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &1298522748923679250 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3624323390632565247} - - component: {fileID: 7046449473698420447} - - component: {fileID: 4350502199133332513} - - component: {fileID: 1516902282747798504} - m_Layer: 0 - m_Name: BasicTower - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3624323390632565247 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1298522748923679250} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 7944159800952945334} - - {fileID: 1075458732215366247} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &7046449473698420447 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1298522748923679250} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &4350502199133332513 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1298522748923679250} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform - ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!114 &1516902282747798504 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1298522748923679250} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4f17758c8b6cecf4d8246570583e22dd, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeTower - ShowTopMostFoldoutHeaderGroup: 1 - range: 7 - damage: 10 - interval: 1.1 ---- !u!1 &2145807653229648836 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7944159800952945334} - - component: {fileID: 1790276681686249612} - - component: {fileID: 693834352212102242} - m_Layer: 0 - m_Name: Base - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7944159800952945334 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2145807653229648836} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.8, y: 0.6, z: 0.8} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 3624323390632565247} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &1790276681686249612 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2145807653229648836} - m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &693834352212102242 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2145807653229648836} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 71c34f710814318499d2d5e7cea2a646, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab.meta b/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab.meta deleted file mode 100644 index 4a72300..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/BasicTower.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ff6c084700aabbc489c6c0e56506cf06 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab deleted file mode 100644 index 20c0e5f..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab +++ /dev/null @@ -1,242 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &546703575891773344 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 4298135991364965670} - - component: {fileID: 6071643205634787452} - - component: {fileID: 1239652695402831595} - - component: {fileID: 4047942926649971892} - - component: {fileID: 2742339966002404743} - m_Layer: 0 - m_Name: Enemy_Digger - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &4298135991364965670 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 546703575891773344} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 4919206663897003855} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &6071643205634787452 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 546703575891773344} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &1239652695402831595 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 546703575891773344} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform - ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!136 &4047942926649971892 -CapsuleCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 546703575891773344} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.45 - m_Height: 1.4 - m_Direction: 1 - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &2742339966002404743 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 546703575891773344} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9a43da78fc3aae144a68b43728a90ca5, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeEnemy - ShowTopMostFoldoutHeaderGroup: 1 - role: 2 - baseHealth: 75 - baseDamage: 10 - moveSpeed: 2 - attackRange: 1.7 - attackInterval: 1.2 ---- !u!1 &3992247528101023445 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 4919206663897003855} - - component: {fileID: 6900977511851920752} - - component: {fileID: 865596204157637417} - m_Layer: 0 - m_Name: Body - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &4919206663897003855 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3992247528101023445} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.75, y: 0.75, z: 0.75} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 4298135991364965670} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &6900977511851920752 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3992247528101023445} - m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &865596204157637417 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3992247528101023445} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 0a698bf6bb63d87478cac34b0f68c142, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab.meta b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab.meta deleted file mode 100644 index 0626f84..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Digger.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 6283a318d09055c4f87992c5c47ea18f -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab deleted file mode 100644 index 9bdedeb..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab +++ /dev/null @@ -1,242 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &1795128131771378134 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3679712303891192401} - - component: {fileID: 8768589662197385903} - - component: {fileID: 5251907241342160272} - m_Layer: 0 - m_Name: Body - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3679712303891192401 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1795128131771378134} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1.35, y: 1.35, z: 1.35} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 8103940472562161808} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &8768589662197385903 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1795128131771378134} - m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &5251907241342160272 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1795128131771378134} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 102393053b60ece44b904614372d6870, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &3287245990848439041 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 8103940472562161808} - - component: {fileID: 259792593174859173} - - component: {fileID: 7534842398197684391} - - component: {fileID: 3697779272654266178} - - component: {fileID: 5023017987581908238} - m_Layer: 0 - m_Name: Enemy_Elite - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &8103940472562161808 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3287245990848439041} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 3679712303891192401} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &259792593174859173 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3287245990848439041} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &7534842398197684391 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3287245990848439041} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform - ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!136 &3697779272654266178 -CapsuleCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3287245990848439041} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.45 - m_Height: 1.4 - m_Direction: 1 - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &5023017987581908238 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3287245990848439041} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9a43da78fc3aae144a68b43728a90ca5, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeEnemy - ShowTopMostFoldoutHeaderGroup: 1 - role: 3 - baseHealth: 150 - baseDamage: 18 - moveSpeed: 1.8 - attackRange: 1.7 - attackInterval: 1.2 diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab.meta b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab.meta deleted file mode 100644 index b01b89c..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Elite.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9d32d65f4d76dcb4ebd0debe3c504625 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab deleted file mode 100644 index a3ca26d..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab +++ /dev/null @@ -1,242 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &1975996375694978275 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3435552826784425708} - - component: {fileID: 951565621441737621} - - component: {fileID: 6711740459413015917} - m_Layer: 0 - m_Name: Body - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &3435552826784425708 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1975996375694978275} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.75, y: 0.75, z: 0.75} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 310875575452679582} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &951565621441737621 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1975996375694978275} - m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &6711740459413015917 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1975996375694978275} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: a89357393ee87964fa2f7116f9d159de, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &4493379191484186568 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 310875575452679582} - - component: {fileID: 4003507315934272567} - - component: {fileID: 4231877088810639438} - - component: {fileID: 4533994881265421980} - - component: {fileID: 7545991508697308226} - m_Layer: 0 - m_Name: Enemy_Grunt - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &310875575452679582 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4493379191484186568} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 3435552826784425708} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &4003507315934272567 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4493379191484186568} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &4231877088810639438 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4493379191484186568} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform - ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!136 &4533994881265421980 -CapsuleCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4493379191484186568} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.45 - m_Height: 1.4 - m_Direction: 1 - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &7545991508697308226 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4493379191484186568} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9a43da78fc3aae144a68b43728a90ca5, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeEnemy - ShowTopMostFoldoutHeaderGroup: 1 - role: 0 - baseHealth: 55 - baseDamage: 8 - moveSpeed: 2.4 - attackRange: 1.7 - attackInterval: 1.2 diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab.meta b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab.meta deleted file mode 100644 index 8fa49f7..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Grunt.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 6a48fd333dbaeba41a27f5c3ad884627 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab deleted file mode 100644 index 34a25aa..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab +++ /dev/null @@ -1,242 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &1976415545473119508 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7926858731802272204} - - component: {fileID: 6577323741198816241} - - component: {fileID: 5685526065556658820} - - component: {fileID: 4275190733162635858} - - component: {fileID: 6015820101618283219} - m_Layer: 0 - m_Name: Enemy_Raider - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7926858731802272204 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1976415545473119508} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 5501974571960031690} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &6577323741198816241 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1976415545473119508} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &5685526065556658820 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1976415545473119508} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform - ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!136 &4275190733162635858 -CapsuleCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1976415545473119508} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.45 - m_Height: 1.4 - m_Direction: 1 - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &6015820101618283219 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1976415545473119508} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9a43da78fc3aae144a68b43728a90ca5, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeEnemy - ShowTopMostFoldoutHeaderGroup: 1 - role: 1 - baseHealth: 48 - baseDamage: 7 - moveSpeed: 2.9 - attackRange: 1.7 - attackInterval: 1.2 ---- !u!1 &4786693246207265736 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5501974571960031690} - - component: {fileID: 6352401606136868636} - - component: {fileID: 3399186486778199231} - m_Layer: 0 - m_Name: Body - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5501974571960031690 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4786693246207265736} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.75, y: 0.75, z: 0.75} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 7926858731802272204} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &6352401606136868636 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4786693246207265736} - m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3399186486778199231 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4786693246207265736} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 5ea9b08c6c96a5841858a20ccc70924a, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab.meta b/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab.meta deleted file mode 100644 index 6ebf3a5..0000000 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Enemy_Raider.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 2f53defa3aa7c474994f1e59a903be4f -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/NorthboundPrototype/Generated/Prefabs/Player.prefab b/Assets/NorthboundPrototype/Generated/Prefabs/Player.prefab index 7ae5f97..ed5e7a2 100644 --- a/Assets/NorthboundPrototype/Generated/Prefabs/Player.prefab +++ b/Assets/NorthboundPrototype/Generated/Prefabs/Player.prefab @@ -1,337 +1,174 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: ---- !u!1 &1469678369176762886 -GameObject: +--- !u!1001 &3319709612200465506 +PrefabInstance: m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 516432810655764773} - - component: {fileID: 855754173299961746} - - component: {fileID: 2883844877114008318} - m_Layer: 0 - m_Name: Body - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &516432810655764773 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1469678369176762886} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.8, y: 0.8, z: 0.8} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 6373439727280873961} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &855754173299961746 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1469678369176762886} - m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &2883844877114008318 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1469678369176762886} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 7731605e2e21ed94fa6f9f66ecad2912, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} ---- !u!1 &3305664295896478561 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 1314983689436087486, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_Name + value: Player + objectReference: {fileID: 0} + - target: {fileID: 1883169379180791275, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_Enabled + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2148255267416253297, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_Enabled + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 2443072964133329520, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_Enabled + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3792365921352178844, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: respawnDelay + value: 3 + objectReference: {fileID: 0} + - target: {fileID: 3792365921352178844, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: dropResourcesOnDeath + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3792365921352178844, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: blockMovementDuringAttack + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5217638038410020423, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: playAnimations + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5217638038410020423, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: secondaryActionName + value: SpecialAttack + objectReference: {fileID: 0} + - target: {fileID: 5217638038410020423, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: actionComponents.Array.size + value: 2 + objectReference: {fileID: 0} + - target: {fileID: 5217638038410020423, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: 'actionComponents.Array.data[1]' + value: + objectReference: {fileID: 1026917702892562607} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalPosition.y + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 5887522270574905679, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8704851935123448388, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: m_Enabled + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8729870597719024730, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: showDebugRay + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8729870597719024730, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: useEquipment + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8729870597719024730, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: playAnimations + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8729870597719024730, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: useAnimationEvents + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8729870597719024730, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: blockDuringAnimation + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: useEquipment + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: useFacingArc + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: minimumFacingDot + value: 0.2 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: useAnimationEvents + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: blockDuringAnimation + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 9062880697264624749, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + propertyPath: attackAnimationTrigger + value: + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 1314983689436087486, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + insertIndex: -1 + addedObject: {fileID: 1026917702892562607} + m_SourcePrefab: {fileID: 100100000, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} +--- !u!1 &4336466159322648796 stripped GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 1314983689436087486, guid: 6c700f44a7d74e141a002e9484d2057c, type: 3} + m_PrefabInstance: {fileID: 3319709612200465506} m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 6373439727280873961} - - component: {fileID: 5772597820739981499} - - component: {fileID: 7554966871982303628} - - component: {fileID: 2733417887935013464} - - component: {fileID: 1510805080327023404} - m_Layer: 0 - m_Name: Player - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &6373439727280873961 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3305664295896478561} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 516432810655764773} - - {fileID: 5595214951552948994} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &5772597820739981499 +--- !u!114 &1026917702892562607 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3305664295896478561} + m_GameObject: {fileID: 4336466159322648796} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Script: {fileID: 11500000, guid: c645a5457e4901d4199afde290b51961, type: 3} m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject - GlobalObjectIdHash: 0 - InScenePlacedSourceGlobalObjectIdHash: 0 - DeferredDespawnTick: 0 - Ownership: 1 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - m_InScenePlaced: 0 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 - SyncOwnerTransformWhenParented: 1 - AllowOwnerToParent: 0 ---- !u!114 &7554966871982303628 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3305664295896478561} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkTransform + m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypeSpecialAttack ShowTopMostFoldoutHeaderGroup: 1 - NetworkTransformExpanded: 0 - AutoOwnerAuthorityTickOffset: 1 - PositionInterpolationType: 0 - RotationInterpolationType: 0 - ScaleInterpolationType: 0 - PositionLerpSmoothing: 1 - PositionMaxInterpolationTime: 0.1 - RotationLerpSmoothing: 1 - RotationMaxInterpolationTime: 0.1 - ScaleLerpSmoothing: 1 - ScaleMaxInterpolationTime: 0.1 - AuthorityMode: 0 - TickSyncChildren: 0 - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 1 - SyncRotAngleY: 1 - SyncRotAngleZ: 1 - SyncScaleX: 1 - SyncScaleY: 1 - SyncScaleZ: 1 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - SwitchTransformSpaceWhenParented: 0 - Interpolate: 1 - SlerpPosition: 0 ---- !u!136 &2733417887935013464 -CapsuleCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3305664295896478561} - m_Material: {fileID: 0} - m_IncludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_ExcludeLayers: - serializedVersion: 2 - m_Bits: 0 - m_LayerOverridePriority: 0 - m_IsTrigger: 0 - m_ProvidesContacts: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.5 - m_Height: 1 - m_Direction: 1 - m_Center: {x: 0, y: 0, z: 0} ---- !u!114 &1510805080327023404 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3305664295896478561} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 47e38d0512a8abd4c83eda8608e3ef9f, type: 3} - m_Name: - m_EditorClassIdentifier: Assembly-CSharp::Northbound.Prototype.PrototypePlayer - ShowTopMostFoldoutHeaderGroup: 1 - moveSpeed: 8 - xBounds: {x: -15, y: 15} - zBounds: {x: -82, y: 88} - maxHealth: 100 - normalDamage: 24 - normalRange: 3.2 - specialDamage: 58 - specialRange: 6 - specialManaCost: 25 - specialCooldown: 4 ---- !u!1 &7287052643425163852 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5595214951552948994} - - component: {fileID: 7960450478991797233} - - component: {fileID: 3507218640918885721} - m_Layer: 0 - m_Name: Facing - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5595214951552948994 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7287052643425163852} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0.15, z: 0.75} - m_LocalScale: {x: 0.25, y: 0.25, z: 0.75} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 6373439727280873961} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!33 &7960450478991797233 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7287052643425163852} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &3507218640918885721 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 7287052643425163852} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_StaticShadowCaster: 0 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RayTracingMode: 2 - m_RayTraceProcedural: 0 - m_RayTracingAccelStructBuildFlagsOverride: 0 - m_RayTracingAccelStructBuildFlags: 1 - m_SmallMeshCulling: 1 - m_ForceMeshLod: -1 - m_MeshLodSelectionBias: 0 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 7731605e2e21ed94fa6f9f66ecad2912, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_ReceiveGI: 1 - m_PreserveUVs: 1 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 1 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_GlobalIlluminationMeshLod: 0 - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 - m_MaskInteraction: 0 - m_AdditionalVertexStreams: {fileID: 0} + cooldown: 4 + manaCost: 25 + range: 6 + radius: 3.5 + damageMultiplier: 3 + minimumFacingDot: 0.05 diff --git a/Assets/NorthboundPrototype/Generated/PrototypeNetworkPrefabs.asset b/Assets/NorthboundPrototype/Generated/PrototypeNetworkPrefabs.asset index 16c7c27..91ca5f5 100644 --- a/Assets/NorthboundPrototype/Generated/PrototypeNetworkPrefabs.asset +++ b/Assets/NorthboundPrototype/Generated/PrototypeNetworkPrefabs.asset @@ -15,32 +15,37 @@ MonoBehaviour: IsDefault: 0 List: - Override: 0 - Prefab: {fileID: 3305664295896478561, guid: 2a0bac19258f9514691bd9aff479dfea, type: 3} + Prefab: {fileID: 4336466159322648796, guid: 2a0bac19258f9514691bd9aff479dfea, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 4493379191484186568, guid: 6a48fd333dbaeba41a27f5c3ad884627, type: 3} + Prefab: {fileID: 7146441246397375875, guid: eccdace7a7b21a446891da5739b1549f, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 1976415545473119508, guid: 2f53defa3aa7c474994f1e59a903be4f, type: 3} + Prefab: {fileID: 9065146123892903723, guid: 4ee9b364dfe9d0949a23374e660d3e13, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 546703575891773344, guid: 6283a318d09055c4f87992c5c47ea18f, type: 3} + Prefab: {fileID: 2347008446492047424, guid: 9cac250ebe8d420469bd4da3ab8cfd86, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 3287245990848439041, guid: 9d32d65f4d76dcb4ebd0debe3c504625, type: 3} + Prefab: {fileID: 4973514444862586119, guid: ff2924ffa397a8e44925625790831d25, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 1298522748923679250, guid: ff6c084700aabbc489c6c0e56506cf06, type: 3} + Prefab: {fileID: 5710477988932221578, guid: e8d09b814275ad745a427433c28dd53f, type: 3} + SourcePrefabToOverride: {fileID: 0} + SourceHashToOverride: 0 + OverridingTargetPrefab: {fileID: 0} + - Override: 0 + Prefab: {fileID: 8512676738329978770, guid: 3f7838db2c2fc424d9bd9a0d243b43be, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} diff --git a/Assets/NorthboundPrototype/Scenes/NorthboundGameplayPrototype.unity b/Assets/NorthboundPrototype/Scenes/NorthboundGameplayPrototype.unity index eebf80bc0ff4daeab5c2f0e9c8b806eaf8ebea67..65998d84f68754bb8337bcfe71eab89f34f939ea 100644 GIT binary patch literal 338464 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 AU;qFB literal 97344 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 diff --git a/Assets/NorthboundPrototype/Scripts/PortalSite.cs b/Assets/NorthboundPrototype/Scripts/PortalSite.cs index 18e2399..f29b51a 100644 --- a/Assets/NorthboundPrototype/Scripts/PortalSite.cs +++ b/Assets/NorthboundPrototype/Scripts/PortalSite.cs @@ -4,104 +4,114 @@ using UnityEngine; namespace Northbound.Prototype { - [RequireComponent(typeof(NetworkObject))] - public sealed class PortalSite : NetworkBehaviour, IPrototypeDamageable + [RequireComponent(typeof(NetworkObject), typeof(EnemyPortal), typeof(TeamGate))] + public sealed class PortalSite : NetworkBehaviour, IInteractable { public static readonly List All = new(); - [SerializeField] private int siteIndex; [SerializeField] private bool finalPortal; [SerializeField] private PortalState initialState = PortalState.Enemy; [SerializeField] private PortalSite southNeighbor; [SerializeField] private PortalSite northNeighbor; - [SerializeField] private float maxHealth = 260f; [SerializeField] private float rebuildCost = 60f; [SerializeField] private Renderer stateRenderer; + [SerializeField] private BoxCollider southEntry; + [SerializeField] private BoxCollider northEntry; + [SerializeField] private Transform southArrival; + [SerializeField] private Transform northArrival; public readonly NetworkVariable State = new(); - public readonly NetworkVariable Health = new(); - private readonly Dictionary teleportCooldown = new(); - + private EnemyPortal portal; + private TeamGate gate; public int SiteIndex => siteIndex; public bool IsFinal => finalPortal; - public bool IsAlive => State.Value != PortalState.Ruined && Health.Value > 0f; public Vector3 Position => transform.position; - private void OnEnable() => All.Add(this); + private void Awake() { portal = GetComponent(); gate = GetComponent(); } + private void OnEnable() { if (!All.Contains(this)) All.Add(this); } private void OnDisable() => All.Remove(this); public override void OnNetworkSpawn() { State.OnValueChanged += OnStateChanged; + portal.OnPortalDestroyed += OnDestroyed; if (IsServer) { State.Value = initialState; - Health.Value = initialState == PortalState.Ruined ? 0f : maxHealth; + if (initialState == PortalState.Ruined) portal.SetDormant(); + else portal.RestorePortal(initialState == PortalState.Allied ? TeamType.Player : TeamType.Hostile); } - RefreshVisual(); + RefreshVisualAndGate(); } - public override void OnNetworkDespawn() => State.OnValueChanged -= OnStateChanged; - private void OnStateChanged(PortalState previous, PortalState current) => RefreshVisual(); - - private void RefreshVisual() + public override void OnNetworkDespawn() { - if (stateRenderer == null) return; - stateRenderer.material.color = State.Value switch - { - PortalState.Enemy => new Color(0.8f, 0.1f, 0.65f), - PortalState.Allied => new Color(0.1f, 0.75f, 1f), - _ => new Color(0.25f, 0.25f, 0.28f) - }; + State.OnValueChanged -= OnStateChanged; + portal.OnPortalDestroyed -= OnDestroyed; } - public void TakeDamage(float amount, bool fromEnemy) + private void OnDestroyed(ulong attackerId) { - if (!IsServer || !IsAlive) return; - if (fromEnemy != (State.Value == PortalState.Allied)) return; - Health.Value = Mathf.Max(0f, Health.Value - amount); - if (Health.Value > 0f) return; - - if (State.Value == PortalState.Enemy && finalPortal) - PrototypeGameState.Instance.SetPhase(PrototypeGamePhase.Victory); + if (!IsServer) return; + bool won = State.Value == PortalState.Enemy && finalPortal; State.Value = PortalState.Ruined; + portal.SetDormant(); + if (won) PrototypeGameState.Instance.SetPhase(PrototypeGamePhase.Victory); + RefreshAllGates(); } - public static void TryInteractNearest(PrototypePlayer player) + private void OnStateChanged(PortalState previous, PortalState current) { RefreshVisualAndGate(); RefreshAllGates(); } + private static void RefreshAllGates() { foreach (var site in All) if (site != null) site.RefreshVisualAndGate(); } + + private void RefreshVisualAndGate() { - PortalSite nearest = null; - float best = 3.2f; - foreach (var portal in All) + if (stateRenderer != null) + stateRenderer.material.color = State.Value switch + { + PortalState.Enemy => new Color(0.8f, 0.1f, 0.65f), + PortalState.Allied => new Color(0.1f, 0.75f, 1f), + _ => new Color(0.25f, 0.25f, 0.28f) + }; + bool allied = State.Value == PortalState.Allied; + bool canSouth = allied && southNeighbor != null && southNeighbor.State.Value == PortalState.Allied; + bool canNorth = allied && northNeighbor != null && northNeighbor.State.Value == PortalState.Allied; + if (southEntry != null) southEntry.enabled = canNorth; + if (northEntry != null) northEntry.enabled = canSouth; + if (gate != null) { - float distance = Vector3.Distance(player.Position, portal.Position); - if (distance < best) { best = distance; nearest = portal; } + gate.enabled = canSouth || canNorth; + gate.frontTrigger = southEntry; gate.backTrigger = northEntry; + gate.frontExitPoint = canNorth ? northNeighbor.northArrival : northArrival; + gate.backExitPoint = canSouth ? southNeighbor.southArrival : southArrival; } - if (nearest == null || nearest.State.Value != PortalState.Ruined) return; - if (!PrototypeGameState.Instance.TrySpend(nearest.rebuildCost)) return; - nearest.State.Value = PortalState.Allied; - nearest.Health.Value = nearest.maxHealth; } - private void OnTriggerEnter(Collider other) + public bool CanInteract(ulong playerId) => State.Value == PortalState.Ruined && PrototypeGameState.Instance != null && + PrototypeGameState.Instance.SharedMana.Value >= rebuildCost; + public void Interact(ulong playerId) { if (CanInteract(playerId)) RebuildRpc(); } + [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] + private void RebuildRpc() { - if (!IsServer || State.Value != PortalState.Allied) return; - var player = other.GetComponentInParent(); - if (player == null || teleportCooldown.TryGetValue(player.OwnerClientId, out float until) && Time.time < until) return; - - Vector3 localVelocityDirection = player.LastMoveDirection.z >= 0f ? Vector3.forward : Vector3.back; - PortalSite target = localVelocityDirection.z > 0f ? northNeighbor : southNeighbor; - if (target == null || target.State.Value != PortalState.Allied) return; - - teleportCooldown[player.OwnerClientId] = Time.time + 1f; - target.teleportCooldown[player.OwnerClientId] = Time.time + 1f; - player.transform.position = target.transform.position + localVelocityDirection * 2.8f + Vector3.up * 0.8f; + if (State.Value != PortalState.Ruined || !PrototypeGameState.Instance.TrySpend(rebuildCost)) return; + portal.RestorePortal(TeamType.Player); + State.Value = PortalState.Allied; } + public string GetInteractionPrompt() => State.Value == PortalState.Ruined ? $"[E] 포탈 재건 ({rebuildCost:0} 마나)" : string.Empty; + public string GetInteractionAnimation() => string.Empty; + public EquipmentData GetEquipmentData() => null; + public Transform GetTransform() => transform; #if UNITY_EDITOR - public void EditorConfigure(int index, bool isFinal, PortalState state, PortalSite south, PortalSite north, Renderer renderer) + public void EditorConfigure(int index, bool isFinal, PortalState state, PortalSite south, PortalSite north, Renderer renderer, + BoxCollider southTrigger, BoxCollider northTrigger, Transform southExit, Transform northExit) { - siteIndex = index; finalPortal = isFinal; initialState = state; - southNeighbor = south; northNeighbor = north; stateRenderer = renderer; + siteIndex = index; finalPortal = isFinal; initialState = state; southNeighbor = south; northNeighbor = north; + stateRenderer = renderer; southEntry = southTrigger; northEntry = northTrigger; southArrival = southExit; northArrival = northExit; + portal = GetComponent(); gate = GetComponent(); + portal.ConfigureLifecycle(false, false); + gate.allowedTeam = TeamType.Player; gate.allowAllTeams = false; + gate.frontTrigger = southTrigger; gate.backTrigger = northTrigger; + gate.frontExitPoint = northExit; gate.backExitPoint = southExit; } public void EditorSetNeighbors(PortalSite south, PortalSite north) { southNeighbor = south; northNeighbor = north; } #endif diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs b/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs deleted file mode 100644 index 92a9718..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs +++ /dev/null @@ -1,19 +0,0 @@ -using UnityEngine; - -namespace Northbound.Prototype -{ - public sealed class PrototypeCameraRig : MonoBehaviour - { - [SerializeField] private float forwardOffset = 6f; - [SerializeField] private Vector2 zLimits = new(-68f, 75f); - private void LateUpdate() - { - PrototypePlayer local = null; - foreach (var player in PrototypePlayer.All) - if (player != null && player.IsOwner) { local = player; break; } - if (local == null) return; - float z = Mathf.Clamp(local.transform.position.z + forwardOffset, zLimits.x, zLimits.y); - transform.position = new Vector3(0f, transform.position.y, z - 0.01f); - } - } -} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs.meta deleted file mode 100644 index bf5ec01..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeCameraRig.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: aadf8f3e54a5c63428969e2d8151f4a6 \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs b/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs deleted file mode 100644 index 1c5471b..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Unity.Netcode; -using UnityEngine; - -namespace Northbound.Prototype -{ - [RequireComponent(typeof(NetworkObject))] - public sealed class PrototypeCore : NetworkBehaviour, IPrototypeDamageable - { - public static PrototypeCore Instance { get; private set; } - [SerializeField] private float maxHealth = 500f; - public readonly NetworkVariable Health = new(); - public bool IsAlive => Health.Value > 0f; - public Vector3 Position => transform.position; - private void Awake() => Instance = this; - public override void OnNetworkSpawn() { if (IsServer) Health.Value = maxHealth; } - public void TakeDamage(float amount, bool fromEnemy) - { - if (!IsServer || !fromEnemy || !IsAlive) return; - Health.Value = Mathf.Max(0f, Health.Value - amount); - if (Health.Value <= 0f) PrototypeGameState.Instance.SetPhase(PrototypeGamePhase.Defeat); - } - } -} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs.meta deleted file mode 100644 index 471970d..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeCore.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: b33daae417e65af48a958114a2390cf8 \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeCrystalOutpost.cs b/Assets/NorthboundPrototype/Scripts/PrototypeCrystalOutpost.cs index 4ddec04..3817b94 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeCrystalOutpost.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeCrystalOutpost.cs @@ -5,47 +5,64 @@ using UnityEngine; namespace Northbound.Prototype { [RequireComponent(typeof(NetworkObject))] - public sealed class PrototypeCrystalOutpost : NetworkBehaviour, IPrototypeDamageable + public sealed class PrototypeCrystalOutpost : NetworkBehaviour, IDamageable, ITeamMember, IHealthProvider, IInteractable { public static readonly List All = new(); - [SerializeField] private float maxHealth = 180f; + [SerializeField] private int maxHealth = 180; [SerializeField] private float manaPerSecond = 0.75f; [SerializeField] private Renderer stateRenderer; public readonly NetworkVariable IsCaptured = new(); - public readonly NetworkVariable Health = new(); + private readonly NetworkVariable health = new(); + private readonly NetworkVariable team = new(TeamType.Neutral); public float ManaPerSecond => manaPerSecond; - bool IPrototypeDamageable.IsAlive => IsAlive; - public bool IsAlive => IsCaptured.Value && Health.Value > 0f; + public bool IsAlive => IsCaptured.Value && health.Value > 0; public Vector3 Position => transform.position; + private void OnEnable() { if (!All.Contains(this)) All.Add(this); } private void OnDisable() => All.Remove(this); public override void OnNetworkSpawn() { - IsCaptured.OnValueChanged += (_, _) => Refresh(); - if (IsServer) { IsCaptured.Value = false; Health.Value = maxHealth; } + IsCaptured.OnValueChanged += OnCapturedChanged; + if (IsServer) { IsCaptured.Value = false; health.Value = maxHealth; team.Value = TeamType.Neutral; } Refresh(); } + public override void OnNetworkDespawn() => IsCaptured.OnValueChanged -= OnCapturedChanged; + private void OnCapturedChanged(bool previous, bool current) => Refresh(); private void Refresh() { if (stateRenderer != null) stateRenderer.material.color = IsCaptured.Value ? new Color(0.2f, 0.8f, 1f) : new Color(0.45f, 0.3f, 0.65f); } - public static void TryInteractNearest(PrototypePlayer player) + + public bool CanInteract(ulong playerId) { - PrototypeCrystalOutpost nearest = null; float best = 3f; - foreach (var crystal in All) - { - float distance = Vector3.Distance(player.Position, crystal.Position); - if (distance < best) { best = distance; nearest = crystal; } - } - if (nearest == null || nearest.IsCaptured.Value) return; - foreach (var enemy in PrototypeEnemy.All) - if (Vector3.Distance(enemy.Position, nearest.Position) < 6f) return; - nearest.IsCaptured.Value = true; - nearest.Health.Value = nearest.maxHealth; + if (IsCaptured.Value) return false; + foreach (var enemy in FindObjectsByType()) + if (!enemy.IsDead() && Vector3.Distance(enemy.transform.position, transform.position) < 6f) return false; + return true; } - public void TakeDamage(float amount, bool fromEnemy) + public void Interact(ulong playerId) { if (CanInteract(playerId)) CaptureRpc(); } + [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] + private void CaptureRpc() { - if (!IsServer || !fromEnemy || !IsAlive) return; - Health.Value = Mathf.Max(0f, Health.Value - amount); - if (Health.Value <= 0f) IsCaptured.Value = false; + if (IsCaptured.Value) return; + foreach (var enemy in FindObjectsByType()) + if (!enemy.IsDead() && Vector3.Distance(enemy.transform.position, transform.position) < 6f) return; + IsCaptured.Value = true; health.Value = maxHealth; team.Value = TeamType.Player; } + + public void TakeDamage(int damage, ulong attackerId) + { + if (!IsServer || !IsAlive) return; + health.Value = Mathf.Max(0, health.Value - damage); + if (health.Value <= 0) { IsCaptured.Value = false; team.Value = TeamType.Neutral; } + } + public bool IsDead() => !IsAlive; + public TeamType GetTeam() => team.Value; + public void SetTeam(TeamType value) { if (IsServer) team.Value = value; } + public int GetCurrentHealth() => health.Value; + public int GetMaxHealth() => maxHealth; + public float GetHealthPercentage() => maxHealth > 0 ? (float)health.Value / maxHealth : 0f; + public string GetInteractionPrompt() => IsCaptured.Value ? string.Empty : "[E] 크리스탈 거점 확보"; + public string GetInteractionAnimation() => string.Empty; + public EquipmentData GetEquipmentData() => null; + public Transform GetTransform() => transform; #if UNITY_EDITOR public void EditorConfigure(Renderer renderer) => stateRenderer = renderer; #endif diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeDefenseSlot.cs b/Assets/NorthboundPrototype/Scripts/PrototypeDefenseSlot.cs index 46c0a5d..554aa75 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeDefenseSlot.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeDefenseSlot.cs @@ -1,32 +1,37 @@ using System.Collections.Generic; +using Unity.Netcode; using UnityEngine; namespace Northbound.Prototype { - public sealed class PrototypeDefenseSlot : MonoBehaviour + [RequireComponent(typeof(NetworkObject))] + public sealed class PrototypeDefenseSlot : NetworkBehaviour, IInteractable { public static readonly List All = new(); [SerializeField] private PrototypeCrystalOutpost requiredOutpost; - [SerializeField] private PrototypeTower towerPrefab; + [SerializeField] private GameObject towerPrefab; [SerializeField] private float buildCost = 45f; - private PrototypeTower builtTower; + public readonly NetworkVariable IsBuilt = new(); private void OnEnable() { if (!All.Contains(this)) All.Add(this); } private void OnDisable() => All.Remove(this); - public static void TryInteractNearest(PrototypePlayer player) + public bool CanInteract(ulong playerId) => !IsBuilt.Value && requiredOutpost != null && requiredOutpost.IsCaptured.Value && + PrototypeGameState.Instance != null && PrototypeGameState.Instance.SharedMana.Value >= buildCost; + public void Interact(ulong playerId) { if (CanInteract(playerId)) BuildRpc(); } + [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] + private void BuildRpc() { - PrototypeDefenseSlot nearest = null; float best = 2.5f; - foreach (var slot in All) - { - float distance = Vector3.Distance(player.Position, slot.transform.position); - if (distance < best) { best = distance; nearest = slot; } - } - if (nearest == null || nearest.builtTower != null || nearest.requiredOutpost == null || !nearest.requiredOutpost.IsCaptured.Value) return; - if (!PrototypeGameState.Instance.TrySpend(nearest.buildCost)) return; - nearest.builtTower = Instantiate(nearest.towerPrefab, nearest.transform.position + Vector3.up * 0.7f, Quaternion.identity); - nearest.builtTower.NetworkObject.Spawn(); + if (IsBuilt.Value || requiredOutpost == null || !requiredOutpost.IsCaptured.Value || + !PrototypeGameState.Instance.TrySpend(buildCost)) return; + GameObject tower = Instantiate(towerPrefab, transform.position + Vector3.up * 0.7f, Quaternion.identity); + tower.GetComponent().Spawn(); + IsBuilt.Value = true; } + public string GetInteractionPrompt() => CanInteract(0) ? $"[E] 기본 타워 건설 ({buildCost:0} 마나)" : string.Empty; + public string GetInteractionAnimation() => string.Empty; + public EquipmentData GetEquipmentData() => null; + public Transform GetTransform() => transform; #if UNITY_EDITOR - public void EditorConfigure(PrototypeCrystalOutpost outpost, PrototypeTower prefab) { requiredOutpost = outpost; towerPrefab = prefab; } + public void EditorConfigure(PrototypeCrystalOutpost outpost, GameObject prefab) { requiredOutpost = outpost; towerPrefab = prefab; } #endif } } diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs b/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs deleted file mode 100644 index 4d742e1..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections.Generic; -using Unity.Netcode; -using UnityEngine; - -namespace Northbound.Prototype -{ - [RequireComponent(typeof(NetworkObject))] - public sealed class PrototypeEnemy : NetworkBehaviour, IPrototypeDamageable - { - public static readonly List All = new(); - - [SerializeField] private EnemyRole role; - [SerializeField] private float baseHealth = 55f; - [SerializeField] private float baseDamage = 8f; - [SerializeField] private float moveSpeed = 2.4f; - [SerializeField] private float attackRange = 1.7f; - [SerializeField] private float attackInterval = 1.2f; - - public readonly NetworkVariable Health = new(); - private float damage; - private float nextAttack; - private float pendingHealthMultiplier = 1f; - private float pendingDamageMultiplier = 1f; - - public bool IsAlive => Health.Value > 0f; - public Vector3 Position => transform.position; - - private void OnEnable() => All.Add(this); - private void OnDisable() => All.Remove(this); - - public void ApplyWaveStats(float healthMultiplier, float damageMultiplier) - { - pendingHealthMultiplier = healthMultiplier; - pendingDamageMultiplier = damageMultiplier; - } - - public override void OnNetworkSpawn() - { - if (IsServer && Health.Value <= 0f) Health.Value = baseHealth * pendingHealthMultiplier; - if (IsServer && damage <= 0f) damage = baseDamage * pendingDamageMultiplier; - } - - private void Update() - { - if (!IsServer || !IsAlive || PrototypeGameState.Instance.Phase.Value != PrototypeGamePhase.Playing) return; - IPrototypeDamageable target = SelectTarget(); - if (target == null || !target.IsAlive) return; - Vector3 direction = target.Position - transform.position; - direction.y = 0f; - if (direction.magnitude > attackRange) - { - transform.position += direction.normalized * moveSpeed * Time.deltaTime; - transform.forward = direction.normalized; - } - else if (Time.time >= nextAttack) - { - nextAttack = Time.time + attackInterval; - target.TakeDamage(damage, true); - } - } - - private IPrototypeDamageable SelectTarget() - { - IPrototypeDamageable target = PrototypeCore.Instance; - float best = target != null ? Vector3.Distance(Position, target.Position) : float.MaxValue; - - foreach (var player in PrototypePlayer.All) - { - if (!player.IsAlive) continue; - float distance = Vector3.Distance(Position, player.Position); - if (distance < 7f && distance < best) { best = distance; target = player; } - } - - if (role == EnemyRole.Raider) - { - foreach (var crystal in PrototypeCrystalOutpost.All) - { - if (!crystal.IsCaptured.Value || !crystal.IsAlive) continue; - float distance = Vector3.Distance(Position, crystal.Position); - if (distance < best) { best = distance; target = crystal; } - } - } - - foreach (var portal in PortalSite.All) - { - if (portal.State.Value != PortalState.Allied || !portal.IsAlive) continue; - float distance = Vector3.Distance(Position, portal.Position); - if (distance < 5f && distance < best) { best = distance; target = portal; } - } - return target; - } - - public void TakeDamage(float amount, bool fromEnemy) - { - if (!IsServer || fromEnemy || !IsAlive) return; - Health.Value = Mathf.Max(0f, Health.Value - amount); - if (Health.Value <= 0f) NetworkObject.Despawn(true); - } - -#if UNITY_EDITOR - public void EditorConfigure(EnemyRole enemyRole, float health, float attack, float speed) - { role = enemyRole; baseHealth = health; baseDamage = attack; moveSpeed = speed; } -#endif - } -} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs.meta deleted file mode 100644 index b0371ca..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeEnemy.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 9a43da78fc3aae144a68b43728a90ca5 \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeGameState.cs b/Assets/NorthboundPrototype/Scripts/PrototypeGameState.cs index 3b0c62d..27f217a 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeGameState.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeGameState.cs @@ -29,6 +29,12 @@ namespace Northbound.Prototype private void Update() { if (!IsServer || Phase.Value != PrototypeGamePhase.Playing) return; + var core = FindAnyObjectByType(); + if (core != null && core.IsDead()) + { + SetPhase(PrototypeGamePhase.Defeat); + return; + } float income = baseManaPerSecond; foreach (var crystal in PrototypeCrystalOutpost.All) if (crystal != null && crystal.IsCaptured.Value) income += crystal.ManaPerSecond; diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeHud.cs b/Assets/NorthboundPrototype/Scripts/PrototypeHud.cs index cb5158d..a2ea995 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeHud.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeHud.cs @@ -1,5 +1,4 @@ using UnityEngine; -using UnityEngine.InputSystem; namespace Northbound.Prototype { @@ -7,12 +6,6 @@ namespace Northbound.Prototype { [SerializeField] private PrototypeNetworkLauncher launcher; [SerializeField] private PrototypeWaveManager waveManager; - private void Update() - { - if (Keyboard.current == null || !Keyboard.current.eKey.wasPressedThisFrame) return; - foreach (var player in PrototypePlayer.All) - if (player != null && player.IsOwner) { player.InteractRpc(); break; } - } private void OnGUI() { GUI.skin.label.fontSize = 17; GUI.skin.button.fontSize = 17; @@ -30,7 +23,8 @@ namespace Northbound.Prototype GUI.Box(new Rect(18, 18, 390, 142), "작전 현황"); string wave = waveManager == null ? "-" : $"{waveManager.WaveNumber.Value} (다음 {waveManager.NextWaveIn.Value:0}초)"; string resonance = waveManager == null ? "-" : waveManager.ResonanceSnapshot.Value.ToString(); - string health = PrototypeCore.Instance == null ? "-" : PrototypeCore.Instance.Health.Value.ToString("0"); + var core = FindAnyObjectByType(); + string health = core == null ? "-" : core.CurrentHealth.ToString(); GUI.Label(new Rect(35, 52, 350, 105), $"공용 마나 {state.SharedMana.Value:0}\n본진 체력 {health}\n웨이브 {wave}\n포탈 공명 {resonance} / 3"); GUI.Box(new Rect(Screen.width - 370, 18, 350, 155), "목표와 조작"); GUI.Label(new Rect(Screen.width - 350, 52, 320, 110), "북진해 적 포탈을 파괴하고 E로 재건\n크리스탈 주변 적 제거 후 E로 확보\n고정 슬롯에서 E로 기본 타워 건설\n좌/우클릭 공격 · 회피/방어 없음"); diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeNetworkLauncher.cs b/Assets/NorthboundPrototype/Scripts/PrototypeNetworkLauncher.cs index 35d48b1..be3aa7e 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeNetworkLauncher.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeNetworkLauncher.cs @@ -25,6 +25,9 @@ namespace Northbound.Prototype { foreach (string argument in System.Environment.GetCommandLineArgs()) if (argument == "-prototypeSmoke") { StartHost(); break; } +#if UNITY_EDITOR + if (UnityEditor.SessionState.GetBool("Northbound.Prototype.InteractiveSmoke", false)) StartHost(); +#endif } public void StartHost() { if (!manager.IsListening) manager.StartHost(); } public void StartClient() { if (!manager.IsListening) manager.StartClient(); } diff --git a/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs b/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs deleted file mode 100644 index 6f723ca..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System.Collections.Generic; -using Unity.Netcode; -using UnityEngine; -using UnityEngine.InputSystem; - -namespace Northbound.Prototype -{ - [RequireComponent(typeof(NetworkObject))] - public sealed class PrototypePlayer : NetworkBehaviour, IPrototypeDamageable - { - public static readonly List All = new(); - - [Header("Movement")] - [SerializeField] private float moveSpeed = 8f; - [SerializeField] private Vector2 xBounds = new(-15f, 15f); - [SerializeField] private Vector2 zBounds = new(-82f, 88f); - [Header("Combat")] - [SerializeField] private float maxHealth = 100f; - [SerializeField] private float normalDamage = 24f; - [SerializeField] private float normalRange = 3.2f; - [SerializeField] private float specialDamage = 58f; - [SerializeField] private float specialRange = 6f; - [SerializeField] private float specialManaCost = 25f; - [SerializeField] private float specialCooldown = 4f; - - public readonly NetworkVariable Health = new(); - private float nextSpecialTime; - private float nextNormalTime; - private Camera mainCamera; - public Vector3 LastMoveDirection { get; private set; } = Vector3.forward; - - public bool IsAlive => Health.Value > 0f; - public Vector3 Position => transform.position; - - private void OnEnable() => All.Add(this); - private void OnDisable() => All.Remove(this); - - public override void OnNetworkSpawn() - { - if (IsServer) - { - Health.Value = maxHealth; - transform.position = new Vector3((OwnerClientId % 4 - 1.5f) * 2f, 0.8f, -74f); - } - if (IsOwner) mainCamera = Camera.main; - } - - private void Update() - { - if (!IsOwner || !IsSpawned || !IsAlive || PrototypeGameState.Instance == null || - PrototypeGameState.Instance.Phase.Value != PrototypeGamePhase.Playing) return; - - var keyboard = Keyboard.current; - var mouse = Mouse.current; - if (keyboard == null || mouse == null) return; - var movement = new Vector2( - (keyboard.dKey.isPressed ? 1f : 0f) - (keyboard.aKey.isPressed ? 1f : 0f), - (keyboard.wKey.isPressed ? 1f : 0f) - (keyboard.sKey.isPressed ? 1f : 0f)); - Vector3 aim = transform.forward; - if (mainCamera == null) mainCamera = Camera.main; - if (mainCamera != null) - { - Ray ray = mainCamera.ScreenPointToRay(mouse.position.ReadValue()); - var plane = new Plane(Vector3.up, Vector3.zero); - if (plane.Raycast(ray, out float distance)) aim = ray.GetPoint(distance) - transform.position; - } - aim.y = 0f; - if (aim.sqrMagnitude < 0.01f) aim = Vector3.forward; - - bool normal = mouse.leftButton.wasPressedThisFrame; - bool special = mouse.rightButton.wasPressedThisFrame; - SubmitInputRpc(movement, aim.normalized, normal, special); - } - - [Rpc(SendTo.Server)] - private void SubmitInputRpc(Vector2 movement, Vector3 aim, bool normal, bool special) - { - if (!IsAlive) return; - Vector3 delta = new Vector3(movement.x, 0f, movement.y); - if (delta.sqrMagnitude > 1f) delta.Normalize(); - if (delta.sqrMagnitude > 0.01f) LastMoveDirection = delta.normalized; - transform.position += delta * moveSpeed * Time.deltaTime; - transform.position = new Vector3( - Mathf.Clamp(transform.position.x, xBounds.x, xBounds.y), 0.8f, - Mathf.Clamp(transform.position.z, zBounds.x, zBounds.y)); - transform.forward = aim; - - if (normal && Time.time >= nextNormalTime) - { - nextNormalTime = Time.time + 0.35f; - PerformAttack(normalRange, normalDamage, 0.35f); - } - if (special && Time.time >= nextSpecialTime && PrototypeGameState.Instance.TrySpend(specialManaCost)) - { - nextSpecialTime = Time.time + specialCooldown; - PerformAttack(specialRange, specialDamage, 0.1f); - } - } - - private void PerformAttack(float range, float damage, float facingThreshold) - { - var hits = Physics.OverlapSphere(transform.position + transform.forward * range * 0.5f, range * 0.65f); - var damaged = new HashSet(); - foreach (var hit in hits) - { - var target = hit.GetComponentInParent(); - if (target == null || ReferenceEquals(target, this) || !target.IsAlive || damaged.Contains(target)) continue; - Vector3 direction = (target.Position - transform.position).normalized; - if (Vector3.Dot(transform.forward, direction) < facingThreshold) continue; - target.TakeDamage(damage, false); - damaged.Add(target); - } - } - - public void TakeDamage(float amount, bool fromEnemy) - { - if (!IsServer || !fromEnemy || !IsAlive) return; - Health.Value = Mathf.Max(0f, Health.Value - amount); - if (Health.Value <= 0f) - { - Health.Value = maxHealth; - transform.position = new Vector3(0f, 0.8f, -74f); - } - } - - [Rpc(SendTo.Server)] - public void InteractRpc() - { - if (!IsAlive) return; - PortalSite.TryInteractNearest(this); - PrototypeCrystalOutpost.TryInteractNearest(this); - PrototypeDefenseSlot.TryInteractNearest(this); - } - } -} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs.meta deleted file mode 100644 index 7bb27d8..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypePlayer.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 47e38d0512a8abd4c83eda8608e3ef9f \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeSmokeRunner.cs b/Assets/NorthboundPrototype/Scripts/PrototypeSmokeRunner.cs index 3463f3b..cb307e0 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeSmokeRunner.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeSmokeRunner.cs @@ -5,43 +5,58 @@ namespace Northbound.Prototype { public sealed class PrototypeSmokeRunner : MonoBehaviour { - private bool enabledForCommandLine; + private bool smokeEnabled; private float startedAt; private void Start() { foreach (string argument in System.Environment.GetCommandLineArgs()) - if (argument == "-prototypeSmoke") enabledForCommandLine = true; + if (argument == "-prototypeSmoke") smokeEnabled = true; +#if UNITY_EDITOR + smokeEnabled |= UnityEditor.SessionState.GetBool("Northbound.Prototype.InteractiveSmoke", false); +#endif startedAt = Time.realtimeSinceStartup; } private void Update() { - if (!enabledForCommandLine || Time.realtimeSinceStartup - startedAt < 18f) return; + if (!smokeEnabled || Time.realtimeSinceStartup - startedAt < 18f) return; bool valid = NetworkManager.Singleton != null && NetworkManager.Singleton.IsHost && - PrototypeGameState.Instance != null && PrototypeCore.Instance != null && - PrototypePlayer.All.Count == 1 && PortalSite.All.Count == 4 && - PrototypeCrystalOutpost.All.Count == 3 && PrototypeEnemy.All.Count > 0 && - FindFirstObjectByType().WaveNumber.Value == 1; + PrototypeGameState.Instance != null && FindAnyObjectByType() != null && + FindObjectsByType().Length == 1 && PortalSite.All.Count == 4 && + PrototypeCrystalOutpost.All.Count == 3 && FindObjectsByType().Length > 0 && + FindAnyObjectByType().WaveNumber.Value == 1; if (valid) { - Debug.Log($"[Northbound Prototype Smoke] PASS: host, player, core, 4 portals, 3 crystals, and wave enemies ({PrototypeEnemy.All.Count}) are active."); + int enemyCount = FindObjectsByType().Length; + Debug.Log($"[Northbound Prototype Smoke] PASS: reused player/core, 4 portals, 3 crystals, and reused wave enemies ({enemyCount}) are active."); Quit(0); } else { - Debug.LogError($"[Northbound Prototype Smoke] FAIL: host={NetworkManager.Singleton?.IsHost}, players={PrototypePlayer.All.Count}, portals={PortalSite.All.Count}, crystals={PrototypeCrystalOutpost.All.Count}"); - foreach (var crystal in FindObjectsByType(FindObjectsSortMode.None)) + int playerCount = FindObjectsByType().Length; + Debug.LogError($"[Northbound Prototype Smoke] FAIL: host={NetworkManager.Singleton?.IsHost}, players={playerCount}, portals={PortalSite.All.Count}, crystals={PrototypeCrystalOutpost.All.Count}"); + foreach (var crystal in FindObjectsByType()) Debug.LogError($"[Northbound Prototype Smoke] Crystal object: {crystal.name}, active={crystal.isActiveAndEnabled}, spawned={crystal.IsSpawned}"); Quit(2); } - enabledForCommandLine = false; + smokeEnabled = false; } private static void Quit(int code) { #if UNITY_EDITOR - UnityEditor.EditorApplication.Exit(code); + if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsListening) + NetworkManager.Singleton.Shutdown(); + if (UnityEditor.SessionState.GetBool("Northbound.Prototype.InteractiveSmoke", false)) + { + UnityEditor.SessionState.EraseBool("Northbound.Prototype.InteractiveSmoke"); + UnityEditor.EditorApplication.isPlaying = false; + } + else + { + UnityEditor.EditorApplication.Exit(code); + } #else Application.Quit(code); #endif diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs b/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs new file mode 100644 index 0000000..fed2797 --- /dev/null +++ b/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using Unity.Netcode; +using UnityEngine; + +namespace Northbound.Prototype +{ + [RequireComponent(typeof(NetworkObject), typeof(NetworkPlayerController))] + public sealed class PrototypeSpecialAttack : NetworkBehaviour, IAction + { + [SerializeField] private float cooldown = 4f; + [SerializeField] private float manaCost = 25f; + [SerializeField] private float range = 6f; + [SerializeField] private float radius = 3.5f; + [SerializeField] private int damageMultiplier = 3; + [SerializeField, Range(-1f, 1f)] private float minimumFacingDot = 0.05f; + private float localNextUse; + private float serverNextUse; + private PlayerStats stats; + private ITeamMember teamMember; + + private void Awake() { stats = GetComponent(); teamMember = GetComponent(); } + public bool CanExecute(ulong playerId) => Time.time >= localNextUse && PrototypeGameState.Instance != null && + PrototypeGameState.Instance.SharedMana.Value >= manaCost; + public void Execute(ulong playerId) + { + if (!CanExecute(playerId)) return; + localNextUse = Time.time + cooldown; + ExecuteSpecialRpc(); + } + [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] + private void ExecuteSpecialRpc() + { + if (Time.time < serverNextUse || PrototypeGameState.Instance == null || !PrototypeGameState.Instance.TrySpend(manaCost)) return; + serverNextUse = Time.time + cooldown; + int damage = (stats != null ? stats.GetDamage() : 10) * damageMultiplier; + Vector3 center = transform.position + transform.forward * range * 0.5f; + var damaged = new HashSet(); + foreach (var hit in Physics.OverlapSphere(center, radius)) + { + if (hit.transform.root == transform.root) continue; + var target = hit.GetComponentInParent(); + if (target == null || target.IsDead() || damaged.Contains(target)) continue; + var targetTeam = hit.GetComponentInParent(); + if (teamMember != null && targetTeam != null && !TeamManager.CanAttack(teamMember, targetTeam)) continue; + Vector3 direction = hit.bounds.center - transform.position; direction.y = 0f; + if (direction.sqrMagnitude > 0.01f && Vector3.Dot(transform.forward, direction.normalized) < minimumFacingDot) continue; + target.TakeDamage(damage, NetworkObjectId); + damaged.Add(target); + } + } + public string GetActionName() => "SpecialAttack"; + public string GetActionAnimation() => string.Empty; + public EquipmentData GetEquipmentData() => null; + } +} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs.meta new file mode 100644 index 0000000..3569c67 --- /dev/null +++ b/Assets/NorthboundPrototype/Scripts/PrototypeSpecialAttack.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c645a5457e4901d4199afde290b51961 \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs b/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs deleted file mode 100644 index 8bc4d9b..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Unity.Netcode; -using UnityEngine; - -namespace Northbound.Prototype -{ - [RequireComponent(typeof(NetworkObject))] - public sealed class PrototypeTower : NetworkBehaviour - { - [SerializeField] private float range = 7f; - [SerializeField] private float damage = 10f; - [SerializeField] private float interval = 1.1f; - private float nextAttack; - private void Update() - { - if (!IsServer || Time.time < nextAttack) return; - PrototypeEnemy nearest = null; float best = range; - foreach (var enemy in PrototypeEnemy.All) - { - float distance = Vector3.Distance(transform.position, enemy.Position); - if (enemy.IsAlive && distance < best) { best = distance; nearest = enemy; } - } - if (nearest == null) return; - nextAttack = Time.time + interval; - nearest.TakeDamage(damage, false); - } - } -} diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs.meta b/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs.meta deleted file mode 100644 index e903340..0000000 --- a/Assets/NorthboundPrototype/Scripts/PrototypeTower.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 4f17758c8b6cecf4d8246570583e22dd \ No newline at end of file diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeTypes.cs b/Assets/NorthboundPrototype/Scripts/PrototypeTypes.cs index f63d8c9..422cd89 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeTypes.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeTypes.cs @@ -1,15 +1,6 @@ -using UnityEngine; - namespace Northbound.Prototype { public enum PrototypeGamePhase : byte { Playing, Victory, Defeat } public enum PortalState : byte { Enemy, Ruined, Allied } public enum EnemyRole : byte { Grunt, Raider, Digger, Elite } - - public interface IPrototypeDamageable - { - bool IsAlive { get; } - Vector3 Position { get; } - void TakeDamage(float amount, bool fromEnemy); - } } diff --git a/Assets/NorthboundPrototype/Scripts/PrototypeWaveManager.cs b/Assets/NorthboundPrototype/Scripts/PrototypeWaveManager.cs index 7db9656..09e0d49 100644 --- a/Assets/NorthboundPrototype/Scripts/PrototypeWaveManager.cs +++ b/Assets/NorthboundPrototype/Scripts/PrototypeWaveManager.cs @@ -1,4 +1,3 @@ -using System.Collections; using System.Collections.Generic; using Unity.Netcode; using UnityEngine; @@ -8,74 +7,81 @@ namespace Northbound.Prototype [RequireComponent(typeof(NetworkObject))] public sealed class PrototypeWaveManager : NetworkBehaviour { - [SerializeField] private PrototypeEnemy[] enemyPrefabs; - [SerializeField] private float firstWaveDelay = 15f; - [SerializeField] private float waveInterval = 90f; + [SerializeField] private GlobalTimer globalTimer; + [SerializeField] private GameObject[] enemyPrefabs; [SerializeField] private int resonanceCap = 3; [SerializeField] private float healthPerPortal = 0.10f; [SerializeField] private float damagePerPortal = 0.06f; - public readonly NetworkVariable WaveNumber = new(); public readonly NetworkVariable ResonanceSnapshot = new(); public readonly NetworkVariable NextWaveIn = new(); public override void OnNetworkSpawn() { - if (IsServer) StartCoroutine(WaveLoop()); + if (globalTimer == null) globalTimer = GlobalTimer.Instance; + if (IsServer && globalTimer != null) globalTimer.OnCycleComplete += SpawnWave; } - - private IEnumerator WaveLoop() + public override void OnNetworkDespawn() { - float delay = firstWaveDelay; - while (PrototypeGameState.Instance.Phase.Value == PrototypeGamePhase.Playing) - { - for (float left = delay; left > 0f; left -= 1f) - { - NextWaveIn.Value = left; - yield return new WaitForSeconds(1f); - } - SpawnWave(); - delay = waveInterval; - } + if (IsServer && globalTimer != null) globalTimer.OnCycleComplete -= SpawnWave; } + private void Update() { if (IsServer && globalTimer != null) NextWaveIn.Value = globalTimer.GetCurrentTime(); } private void SpawnWave() { + if (!IsServer || PrototypeGameState.Instance.Phase.Value != PrototypeGamePhase.Playing) return; var activePortals = new List(); - foreach (var portal in PortalSite.All) - if (portal != null && portal.State.Value == PortalState.Enemy) activePortals.Add(portal); - + foreach (var portal in PortalSite.All) if (portal != null && portal.State.Value == PortalState.Enemy) activePortals.Add(portal); if (activePortals.Count == 0) return; WaveNumber.Value++; ResonanceSnapshot.Value = Mathf.Min(activePortals.Count, resonanceCap); - int budget = 5 + WaveNumber.Value * 2; - float hpMultiplier = 1f + ResonanceSnapshot.Value * healthPerPortal; - float damageMultiplier = 1f + ResonanceSnapshot.Value * damagePerPortal; - - for (int i = 0; i < budget; i++) + int remainingBudget = 18 + WaveNumber.Value * 3; + int spawnIndex = 0; + while (remainingBudget > 0) { - PortalSite portal = activePortals[i % activePortals.Count]; - int prefabIndex = ChooseEnemyIndex(i, WaveNumber.Value); - var prefab = enemyPrefabs[Mathf.Clamp(prefabIndex, 0, enemyPrefabs.Length - 1)]; - float xOffset = prefabIndex == 2 ? (i % 2 == 0 ? -11f : 11f) : Random.Range(-2f, 2f); - float zOffset = prefabIndex == 2 ? -7f : -2.5f; - var enemy = Instantiate(prefab, portal.Position + new Vector3(xOffset, 0.7f, zOffset), Quaternion.identity); - enemy.ApplyWaveStats(hpMultiplier, damageMultiplier); - enemy.NetworkObject.Spawn(); + GameObject prefab = SelectAffordablePrefab(remainingBudget); + if (prefab == null) break; + var data = prefab.GetComponent()?.monsterData; + int cost = data != null ? Mathf.Max(1, data.cost) : 3; + PortalSite portal = activePortals[spawnIndex % activePortals.Count]; + float x = spawnIndex % 5 == 4 ? (spawnIndex % 2 == 0 ? -11f : 11f) : Random.Range(-2f, 2f); + GameObject enemy = Instantiate(prefab, portal.Position + new Vector3(x, 0.3f, -3f), Quaternion.identity); + ApplyResonance(enemy); + enemy.GetComponent().Spawn(); + remainingBudget -= cost; spawnIndex++; } } - private int ChooseEnemyIndex(int spawnIndex, int wave) + private GameObject SelectAffordablePrefab(int budget) { - if (enemyPrefabs.Length <= 1) return 0; - if (wave >= 3 && spawnIndex % 7 == 0) return Mathf.Min(3, enemyPrefabs.Length - 1); - if (spawnIndex % 5 == 0) return Mathf.Min(1, enemyPrefabs.Length - 1); - if (wave >= 2 && spawnIndex % 4 == 0) return Mathf.Min(2, enemyPrefabs.Length - 1); - return 0; + var eligible = new List(); float totalWeight = 0f; + foreach (var prefab in enemyPrefabs) + { + if (prefab == null) continue; + var data = prefab.GetComponent()?.monsterData; + if (data == null || data.cost > budget || WaveNumber.Value < data.waveMin || (data.waveMax > 0 && WaveNumber.Value > data.waveMax)) continue; + eligible.Add(prefab); totalWeight += Mathf.Max(0.01f, data.weight); + } + if (eligible.Count == 0) return null; + float roll = Random.Range(0f, totalWeight); + foreach (var prefab in eligible) + { + roll -= Mathf.Max(0.01f, prefab.GetComponent().monsterData.weight); + if (roll <= 0f) return prefab; + } + return eligible[0]; } + private void ApplyResonance(GameObject enemy) + { + int resonance = ResonanceSnapshot.Value; + var unit = enemy.GetComponent(); + var ai = enemy.GetComponent(); + if (unit != null) unit.maxHealth = Mathf.RoundToInt(unit.maxHealth * (1f + resonance * healthPerPortal)); + if (ai != null) ai.attackDamage = Mathf.RoundToInt(ai.attackDamage * (1f + resonance * damagePerPortal)); + } #if UNITY_EDITOR - public void EditorConfigure(PrototypeEnemy[] prefabs) => enemyPrefabs = prefabs; + public void EditorConfigure(GlobalTimer timer, GameObject[] prefabs) { globalTimer = timer; enemyPrefabs = prefabs; } #endif } } diff --git a/Assets/Scripts/AttackAction.cs b/Assets/Scripts/AttackAction.cs index 15ce99d..a59ac5f 100644 --- a/Assets/Scripts/AttackAction.cs +++ b/Assets/Scripts/AttackAction.cs @@ -11,6 +11,8 @@ namespace Northbound [Header("Attack Settings")] public float attackCooldown = 0.5f; public LayerMask attackableLayer = ~0; + public bool useFacingArc = false; + [Range(-1f, 1f)] public float minimumFacingDot = 0.25f; [Header("Animation")] public string attackAnimationTrigger = "Attack"; @@ -72,7 +74,7 @@ namespace Northbound PlayAttackAnimation(); // 애니메이션이 없으면 즉시 공격 실행 - if (_animator == null || string.IsNullOrEmpty(attackAnimationTrigger)) + if (!useAnimationEvents || _animator == null || string.IsNullOrEmpty(attackAnimationTrigger)) { PerformAttack(); _isAttacking = false; @@ -89,6 +91,14 @@ namespace Northbound if (hit.transform.root == transform.root) continue; + if (useFacingArc) + { + Vector3 targetDirection = hit.bounds.center - transform.position; + targetDirection.y = 0f; + if (targetDirection.sqrMagnitude > 0.01f && Vector3.Dot(transform.forward, targetDirection.normalized) < minimumFacingDot) + continue; + } + var targetDamageable = hit.GetComponent(); var targetTeamMember = hit.GetComponent(); diff --git a/Assets/Scripts/EnemyPortal.cs b/Assets/Scripts/EnemyPortal.cs index 876f064..a416d04 100644 --- a/Assets/Scripts/EnemyPortal.cs +++ b/Assets/Scripts/EnemyPortal.cs @@ -9,6 +9,10 @@ using UnityEngine; [Header("Team Settings")] [Tooltip("포털의 팀 (Hostile 또는 Monster)")] [SerializeField] private TeamType portalTeam = TeamType.Hostile; + [Header("Lifecycle")] + [SerializeField] private bool spawnFromGlobalTimer = true; + [SerializeField] private bool despawnWhenDestroyed = true; + public event System.Action OnPortalDestroyed; [Header("Health Settings")] [Tooltip("최대 체력")] @@ -67,12 +71,18 @@ using UnityEngine; } } - GlobalTimer.Instance.OnCycleStart += OnCycleStart; + if (spawnFromGlobalTimer && GlobalTimer.Instance != null) + { + GlobalTimer.Instance.OnCycleStart += OnCycleStart; + } } public override void OnNetworkDespawn() { - GlobalTimer.Instance.OnCycleStart -= OnCycleStart; + if (spawnFromGlobalTimer && GlobalTimer.Instance != null) + { + GlobalTimer.Instance.OnCycleStart -= OnCycleStart; + } // 체력 변경 이벤트 정리 (나중에 추가할 경우 대비) @@ -249,7 +259,7 @@ using UnityEngine; } } - private void DestroyPortal(ulong attackerId) + private void DestroyPortal(ulong attackerId) { if (!IsServer) return; @@ -257,10 +267,40 @@ using UnityEngine; ShowDestroyEffectClientRpc(); // 몬스터 스폰 중지 (이벤트 구독 해제) - GlobalTimer.Instance.OnCycleStart -= OnCycleStart; + if (spawnFromGlobalTimer && GlobalTimer.Instance != null) + { + GlobalTimer.Instance.OnCycleStart -= OnCycleStart; + } - // 네트워크 오브젝트 파괴 (약간의 딜레이) - Invoke(nameof(DespawnPortal), 1.0f); + OnPortalDestroyed?.Invoke(attackerId); + + if (despawnWhenDestroyed) + { + Invoke(nameof(DespawnPortal), 1.0f); + } + } + + public int CurrentHealth => _currentHealth.Value; + public int MaxHealth => maxHealth; + + public void ConfigureLifecycle(bool useGlobalTimerSpawning, bool shouldDespawn) + { + spawnFromGlobalTimer = useGlobalTimerSpawning; + despawnWhenDestroyed = shouldDespawn; + } + + public void RestorePortal(TeamType team) + { + if (!IsServer) return; + _team.Value = team; + _currentHealth.Value = maxHealth; + } + + public void SetDormant() + { + if (!IsServer) return; + _team.Value = TeamType.Neutral; + _currentHealth.Value = 0; } private void DespawnPortal() diff --git a/Assets/Scripts/NetworkConnectionHandler.cs b/Assets/Scripts/NetworkConnectionHandler.cs index 2fdeb16..5d6e0c4 100644 --- a/Assets/Scripts/NetworkConnectionHandler.cs +++ b/Assets/Scripts/NetworkConnectionHandler.cs @@ -17,6 +17,8 @@ namespace Northbound private Dictionary _clientSpawnIndices = new Dictionary(); private int _nextSpawnIndex = 0; + private NetworkManager _networkManager; + private bool _callbacksRegistered; // ⭐ Awake에서 스폰 포인트 먼저 찾고, 콜백 등록 private void Awake() @@ -28,15 +30,25 @@ namespace Northbound } // 2️⃣ 그 다음 콜백 등록 - if (NetworkManager.Singleton != null) - { - NetworkManager.Singleton.ConnectionApprovalCallback = ApprovalCheck; - NetworkManager.Singleton.OnServerStarted += OnServerStarted; - NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected; - } - else - { - } + RegisterCallbacks(); + } + + private void Start() + { + RegisterCallbacks(); + } + + private void RegisterCallbacks() + { + if (_callbacksRegistered) return; + _networkManager = GetComponent(); + if (_networkManager == null) _networkManager = NetworkManager.Singleton; + if (_networkManager == null) return; + + _networkManager.ConnectionApprovalCallback = ApprovalCheck; + _networkManager.OnServerStarted += OnServerStarted; + _networkManager.OnClientConnectedCallback += OnClientConnected; + _callbacksRegistered = true; } private void FindSpawnPoints() @@ -192,11 +204,11 @@ namespace Northbound private void OnDestroy() { - if (NetworkManager.Singleton != null) + if (_callbacksRegistered && _networkManager != null) { - NetworkManager.Singleton.ConnectionApprovalCallback = null; - NetworkManager.Singleton.OnServerStarted -= OnServerStarted; - NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected; + _networkManager.ConnectionApprovalCallback = null; + _networkManager.OnServerStarted -= OnServerStarted; + _networkManager.OnClientConnectedCallback -= OnClientConnected; } } } diff --git a/Assets/Scripts/NetworkPlayerController.cs b/Assets/Scripts/NetworkPlayerController.cs index d2163be..e6430c9 100644 --- a/Assets/Scripts/NetworkPlayerController.cs +++ b/Assets/Scripts/NetworkPlayerController.cs @@ -10,6 +10,8 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl { [Header("Movement Settings")] public float rotationSpeed = 10f; + [Tooltip("공격 애니메이션 중 이동을 막을지 여부")] + public bool blockMovementDuringAttack = true; [Header("Team Settings")] [SerializeField] private TeamType initialTeam = TeamType.Player; @@ -21,6 +23,7 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl [Header("Death Settings")] [SerializeField] private GameObject resourcePickupPrefab; // 자원 드랍 프리팹 [SerializeField] private float respawnDelay = 10f; // 부활 대기 시간 (초) + [SerializeField] private bool dropResourcesOnDeath = true; [Header("Health Bar")] [SerializeField] private bool showHealthBar = true; @@ -61,9 +64,18 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl // 이 플레이어가 로컬 플레이어인지 확인 - public new bool IsLocalPlayer => _ownerPlayerId.Value == NetworkManager.Singleton.LocalClientId; + public new bool IsLocalPlayer => NetworkManager.Singleton != null && + (_ownerPlayerId.Value == ulong.MaxValue ? OwnerClientId : _ownerPlayerId.Value) == NetworkManager.Singleton.LocalClientId; - public ulong OwnerPlayerId => _ownerPlayerId.Value; + public ulong OwnerPlayerId => _ownerPlayerId.Value == ulong.MaxValue ? OwnerClientId : _ownerPlayerId.Value; + public Vector3 ServerMoveDirection => new Vector3(_serverMoveInput.x, 0f, _serverMoveInput.y).normalized; + + public void ConfigurePrototypeMode() + { + blockMovementDuringAttack = false; + dropResourcesOnDeath = false; + respawnDelay = 3f; + } // 중앙 집중식 입력 관리 - 다른 컴포넌트에서 참조 public PlayerInputActions InputActions => _inputActions; @@ -89,6 +101,10 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl // 서버에서 초기화 if (IsServer) { + if (_ownerPlayerId.Value == ulong.MaxValue) + { + _ownerPlayerId.Value = OwnerClientId; + } if (_team.Value == TeamType.Neutral) { _team.Value = initialTeam; @@ -245,7 +261,7 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl var attackAction = GetComponent(); var playerInteraction = GetComponent(); - bool isActionBlocked = (attackAction != null && attackAction.IsAttacking) || + bool isActionBlocked = (blockMovementDuringAttack && attackAction != null && attackAction.IsAttacking) || (playerInteraction != null && playerInteraction.IsInteracting); if (isActionBlocked) @@ -420,7 +436,10 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl if (!IsServer) return; // 플레이어가 가진 자원을 ResourcePickup으로 드랍 - DropPlayerResources(); + if (dropResourcesOnDeath) + { + DropPlayerResources(); + } // 사망 이펙트 ShowDeathEffectClientRpc(); diff --git a/Assets/Scripts/PlayerActionSystem.cs b/Assets/Scripts/PlayerActionSystem.cs index 2ea87d0..453a83f 100644 --- a/Assets/Scripts/PlayerActionSystem.cs +++ b/Assets/Scripts/PlayerActionSystem.cs @@ -17,6 +17,10 @@ namespace Northbound [Header("Animation")] public bool playAnimations = true; + [Header("Secondary Action")] + [Tooltip("우클릭으로 실행할 액션 이름. 비어 있으면 사용하지 않습니다.")] + public string secondaryActionName = ""; + private Dictionary _actions = new Dictionary(); private Animator _animator; private NetworkAnimator _networkAnimator; @@ -103,6 +107,18 @@ namespace Northbound ExecuteAction("Attack"); } + private void Update() + { + if (!_isInputInitialized || !IsLocalPlayer || string.IsNullOrEmpty(secondaryActionName)) return; + if (Mouse.current != null && Mouse.current.rightButton.wasPressedThisFrame) + { + if (!UpgradeListPopup.IsOpen && (_networkPlayerController == null || !_networkPlayerController.IsDead())) + { + ExecuteAction(secondaryActionName); + } + } + } + public void ExecuteAction(string actionName) { if (_actions.TryGetValue(actionName, out IAction action)) diff --git a/Assets/Scripts/SimpleCameraZFollow.cs b/Assets/Scripts/SimpleCameraZFollow.cs index 2666c16..a5779d6 100644 --- a/Assets/Scripts/SimpleCameraZFollow.cs +++ b/Assets/Scripts/SimpleCameraZFollow.cs @@ -11,6 +11,15 @@ public class SimpleCameraZFollow : MonoBehaviour private Transform target; + public void Configure(float height, float forwardOffset, float followSmoothSpeed) + { + fixedXPosition = 0f; + fixedYPosition = height; + zOffset = forwardOffset; + smoothSpeed = followSmoothSpeed; + lockRotation = true; + } + private void Start() { FindPlayerTarget(); @@ -21,7 +30,7 @@ public class SimpleCameraZFollow : MonoBehaviour var players = FindObjectsByType(); foreach (var player in players) { - if (player.IsOwner) + if (player.IsLocalPlayer) { target = player.transform; Debug.Log($"[Camera] Target found: {player.name}");