Worker 네트워크 동기화
This commit is contained in:
@@ -15,6 +15,8 @@ GameObject:
|
|||||||
- component: {fileID: -6833905931170612921}
|
- component: {fileID: -6833905931170612921}
|
||||||
- component: {fileID: -5642067558840373223}
|
- component: {fileID: -5642067558840373223}
|
||||||
- component: {fileID: 7652614764984268938}
|
- component: {fileID: 7652614764984268938}
|
||||||
|
- component: {fileID: 3118986035178891702}
|
||||||
|
- component: {fileID: -802640627660999798}
|
||||||
m_Layer: 7
|
m_Layer: 7
|
||||||
m_Name: Worker
|
m_Name: Worker
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -31,7 +33,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 1348125539835438327}
|
m_GameObject: {fileID: 1348125539835438327}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 5.26293, y: 1.00002, z: -80.92117}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
@@ -102,7 +104,7 @@ MonoBehaviour:
|
|||||||
maxBagCapacity: 50
|
maxBagCapacity: 50
|
||||||
miningSpeed: 1
|
miningSpeed: 1
|
||||||
followDistance: 3
|
followDistance: 3
|
||||||
movementSpeed: 10
|
movementSpeed: 21.41
|
||||||
resourcesPerMining: 5
|
resourcesPerMining: 5
|
||||||
interactionAnimationTrigger:
|
interactionAnimationTrigger:
|
||||||
miningEffectPrefab: {fileID: 0}
|
miningEffectPrefab: {fileID: 0}
|
||||||
@@ -181,10 +183,88 @@ Rigidbody:
|
|||||||
m_ImplicitCom: 1
|
m_ImplicitCom: 1
|
||||||
m_ImplicitTensor: 1
|
m_ImplicitTensor: 1
|
||||||
m_UseGravity: 1
|
m_UseGravity: 1
|
||||||
m_IsKinematic: 0
|
m_IsKinematic: 1
|
||||||
m_Interpolate: 0
|
m_Interpolate: 0
|
||||||
m_Constraints: 0
|
m_Constraints: 0
|
||||||
m_CollisionDetection: 0
|
m_CollisionDetection: 0
|
||||||
|
--- !u!114 &3118986035178891702
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1348125539835438327}
|
||||||
|
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: 1
|
||||||
|
RotationInterpolationType: 1
|
||||||
|
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: 0
|
||||||
|
SyncScaleY: 0
|
||||||
|
SyncScaleZ: 0
|
||||||
|
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 &-802640627660999798
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1348125539835438327}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: e8d0727d5ae3244e3b569694d3912374, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.Components.NetworkAnimator
|
||||||
|
ShowTopMostFoldoutHeaderGroup: 1
|
||||||
|
NetworkAnimatorExpanded: 0
|
||||||
|
AuthorityMode: 0
|
||||||
|
m_Animator: {fileID: -6833905931170612921}
|
||||||
|
TransitionStateInfoList: []
|
||||||
|
AnimatorParameterEntries:
|
||||||
|
ParameterEntries:
|
||||||
|
- name: Idle
|
||||||
|
NameHash: 2081823275
|
||||||
|
Synchronize: 1
|
||||||
|
ParameterType: 4
|
||||||
|
- name: Walk
|
||||||
|
NameHash: 765711723
|
||||||
|
Synchronize: 1
|
||||||
|
ParameterType: 4
|
||||||
|
- name: Mine
|
||||||
|
NameHash: -912622419
|
||||||
|
Synchronize: 1
|
||||||
|
ParameterType: 4
|
||||||
|
AnimatorParametersExpanded: 0
|
||||||
--- !u!1001 &8340426036889336253
|
--- !u!1001 &8340426036889336253
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -1828,7 +1828,7 @@ MonoBehaviour:
|
|||||||
m_DisconnectTimeoutMS: 30000
|
m_DisconnectTimeoutMS: 30000
|
||||||
ConnectionData:
|
ConnectionData:
|
||||||
Address: 127.0.0.1
|
Address: 127.0.0.1
|
||||||
Port: 7835
|
Port: 7843
|
||||||
ServerListenAddress: 127.0.0.1
|
ServerListenAddress: 127.0.0.1
|
||||||
ClientBindPort: 0
|
ClientBindPort: 0
|
||||||
DebugSimulator:
|
DebugSimulator:
|
||||||
|
|||||||
@@ -163,26 +163,35 @@ namespace Northbound
|
|||||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||||
private void AssignOrGatherResourceServerRpc(ulong playerId, ulong resourceId)
|
private void AssignOrGatherResourceServerRpc(ulong playerId, ulong resourceId)
|
||||||
{
|
{
|
||||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId].PlayerObject;
|
Debug.Log($"[Resource] AssignOrGatherResourceServerRpc called - PlayerID: {playerId}, ResourceID: {resourceId}");
|
||||||
if (playerObject == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var playerInteraction = playerObject.GetComponent<PlayerInteraction>();
|
|
||||||
|
|
||||||
bool workerAssigned = false;
|
bool workerAssigned = false;
|
||||||
|
|
||||||
if (allowWorkerAssignment && playerInteraction != null && playerInteraction.assignedWorker != null)
|
if (allowWorkerAssignment)
|
||||||
{
|
{
|
||||||
var worker = playerInteraction.assignedWorker;
|
// Find worker owned by player in Following state (server-side, not client-side)
|
||||||
|
Worker assignedWorker = FindWorkerForPlayer(playerId);
|
||||||
if (worker.OwnerPlayerId == playerId && (int)worker.CurrentState == 1)
|
|
||||||
|
if (assignedWorker != null)
|
||||||
{
|
{
|
||||||
worker.AssignMiningTargetServerRpc(resourceId);
|
Debug.Log($"[Resource] Worker found server-side - OwnerPlayerId: {assignedWorker.OwnerPlayerId}, CurrentState: {(int)assignedWorker.CurrentState}");
|
||||||
workerAssigned = true;
|
|
||||||
|
if ((int)assignedWorker.CurrentState == 1) // 1 = Following
|
||||||
ShowGatheringEffectClientRpc();
|
{
|
||||||
|
Debug.Log($"[Resource] ✓ Assigning worker to resource!");
|
||||||
|
assignedWorker.AssignMiningTargetServerRpc(resourceId);
|
||||||
|
workerAssigned = true;
|
||||||
|
|
||||||
|
ShowGatheringEffectClientRpc();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[Resource] Worker not in Following state! State: {(int)assignedWorker.CurrentState}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log($"[Resource] No worker found for player {playerId} in Following state");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +201,7 @@ namespace Northbound
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GatherResource(playerId);
|
GatherResource(playerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,5 +283,42 @@ namespace Northbound
|
|||||||
{
|
{
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Worker FindWorkerForPlayer(ulong playerId)
|
||||||
|
{
|
||||||
|
Debug.Log($"[Resource] FindWorkerForPlayer called - Looking for worker assigned to player {playerId}");
|
||||||
|
|
||||||
|
if (NetworkManager.Singleton == null || NetworkManager.Singleton.SpawnManager == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[Resource] FindWorkerForPlayer - NetworkManager or SpawnManager is null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawnedObjects = NetworkManager.Singleton.SpawnManager.SpawnedObjects;
|
||||||
|
int objectsChecked = 0;
|
||||||
|
int workersFound = 0;
|
||||||
|
|
||||||
|
foreach (var kvp in spawnedObjects)
|
||||||
|
{
|
||||||
|
var networkObj = kvp.Value;
|
||||||
|
var worker = networkObj.GetComponent<Worker>();
|
||||||
|
|
||||||
|
if (worker != null)
|
||||||
|
{
|
||||||
|
workersFound++;
|
||||||
|
Debug.Log($"[Resource] FindWorkerForPlayer - Found worker: {worker.gameObject.name}, OwnerPlayerId: {worker.OwnerPlayerId}, State: {(int)worker.CurrentState}");
|
||||||
|
|
||||||
|
// Use worker's internal OwnerPlayerId, NOT NetworkObject.OwnerClientId!
|
||||||
|
if (worker.OwnerPlayerId == playerId && (int)worker.CurrentState == 1) // 1 = Following
|
||||||
|
{
|
||||||
|
Debug.Log($"[Resource] FindWorkerForPlayer - ✓ Found worker: {worker.gameObject.name} for player {playerId}");
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.LogWarning($"[Resource] FindWorkerForPlayer - Checked {objectsChecked} objects, found {workersFound} workers, no matching worker in Following state!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -504,7 +504,8 @@ namespace Northbound
|
|||||||
var networkObj = kvp.Value;
|
var networkObj = kvp.Value;
|
||||||
if (networkObj != null && networkObj.OwnerClientId == _ownerPlayerId.Value)
|
if (networkObj != null && networkObj.OwnerClientId == _ownerPlayerId.Value)
|
||||||
{
|
{
|
||||||
if (networkObj.gameObject != null)
|
var playerInteraction = networkObj.GetComponent<PlayerInteraction>();
|
||||||
|
if (playerInteraction != null && networkObj.gameObject != null)
|
||||||
{
|
{
|
||||||
_playerTransform = networkObj.transform;
|
_playerTransform = networkObj.transform;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ namespace Northbound
|
|||||||
|
|
||||||
GameObject workerObj = Instantiate(workerPrefab, spawnPosition, Quaternion.identity);
|
GameObject workerObj = Instantiate(workerPrefab, spawnPosition, Quaternion.identity);
|
||||||
NetworkObject workerNetObj = workerObj.GetComponent<NetworkObject>();
|
NetworkObject workerNetObj = workerObj.GetComponent<NetworkObject>();
|
||||||
|
|
||||||
if (workerNetObj == null)
|
if (workerNetObj == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("[WorkerSpawner] Worker prefab must have NetworkObject component");
|
Debug.LogError("[WorkerSpawner] Worker prefab must have NetworkObject component");
|
||||||
@@ -102,18 +102,19 @@ namespace Northbound
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
workerNetObj.Spawn();
|
// IMPORTANT: Spawn as server-owned so server can modify worker's NetworkVariables
|
||||||
_lastSpawnTime = Time.time;
|
workerNetObj.Spawn();
|
||||||
_workerCount.Value++;
|
_lastSpawnTime = Time.time;
|
||||||
|
_workerCount.Value++;
|
||||||
|
|
||||||
ShowSpawnEffectClientRpc(spawnPosition);
|
ShowSpawnEffectClientRpc(spawnPosition);
|
||||||
|
|
||||||
Debug.Log($"[WorkerSpawner] 워커 생성됨 (총 워커: {_workerCount.Value}/{maxWorkers})");
|
Debug.Log($"[WorkerSpawner] Worker spawned (server-owned) and assigned to player {playerId} (Total: {_workerCount.Value}/{maxWorkers})");
|
||||||
|
|
||||||
ScheduleWorkerAssignment(playerId, workerNetObj.NetworkObjectId);
|
ScheduleWorkerAssignment(playerId, workerNetObj.NetworkObjectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScheduleWorkerAssignment(ulong playerId, ulong workerNetObjectId)
|
private void ScheduleWorkerAssignment(ulong playerId, ulong workerNetObjectId)
|
||||||
{
|
{
|
||||||
StartCoroutine(AssignWorkerAfterFrame(playerId, workerNetObjectId));
|
StartCoroutine(AssignWorkerAfterFrame(playerId, workerNetObjectId));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user