네트워크 환경에서의 비정상 동작 수정

클라이언트 접속 전에 스폰되어 있는 오브젝트의 경우, Ownership이 Distributable일 경우 클라이언트 접속 시점에 Ownership을 호스트로부터 분배받는다.
서버만 데이터를 수정해야 하는 환경이기 때문에 대부분 Distributable 대신 None을 사용하면 된다.
This commit is contained in:
2026-02-17 01:53:06 +09:00
parent cc2487e7e4
commit 63a742d5d4
40 changed files with 582 additions and 316 deletions

View File

@@ -23,13 +23,14 @@ namespace Northbound
[Tooltip("Z 끝 위치")]
public float endZ = 700f;
private Vector2 _initialResourcePosition;
private Vector2 _corePosition;
private Vector2 _barracksPosition;
[Header("Resource Generation")]
[Tooltip("자원 프리팹")]
public GameObject resourcePrefab;
[Tooltip("기본 자원 위치 (초기 스폰 지점)")]
public Vector2 initialResourcePosition = new Vector2(0f, 5f);
[Tooltip("최소 자원 개수 (초기 자원 제외)")]
[Range(8, 12)]
public int minResourceCount = 8;
@@ -163,21 +164,6 @@ namespace Northbound
_corePosition = Vector2.zero;
}
Resource[] resources = FindObjectsByType<Resource>(FindObjectsSortMode.InstanceID);
if (resources.Length > 0)
{
_initialResourcePosition = new Vector2(resources[0].transform.position.x, resources[0].transform.position.z);
foreach (var resource in resources)
{
resource.InitializeQuality(0f);
}
}
else
{
_initialResourcePosition = Vector2.zero;
}
GameObject barracks = GameObject.Find("Worker Hall");
if (barracks != null)
{
@@ -241,9 +227,19 @@ namespace Northbound
{
resources = null;
int additionalResourceCount = Random.Range(minResourceCount, maxResourceCount + 1);
ResourceData[] tempResources = new ResourceData[additionalResourceCount];
ResourceData[] tempResources = new ResourceData[additionalResourceCount + 1];
for (int i = 0; i < additionalResourceCount; i++)
// Add initial resource at index 0
tempResources[0] = new ResourceData
{
position = initialResourcePosition,
baseProduction = initialResourceProduction,
qualityModifier = 0f,
finalProduction = initialResourceProduction
};
// Generate additional resources starting from index 1
for (int i = 1; i < tempResources.Length; i++)
{
Vector2 position;
float qualityModifier;
@@ -285,6 +281,14 @@ namespace Northbound
private bool TryFindValidResourcePosition(ResourceData[] existingResources, int currentIndex, out Vector2 position)
{
position = Vector2.zero;
// Initial resource uses fixed position
if (currentIndex == 0)
{
position = initialResourcePosition;
return true;
}
int maxAttempts = 100;
for (int attempt = 0; attempt < maxAttempts; attempt++)
@@ -305,7 +309,7 @@ namespace Northbound
private bool IsValidResourcePosition(Vector2 position, ResourceData[] existingResources, int currentIndex)
{
if (Vector2.Distance(position, _initialResourcePosition) < minDistanceBetweenResources)
if (Vector2.Distance(position, initialResourcePosition) < minDistanceBetweenResources)
{
return false;
}
@@ -334,7 +338,7 @@ namespace Northbound
private bool ValidateProductionRate(ResourceData[] additionalResources, out float globalMultiplier)
{
globalMultiplier = 1f;
float totalProduction = initialResourceProduction;
float totalProduction = 0f;
for (int i = 0; i < additionalResources.Length; i++)
{
@@ -365,6 +369,7 @@ namespace Northbound
{
_generatedResources = new ResourceData[]
{
new ResourceData { position = initialResourcePosition, baseProduction = initialResourceProduction, qualityModifier = 0f, finalProduction = initialResourceProduction },
new ResourceData { position = new Vector2(-30, 100), baseProduction = additionalResourceBaseProduction, qualityModifier = 0f, finalProduction = additionalResourceBaseProduction },
new ResourceData { position = new Vector2(30, 200), baseProduction = additionalResourceBaseProduction, qualityModifier = 0f, finalProduction = additionalResourceBaseProduction },
new ResourceData { position = new Vector2(-20, 300), baseProduction = additionalResourceBaseProduction, qualityModifier = 0f, finalProduction = additionalResourceBaseProduction },
@@ -376,7 +381,7 @@ namespace Northbound
new ResourceData { position = new Vector2(15, 250), baseProduction = additionalResourceBaseProduction, qualityModifier = 0f, finalProduction = additionalResourceBaseProduction }
};
float totalProduction = initialResourceProduction;
float totalProduction = 0f;
for (int i = 0; i < _generatedResources.Length; i++)
{
totalProduction += _generatedResources[i].finalProduction;
@@ -391,8 +396,6 @@ namespace Northbound
private void SpawnResources()
{
float totalProduction = initialResourceProduction;
for (int i = 0; i < _generatedResources.Length; i++)
{
GameObject resourceObj = Instantiate(resourcePrefab, new Vector3(_generatedResources[i].position.x, 1f, _generatedResources[i].position.y), Quaternion.identity);
@@ -409,17 +412,14 @@ namespace Northbound
NetworkObject networkObj = resourceObj.GetComponent<NetworkObject>();
if (networkObj != null)
{
networkObj.Spawn();
networkObj.SpawnWithOwnership(NetworkManager.ServerClientId);
_spawnedPositions.Add(new Vector3(_generatedResources[i].position.x, 1f, _generatedResources[i].position.y));
}
else
{
Destroy(resourceObj);
}
_spawnedPositions.Add(new Vector3(_generatedResources[i].position.x, 1f, _generatedResources[i].position.y));
totalProduction += _generatedResources[i].finalProduction;
}
}
#endregion
@@ -735,7 +735,7 @@ namespace Northbound
return false;
}
if (Vector2.Distance(new Vector2(position.x, position.z), _initialResourcePosition) < minDistanceFromInitialResource)
if (Vector2.Distance(new Vector2(position.x, position.z), initialResourcePosition) < minDistanceFromInitialResource)
{
return false;
}
@@ -841,9 +841,9 @@ namespace Northbound
public float GetTotalProduction()
{
if (_generatedResources == null)
return initialResourceProduction;
return 0f;
float total = initialResourceProduction;
float total = 0f;
for (int i = 0; i < _generatedResources.Length; i++)
{
total += _generatedResources[i].finalProduction;
@@ -906,7 +906,7 @@ namespace Northbound
if (resourcePrefab != null)
{
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(new Vector3(_initialResourcePosition.x, 0, _initialResourcePosition.y), 5f);
Gizmos.DrawWireSphere(new Vector3(initialResourcePosition.x, 0, initialResourcePosition.y), 5f);
}
if (creepCampPrefab != null)