네트워크 환경에서의 비정상 동작 수정
클라이언트 접속 전에 스폰되어 있는 오브젝트의 경우, Ownership이 Distributable일 경우 클라이언트 접속 시점에 Ownership을 호스트로부터 분배받는다. 서버만 데이터를 수정해야 하는 환경이기 때문에 대부분 Distributable 대신 None을 사용하면 된다.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace Northbound
|
||||
_displayAmount = amount;
|
||||
}
|
||||
|
||||
public void UpdateResourceAmountDirectly(int amount)
|
||||
{
|
||||
_displayAmount = amount;
|
||||
}
|
||||
|
||||
public bool CanAddResource(int amount)
|
||||
{
|
||||
var resourceManager = ServerResourceManager.Instance;
|
||||
|
||||
@@ -253,6 +253,7 @@ namespace Northbound
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void AssignOrGatherResourceServerRpc(ulong playerId, ulong resourceId)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
|
||||
bool workerAssigned = false;
|
||||
|
||||
@@ -286,6 +287,14 @@ namespace Northbound
|
||||
|
||||
private void GatherResource(ulong playerId)
|
||||
{
|
||||
Debug.Log($"[Resource] GatherResource called - IsServer: {IsServer}, OwnerClientId: {OwnerClientId}, Current: {_currentResources.Value}");
|
||||
|
||||
if (!IsServer)
|
||||
{
|
||||
Debug.LogError($"[Resource] GatherResource called on CLIENT! This should not happen!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanInteract(playerId))
|
||||
return;
|
||||
|
||||
@@ -315,18 +324,15 @@ namespace Northbound
|
||||
ShowGatheringEffectClientRpc();
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
[Rpc(SendTo.Owner)]
|
||||
private void UpdatePlayerResourcesClientRpc(ulong playerId)
|
||||
{
|
||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId].PlayerObject;
|
||||
if (playerObject != null)
|
||||
{
|
||||
var playerInventory = playerObject.GetComponent<PlayerResourceInventory>();
|
||||
if (playerInventory != null)
|
||||
{
|
||||
playerInventory.RequestResourceUpdateServerRpc();
|
||||
}
|
||||
}
|
||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId]?.PlayerObject;
|
||||
if (playerObject == null)
|
||||
return;
|
||||
|
||||
var playerInventory = playerObject.GetComponent<PlayerResourceInventory>();
|
||||
playerInventory?.RequestResourceUpdateServerRpc();
|
||||
}
|
||||
|
||||
[Rpc(SendTo.NotServer)]
|
||||
|
||||
@@ -88,18 +88,15 @@ namespace Northbound
|
||||
Invoke(nameof(DestroyPickup), 0.1f);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
[Rpc(SendTo.Owner)]
|
||||
private void UpdatePlayerResourcesClientRpc(ulong playerId)
|
||||
{
|
||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId].PlayerObject;
|
||||
if (playerObject != null)
|
||||
{
|
||||
var playerInventory = playerObject.GetComponent<PlayerResourceInventory>();
|
||||
if (playerInventory != null)
|
||||
{
|
||||
playerInventory.RequestResourceUpdateServerRpc();
|
||||
}
|
||||
}
|
||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId]?.PlayerObject;
|
||||
if (playerObject == null)
|
||||
return;
|
||||
|
||||
var playerInventory = playerObject.GetComponent<PlayerResourceInventory>();
|
||||
playerInventory?.RequestResourceUpdateServerRpc();
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
|
||||
Reference in New Issue
Block a user