ObstacleSpawner 네트워크 연동

모든 클라이언트가 동일한 장애물을 보도록 함
This commit is contained in:
2026-02-02 10:08:57 +09:00
parent 10b496dfae
commit b5f8943bcc
8 changed files with 234 additions and 16 deletions

View File

@@ -114,3 +114,28 @@ MonoBehaviour:
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 7245241003860522441, guid: 2c33c67d086286d4a929d533b4e26863, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 7867287811520877109, guid: 915c4daebc2463840b83193366491ba1, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 1559926009631082787, guid: 4ade932e47f340647ac833f7188a6dd0, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 4345146930867537194, guid: d754e5f1f9047ce428c55a0ae1975b4e, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 7773749726967315046, guid: b49d9f4b44d4c7d4b92498e95c847667, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}

View File

@@ -10,6 +10,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 6371576195603730939} - component: {fileID: 6371576195603730939}
- component: {fileID: -3907047637289204963} - component: {fileID: -3907047637289204963}
- component: {fileID: -8721167865250746961}
m_Layer: 10 m_Layer: 10
m_Name: Rock1 m_Name: Rock1
m_TagString: Untagged m_TagString: Untagged
@@ -48,9 +49,36 @@ MonoBehaviour:
showInExploredAreas: 1 showInExploredAreas: 1
updateInterval: 0.2 updateInterval: 0.2
renderers: [] renderers: []
debugLogging: 1 enableDistantVisibility: 1
heightVisibilityMultiplier: 2
minHeightForDistantVisibility: 3
useExploredMaterial: 0 useExploredMaterial: 0
exploredMaterial: {fileID: 0} exploredMaterial: {fileID: 0}
--- !u!114 &-8721167865250746961
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7867287811520877109}
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
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 1
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1001 &276409350290535739 --- !u!1001 &276409350290535739
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -10,6 +10,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 5791990943856352332} - component: {fileID: 5791990943856352332}
- component: {fileID: 6386629597168169889} - component: {fileID: 6386629597168169889}
- component: {fileID: 4283595864140016680}
m_Layer: 10 m_Layer: 10
m_Name: Rock2 m_Name: Rock2
m_TagString: Untagged m_TagString: Untagged
@@ -48,9 +49,36 @@ MonoBehaviour:
showInExploredAreas: 1 showInExploredAreas: 1
updateInterval: 0.2 updateInterval: 0.2
renderers: [] renderers: []
debugLogging: 1 enableDistantVisibility: 1
heightVisibilityMultiplier: 2
minHeightForDistantVisibility: 3
useExploredMaterial: 0 useExploredMaterial: 0
exploredMaterial: {fileID: 0} exploredMaterial: {fileID: 0}
--- !u!114 &4283595864140016680
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7245241003860522441}
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
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 1
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1001 &1439609661864653002 --- !u!1001 &1439609661864653002
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -10,6 +10,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 5832127839780190644} - component: {fileID: 5832127839780190644}
- component: {fileID: 6163423706184354979} - component: {fileID: 6163423706184354979}
- component: {fileID: 6341284887249651874}
m_Layer: 10 m_Layer: 10
m_Name: Rock3 m_Name: Rock3
m_TagString: Untagged m_TagString: Untagged
@@ -48,9 +49,36 @@ MonoBehaviour:
showInExploredAreas: 1 showInExploredAreas: 1
updateInterval: 0.2 updateInterval: 0.2
renderers: [] renderers: []
debugLogging: 1 enableDistantVisibility: 1
heightVisibilityMultiplier: 2
minHeightForDistantVisibility: 3
useExploredMaterial: 0 useExploredMaterial: 0
exploredMaterial: {fileID: 0} exploredMaterial: {fileID: 0}
--- !u!114 &6341284887249651874
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7773749726967315046}
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
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 1
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1001 &8592066193955497239 --- !u!1001 &8592066193955497239
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -11,6 +11,7 @@ GameObject:
- component: {fileID: 7011000049316995908} - component: {fileID: 7011000049316995908}
- component: {fileID: 1948217933253124379} - component: {fileID: 1948217933253124379}
- component: {fileID: 1861572095783484933} - component: {fileID: 1861572095783484933}
- component: {fileID: 383497841330268597}
m_Layer: 10 m_Layer: 10
m_Name: Tree1 m_Name: Tree1
m_TagString: Untagged m_TagString: Untagged
@@ -70,9 +71,36 @@ MonoBehaviour:
showInExploredAreas: 1 showInExploredAreas: 1
updateInterval: 0.2 updateInterval: 0.2
renderers: [] renderers: []
debugLogging: 1 enableDistantVisibility: 1
heightVisibilityMultiplier: 2
minHeightForDistantVisibility: 3
useExploredMaterial: 0 useExploredMaterial: 0
exploredMaterial: {fileID: 0} exploredMaterial: {fileID: 0}
--- !u!114 &383497841330268597
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1559926009631082787}
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
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 1
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1001 &6713237626157896158 --- !u!1001 &6713237626157896158
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -11,6 +11,7 @@ GameObject:
- component: {fileID: 2594114534543661658} - component: {fileID: 2594114534543661658}
- component: {fileID: 6161783292885910878} - component: {fileID: 6161783292885910878}
- component: {fileID: 5630203293812958152} - component: {fileID: 5630203293812958152}
- component: {fileID: 2966181383853663289}
m_Layer: 10 m_Layer: 10
m_Name: Tree2 m_Name: Tree2
m_TagString: Untagged m_TagString: Untagged
@@ -70,9 +71,36 @@ MonoBehaviour:
showInExploredAreas: 1 showInExploredAreas: 1
updateInterval: 0.2 updateInterval: 0.2
renderers: [] renderers: []
debugLogging: 1 enableDistantVisibility: 1
heightVisibilityMultiplier: 2
minHeightForDistantVisibility: 3
useExploredMaterial: 0 useExploredMaterial: 0
exploredMaterial: {fileID: 0} exploredMaterial: {fileID: 0}
--- !u!114 &2966181383853663289
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4345146930867537194}
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
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 1
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1001 &7745148207212772657 --- !u!1001 &7745148207212772657
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -2009,6 +2009,7 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 1572384099} - component: {fileID: 1572384099}
- component: {fileID: 1572384100}
- component: {fileID: 1572384098} - component: {fileID: 1572384098}
m_Layer: 0 m_Layer: 0
m_Name: ObstacleSpawner m_Name: ObstacleSpawner
@@ -2029,6 +2030,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a889d8fab7aeaa24dbbffaee2f02ba54, type: 3} m_Script: {fileID: 11500000, guid: a889d8fab7aeaa24dbbffaee2f02ba54, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Northbound.ObstacleSpawner m_EditorClassIdentifier: Assembly-CSharp::Northbound.ObstacleSpawner
ShowTopMostFoldoutHeaderGroup: 1
spawnCenter: {fileID: 0} spawnCenter: {fileID: 0}
spawnAreaSize: {x: 80, y: 725} spawnAreaSize: {x: 80, y: 725}
areaShape: 0 areaShape: 0
@@ -2082,6 +2084,31 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1572384100
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1572384097}
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: 2866586184
InScenePlacedSourceGlobalObjectIdHash: 0
DeferredDespawnTick: 0
Ownership: 1
AlwaysReplicateAsRoot: 0
SynchronizeTransform: 1
ActiveSceneSynchronization: 0
SceneMigrationSynchronization: 0
SpawnWithObservers: 1
DontDestroyWithOwner: 0
AutoObjectParentSync: 1
SyncOwnerTransformWhenParented: 1
AllowOwnerToParent: 0
--- !u!1 &1701756764 --- !u!1 &1701756764
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@@ -1,12 +1,13 @@
using UnityEngine; using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using Unity.Netcode;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEditor; using UnityEditor;
#endif #endif
namespace Northbound namespace Northbound
{ {
public class ObstacleSpawner : MonoBehaviour public class ObstacleSpawner : NetworkBehaviour
{ {
[System.Serializable] [System.Serializable]
public class ObstacleEntry public class ObstacleEntry
@@ -89,9 +90,9 @@ namespace Northbound
Circle Circle
} }
private void Start() public override void OnNetworkSpawn()
{ {
if (spawnOnStart) if (IsServer && spawnOnStart)
{ {
SpawnObstacles(); SpawnObstacles();
} }
@@ -102,6 +103,12 @@ namespace Northbound
/// </summary> /// </summary>
public void SpawnObstacles() public void SpawnObstacles()
{ {
if (!IsServer)
{
Debug.LogWarning("[ObstacleSpawner] Only server can spawn obstacles!");
return;
}
ClearObstacles(); ClearObstacles();
_spawnedPositions.Clear(); _spawnedPositions.Clear();
@@ -236,17 +243,12 @@ namespace Northbound
} }
// 장애물 생성 // 장애물 생성
Quaternion rotation = randomRotation Quaternion rotation = randomRotation
? Quaternion.Euler(0, Random.Range(0f, 360f), 0) ? Quaternion.Euler(0, Random.Range(0f, 360f), 0)
: Quaternion.identity; : Quaternion.identity;
GameObject obstacle = Instantiate(obstacleEntry.prefab, randomPos, rotation); GameObject obstacle = Instantiate(obstacleEntry.prefab, randomPos, rotation);
if (groupUnderParent && _obstacleParent != null)
{
obstacle.transform.SetParent(_obstacleParent);
}
// 크기 변화 // 크기 변화
if (scaleVariation > 0) if (scaleVariation > 0)
{ {
@@ -254,11 +256,26 @@ namespace Northbound
obstacle.transform.localScale *= scale; obstacle.transform.localScale *= scale;
} }
// Add NetworkObject component if not exists
NetworkObject networkObj = obstacle.GetComponent<NetworkObject>();
if (networkObj == null)
{
networkObj = obstacle.AddComponent<NetworkObject>();
}
if (groupUnderParent && _obstacleParent != null)
{
obstacle.transform.SetParent(_obstacleParent);
}
// Spawn on network
networkObj.Spawn();
// Add FogOfWarVisibility component to hide obstacles in unexplored areas // Add FogOfWarVisibility component to hide obstacles in unexplored areas
if (obstacle.GetComponent<FogOfWarVisibility>() == null) if (obstacle.GetComponent<FogOfWarVisibility>() == null)
{ {
var visibility = obstacle.AddComponent<FogOfWarVisibility>(); var visibility = obstacle.AddComponent<FogOfWarVisibility>();
visibility.showInExploredAreas = false; // Obstacles hidden when not visible visibility.showInExploredAreas = false;
visibility.updateInterval = 0.2f; visibility.updateInterval = 0.2f;
} }
@@ -359,6 +376,15 @@ namespace Northbound
{ {
if (_obstacleParent != null) if (_obstacleParent != null)
{ {
foreach (Transform child in _obstacleParent)
{
NetworkObject networkObj = child.GetComponent<NetworkObject>();
if (networkObj != null && networkObj.IsSpawned)
{
networkObj.Despawn(true);
}
}
if (Application.isPlaying) if (Application.isPlaying)
{ {
Destroy(_obstacleParent.gameObject); Destroy(_obstacleParent.gameObject);