// see which player is best suited to own this enemy private static PlayerController CalculateBestOwner(EnemyController enemy, NetworkOwnershipComponent netOwner) { CharacterTargetingComponent enemyTargeting = enemy.gameObject.GetComponent <CharacterTargetingComponent>(); PlayerController closestPlayer = null; float distToClosestPlayerSqr = float.MaxValue; for (int controller = 0; controller < PlayerManager.sPlayerControllers.Count; ++controller) { PlayerController pc = PlayerManager.sPlayerControllers[controller]; if (pc.gameObject.GetComponent <CharacterTargetingComponent>().AttackTarget == enemy.gameObject) // if this enemy is this player's attack target, then we should be owned by this player { return(pc); } float distToPlayerSqr = GameUtils.GetDistSqXZ(pc.transform.position, enemy.transform.position); if (distToPlayerSqr < distToClosestPlayerSqr) { distToClosestPlayerSqr = distToPlayerSqr; closestPlayer = pc; } } if (null != enemyTargeting.AttackTarget && PlayerManager.IsPlayer(enemyTargeting.AttackTarget)) { return(enemyTargeting.AttackTarget.GetComponent <PlayerController>()); // if this player is this enemies attack target, then we should be owned by this player } if (!netOwner.IsOwner(closestPlayer.ReplicationPlayer)) // if the closest player is not our current owner, we may want to change owners { EB.Sparx.Player sparxPlayer = netOwner.GetOwner(); if (sparxPlayer == null) { return(closestPlayer); } PlayerController currentOwner = PlayerManager.GetPlayerController(sparxPlayer); float distFromCurrentOwnerSqr = GameUtils.GetDistSqXZ(currentOwner.transform.position, enemy.transform.position); // these distances are arbitrary, but are designed so that dithering between different owners should not occur const float RequiredDistFromCurrentOwnerSqr = 12f * 12f; const float RequiredDistToNewOwnerSqr = 5f * 5f; if (distFromCurrentOwnerSqr > RequiredDistFromCurrentOwnerSqr && // if we are far enough away from our current owner distToClosestPlayerSqr < RequiredDistToNewOwnerSqr) // we are close enough to our potential new owner { return(closestPlayer); } } return(null); }
// look each frame at who should be owner of what private static void TryTransferOwnership() { for (int i = 0; i < _networkOwnershipComponents.Count; ++i) { NetworkOwnershipComponent netOwner = _networkOwnershipComponents[i]; if (!netOwner.IsOwnershipTransferAllowed) { continue; // we don't want to change who owns this object right now } EnemyController enemy = netOwner.gameObject.GetComponent <EnemyController>(); if (null != enemy) { PlayerController bestOwner = CalculateBestOwner(enemy, netOwner); if (null != bestOwner && !netOwner.IsOwner(bestOwner.ReplicationPlayer)) // if the best owner is not the current owner { netOwner.ChangeOwner(bestOwner.ReplicationPlayer); } } } }