Commit 33f6e76e by alsunj

add documenation and setup scene

parent 5dd86ee9
Showing with 1477 additions and 730 deletions
...@@ -54,3 +54,8 @@ MonoBehaviour: ...@@ -54,3 +54,8 @@ MonoBehaviour:
SourcePrefabToOverride: {fileID: 0} SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0 SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0} OverridingTargetPrefab: {fileID: 0}
- Override: 0
Prefab: {fileID: 6866275124911934084, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
SourcePrefabToOverride: {fileID: 0}
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Represents an animated enemy in the game, inheriting from the base Enemy class.
/// This class handles initialization of enemy-specific components such as the EnemyManager
/// and EnemyAnimator, and provides functionality for enemy animations and events.
/// </summary>
public class AnimatedEnemy : Enemy public class AnimatedEnemy : Enemy
{ {
/// <summary>
/// Reference to the EnemyAnimator component, which handles animation-related events.
/// </summary>
protected EnemyAnimator _enemyAnimator; protected EnemyAnimator _enemyAnimator;
/// <summary>
/// Reference to the EnemyManager component, which manages enemy-specific logic and events.
/// </summary>
protected EnemyManager _enemyManager; protected EnemyManager _enemyManager;
/// <summary>
/// Initializes the enemy with the specified detection range and target layer mask.
/// This method also initializes the EnemyManager and EnemyAnimator components.
/// </summary>
/// <param name="detectionRange">The range within which the enemy can detect targets.</param>
/// <param name="targetLayerMask">The layer mask used to identify valid targets.</param>
protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask) protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask)
{ {
base.InitializeEnemy(detectionRange, targetLayerMask); base.InitializeEnemy(detectionRange, targetLayerMask);
// Initialize the EnemyManager component
_enemyManager = GetComponent<EnemyManager>(); _enemyManager = GetComponent<EnemyManager>();
if (_enemyManager != null) if (_enemyManager != null)
{ {
...@@ -19,35 +39,14 @@ public class AnimatedEnemy : Enemy ...@@ -19,35 +39,14 @@ public class AnimatedEnemy : Enemy
Debug.LogError("EnemyManager is not set in the inspector"); Debug.LogError("EnemyManager is not set in the inspector");
} }
// Initialize the EnemyAnimator component and bind its events
_enemyAnimator = GetComponentInChildren<EnemyAnimator>(); _enemyAnimator = GetComponentInChildren<EnemyAnimator>();
_enemyAnimator.InitializeEvents(_enemyManager.enemyEvents); _enemyAnimator.InitializeEvents(_enemyManager.enemyEvents);
// if (_enemyAnimator != null)
// {
// _enemyAnimator.InitializeEvents(_enemyManager.enemyEvents);
// _enemyAnimator.receiveTargetShotEventFromAnimator += TargetShotEventServerRpc;
// _enemyAnimator.receiveTargetAimedEventFromAnimator += ShootTargetServerRpc;
// _enemyAnimator.receiveTargetReloadEventFromAnimator += ReloadCrossbowServerRpc;
// }
} }
// not possible to raise the functions to inheritor
// [ServerRpc]
// protected virtual void ReloadCrossbowServerRpc()
// {
// }
//
// [ServerRpc]
// protected virtual void ShootTargetServerRpc()
// {
// _enemyManager.enemyEvents.EnemyAttack();
// }
//
// [ServerRpc]
// protected virtual void TargetShotEventServerRpc()
// {
// _enemyManager.enemyEvents.EnemyReload();
// }
/// <summary>
/// Handles aiming at the target by triggering the appropriate enemy event.
/// </summary>
protected virtual void AimAtTarget() protected virtual void AimAtTarget()
{ {
_enemyManager.enemyEvents.EnemyAim(); _enemyManager.enemyEvents.EnemyAim();
......
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
public class DamageCollision : NetworkBehaviour /// <summary>
/// Manages collision-based damage interactions in a networked environment.
/// This class handles damage application, object despawning, and client-side updates
/// for projectiles and enemies upon collision with targets or terrain.
/// </summary>
public class DamageCollisionManager : NetworkBehaviour
{ {
/// <summary>
/// Settings for damage collision, including target and terrain layers and damage amount.
/// </summary>
[SerializeField] private DamageCollisionSettings _damageCollisionSettings; [SerializeField] private DamageCollisionSettings _damageCollisionSettings;
private int _targetLayer;
private int _terrainLayer;
private int _damage;
private int _targetLayer; // Layer for target objects (e.g., players).
private int _terrainLayer; // Layer for terrain objects.
private int _damage; // Amount of damage to apply to targets.
/// <summary>
/// Called when the object is spawned on the network.
/// Initializes layer and damage values from the provided settings.
/// </summary>
public override void OnNetworkSpawn() public override void OnNetworkSpawn()
{ {
_targetLayer = GetLayerFromLayerMask(_damageCollisionSettings.targetLayer); _targetLayer = GetLayerFromLayerMask(_damageCollisionSettings.targetLayer);
...@@ -15,21 +28,27 @@ public class DamageCollision : NetworkBehaviour ...@@ -15,21 +28,27 @@ public class DamageCollision : NetworkBehaviour
_damage = _damageCollisionSettings.damageAmount; _damage = _damageCollisionSettings.damageAmount;
} }
/// <summary>
/// Handles collision events and applies appropriate logic based on the collided object's layer.
/// </summary>
/// <param name="other">The collision data of the object this collided with.</param>
private void OnCollisionEnter(Collision other) private void OnCollisionEnter(Collision other)
{ {
if (IsServer) if (IsServer) // Ensure logic is executed only on the server.
{ {
if (other.gameObject.layer == _targetLayer) if (other.gameObject.layer == _targetLayer)
{ {
// Apply damage to the target if it has a PlayerHealth component.
other.gameObject.GetComponent<PlayerHealth>().decreaseHealth(_damage); other.gameObject.GetComponent<PlayerHealth>().decreaseHealth(_damage);
// Handle enemy despawning and removal from targeting list.
if (gameObject.TryGetComponent(out Slime enemyComponent)) if (gameObject.TryGetComponent(out Slime enemyComponent))
{ {
TargetingManager.Instance.RemoveEnemyFromTargetingList(enemyComponent); TargetingManager.Instance.RemoveEnemyFromTargetingList(enemyComponent);
gameObject.GetComponent<NetworkObject>().Despawn(); gameObject.GetComponent<NetworkObject>().Despawn();
Destroy(this);
} }
// Handle arrow-specific logic for disabling the arrow on clients.
if (gameObject.TryGetComponent(out Arrow arrowComponent)) if (gameObject.TryGetComponent(out Arrow arrowComponent))
{ {
NetworkObjectReference arrowNetworkObjectReference = NetworkObjectReference arrowNetworkObjectReference =
...@@ -40,6 +59,7 @@ public class DamageCollision : NetworkBehaviour ...@@ -40,6 +59,7 @@ public class DamageCollision : NetworkBehaviour
if (other.gameObject.layer == _terrainLayer) if (other.gameObject.layer == _terrainLayer)
{ {
// Handle arrow-specific logic for disabling the arrow on clients when hitting terrain.
if (gameObject.TryGetComponent(out Arrow arrowComponent)) if (gameObject.TryGetComponent(out Arrow arrowComponent))
{ {
NetworkObjectReference arrowNetworkObjectReference = NetworkObjectReference arrowNetworkObjectReference =
...@@ -50,6 +70,10 @@ public class DamageCollision : NetworkBehaviour ...@@ -50,6 +70,10 @@ public class DamageCollision : NetworkBehaviour
} }
} }
/// <summary>
/// Disables the arrow object on all clients.
/// </summary>
/// <param name="arrowReference">A reference to the arrow's NetworkObject.</param>
[ClientRpc] [ClientRpc]
private void DisableArrowClientRpc(NetworkObjectReference arrowReference) private void DisableArrowClientRpc(NetworkObjectReference arrowReference)
{ {
...@@ -59,6 +83,11 @@ public class DamageCollision : NetworkBehaviour ...@@ -59,6 +83,11 @@ public class DamageCollision : NetworkBehaviour
} }
} }
/// <summary>
/// Converts a LayerMask to its corresponding layer index.
/// </summary>
/// <param name="layerMask">The LayerMask to convert.</param>
/// <returns>The index of the layer, or -1 if the LayerMask is invalid.</returns>
public static int GetLayerFromLayerMask(LayerMask layerMask) public static int GetLayerFromLayerMask(LayerMask layerMask)
{ {
int value = layerMask.value; int value = layerMask.value;
......
...@@ -2,12 +2,33 @@ using System; ...@@ -2,12 +2,33 @@ using System;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Represents a base class for enemies in the game.
/// Provides properties and methods for enemy initialization and behavior.
/// </summary>
public class Enemy : NetworkBehaviour public class Enemy : NetworkBehaviour
{ {
/// <summary>
/// Gets or sets the detection radius of the enemy.
/// This defines the range within which the enemy can detect targets.
/// </summary>
public int DetectionRadius { get; set; } public int DetectionRadius { get; set; }
/// <summary>
/// Gets or sets the current target of the enemy.
/// </summary>
public Transform Target { get; set; } public Transform Target { get; set; }
/// <summary>
/// Gets or sets the layer mask used to identify valid targets for the enemy.
/// </summary>
public LayerMask TargetLayerMask { get; set; } public LayerMask TargetLayerMask { get; set; }
/// <summary>
/// Initializes the enemy with the specified detection range and target layer mask.
/// </summary>
/// <param name="detectionRange">The range within which the enemy can detect targets.</param>
/// <param name="targetLayerMask">The layer mask used to identify valid targets.</param>
protected virtual void InitializeEnemy(int detectionRange, LayerMask targetLayerMask) protected virtual void InitializeEnemy(int detectionRange, LayerMask targetLayerMask)
{ {
DetectionRadius = detectionRange; DetectionRadius = detectionRange;
...@@ -15,6 +36,9 @@ public class Enemy : NetworkBehaviour ...@@ -15,6 +36,9 @@ public class Enemy : NetworkBehaviour
Target = null; Target = null;
} }
// /// <summary>
// /// Removes the enemy from the targeting list when it is destroyed.
// /// </summary>
// public override void OnDestroy() // public override void OnDestroy()
// { // {
// TargetingManager.Instance.RemoveEnemyFromTargetingList(this); // TargetingManager.Instance.RemoveEnemyFromTargetingList(this);
......
...@@ -3,20 +3,37 @@ using System.Collections; ...@@ -3,20 +3,37 @@ using System.Collections;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEngine; using UnityEngine;
/// <summary>
/// Handles enemy animation events and triggers animations for aiming, reloading, and attacking.
/// This class also integrates with the EnemyEvents system to respond to enemy-specific actions.
/// </summary>
public class EnemyAnimator : MonoBehaviour public class EnemyAnimator : MonoBehaviour
{ {
private const string IS_AIMING = "Aim"; private const string IS_AIMING = "Aim"; // Animation trigger for aiming.
private const string IS_RELOADING = "Reload"; private const string IS_RELOADING = "Reload"; // Animation trigger for reloading.
private const string IS_ATTACKING = "Attack"; private const string IS_ATTACKING = "Attack"; // Animation trigger for attacking.
private EnemyEvents _enemyEvents; private EnemyEvents _enemyEvents; // Reference to the EnemyEvents instance.
private Animator _animator; private Animator _animator; // Reference to the Animator component.
/// <summary>
/// Event triggered when the animator signals that the target has been shot.
/// </summary>
public event Action receiveTargetShotEventFromAnimator; public event Action receiveTargetShotEventFromAnimator;
/// <summary>
/// Event triggered when the animator signals that the target has been aimed at.
/// </summary>
public event Action receiveTargetAimedEventFromAnimator; public event Action receiveTargetAimedEventFromAnimator;
public event Action receiveTargetReloadEventFromAnimator;
/// <summary>
/// Event triggered when the animator signals that the target has been reloaded.
/// </summary>
public event Action receiveTargetReloadEventFromAnimator;
/// <summary>
/// Unsubscribes from EnemyEvents when the object is disabled.
/// </summary>
private void OnDisable() private void OnDisable()
{ {
if (_enemyEvents != null) if (_enemyEvents != null)
...@@ -27,6 +44,11 @@ public class EnemyAnimator : MonoBehaviour ...@@ -27,6 +44,11 @@ public class EnemyAnimator : MonoBehaviour
} }
} }
/// <summary>
/// Initializes the EnemyAnimator with the provided EnemyEvents instance.
/// Binds animation triggers to the corresponding enemy events.
/// </summary>
/// <param name="enemyEvents">The EnemyEvents instance to bind to.</param>
public void InitializeEvents(EnemyEvents enemyEvents) public void InitializeEvents(EnemyEvents enemyEvents)
{ {
_animator = GetComponentInChildren<Animator>(); _animator = GetComponentInChildren<Animator>();
...@@ -44,31 +66,49 @@ public class EnemyAnimator : MonoBehaviour ...@@ -44,31 +66,49 @@ public class EnemyAnimator : MonoBehaviour
} }
} }
/// <summary>
/// Invokes the event when the animator signals that the target has been aimed at.
/// </summary>
private void ReceiveTargetAimedEventFromAnimator() private void ReceiveTargetAimedEventFromAnimator()
{ {
receiveTargetAimedEventFromAnimator?.Invoke(); receiveTargetAimedEventFromAnimator?.Invoke();
} }
/// <summary>
/// Invokes the event when the animator signals that the target has been reloaded.
/// </summary>
private void ReceiveTargetReloadEventFromAnimator() private void ReceiveTargetReloadEventFromAnimator()
{ {
receiveTargetReloadEventFromAnimator?.Invoke(); receiveTargetReloadEventFromAnimator?.Invoke();
} }
/// <summary>
/// Invokes the event when the animator signals that the target has been shot.
/// </summary>
private void ReceiveTargetShotEventFromAnimator() private void ReceiveTargetShotEventFromAnimator()
{ {
receiveTargetShotEventFromAnimator?.Invoke(); receiveTargetShotEventFromAnimator?.Invoke();
} }
/// <summary>
/// Triggers the reload animation for the enemy.
/// </summary>
private void SetEnemyReload() private void SetEnemyReload()
{ {
_animator.SetTrigger(IS_RELOADING); _animator.SetTrigger(IS_RELOADING);
} }
/// <summary>
/// Triggers the aim animation for the enemy.
/// </summary>
private void SetEnemyAim() private void SetEnemyAim()
{ {
_animator.SetTrigger(IS_AIMING); _animator.SetTrigger(IS_AIMING);
} }
/// <summary>
/// Triggers the attack animation for the enemy.
/// </summary>
private void SetEnemyAttack() private void SetEnemyAttack()
{ {
_animator.SetTrigger(IS_ATTACKING); _animator.SetTrigger(IS_ATTACKING);
......
...@@ -3,19 +3,39 @@ using DG.Tweening; ...@@ -3,19 +3,39 @@ using DG.Tweening;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Represents a Rogue enemy, inheriting from AnimatedEnemy.
/// This class handles the initialization and behavior of the Rogue, including aiming, shooting, and reloading.
/// </summary>
public class Rogue : AnimatedEnemy public class Rogue : AnimatedEnemy
{ {
/// <summary>
/// Settings for the enemy, including detection range, target layer, and shooting delay.
/// </summary>
[SerializeField] private EnemySettings enemySettings; [SerializeField] private EnemySettings enemySettings;
/// <summary>
/// Prefab for the arrow used by the Rogue.
/// </summary>
[SerializeField] private GameObject arrow; [SerializeField] private GameObject arrow;
/// <summary>
/// Reference to the weapon GameObject used by the Rogue.
/// </summary>
[SerializeField] private GameObject weapon; [SerializeField] private GameObject weapon;
private Arrow _arrowComponent;
private float _shootingCooldown;
private bool _isAiming;
private Vector3 _lookingDirection;
private NetworkObject _instantiatedArrow;
private Transform _arrowSpawnPoint;
private Rigidbody _arrowRigidbody;
private Arrow _arrowComponent; // Reference to the Arrow component of the instantiated arrow.
private float _shootingCooldown; // Cooldown timer for shooting.
private bool _isAiming; // Indicates whether the Rogue is currently aiming.
private Vector3 _lookingDirection; // Direction the Rogue is looking towards.
private NetworkObject _instantiatedArrow; // Networked instance of the arrow.
private Transform _arrowSpawnPoint; // Spawn point for the arrow.
private Rigidbody _arrowRigidbody; // Rigidbody component of the arrow.
/// <summary>
/// Called when the Rogue is spawned on the network.
/// Initializes the enemy with the specified settings.
/// </summary>
public override void OnNetworkSpawn() public override void OnNetworkSpawn()
{ {
if (IsServer) if (IsServer)
...@@ -24,9 +44,16 @@ public class Rogue : AnimatedEnemy ...@@ -24,9 +44,16 @@ public class Rogue : AnimatedEnemy
} }
} }
/// <summary>
/// Initializes the Rogue with the specified detection range and target layer mask.
/// Sets up event listeners and validates required components.
/// </summary>
/// <param name="detectionRange">The range within which the Rogue can detect targets.</param>
/// <param name="targetLayerMask">The layer mask used to identify valid targets.</param>
protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask) protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask)
{ {
base.InitializeEnemy(detectionRange, targetLayerMask); base.InitializeEnemy(detectionRange, targetLayerMask);
if (_enemyAnimator != null) if (_enemyAnimator != null)
{ {
_enemyAnimator.receiveTargetShotEventFromAnimator += TargetShotEvent; _enemyAnimator.receiveTargetShotEventFromAnimator += TargetShotEvent;
...@@ -50,7 +77,6 @@ public class Rogue : AnimatedEnemy ...@@ -50,7 +77,6 @@ public class Rogue : AnimatedEnemy
_arrowSpawnPoint = weapon.transform.Find("Skeleton_Crossbow/ArrowSpawnPoint"); _arrowSpawnPoint = weapon.transform.Find("Skeleton_Crossbow/ArrowSpawnPoint");
if (_arrowSpawnPoint == null) if (_arrowSpawnPoint == null)
{ {
throw new Exception("ArrowSpawnPoint is not found as a child of Weapon"); throw new Exception("ArrowSpawnPoint is not found as a child of Weapon");
} }
...@@ -60,11 +86,12 @@ public class Rogue : AnimatedEnemy ...@@ -60,11 +86,12 @@ public class Rogue : AnimatedEnemy
throw new Exception("Arrow is not set in the inspector"); throw new Exception("Arrow is not set in the inspector");
} }
InstantiateArrow(); InstantiateArrow();
} }
/// <summary>
/// Instantiates the arrow at the spawn point and sets up its components.
/// </summary>
public void InstantiateArrow() public void InstantiateArrow()
{ {
_instantiatedArrow = Instantiate(arrow, _arrowSpawnPoint.position, _arrowSpawnPoint.rotation) _instantiatedArrow = Instantiate(arrow, _arrowSpawnPoint.position, _arrowSpawnPoint.rotation)
...@@ -75,9 +102,13 @@ public class Rogue : AnimatedEnemy ...@@ -75,9 +102,13 @@ public class Rogue : AnimatedEnemy
_arrowComponent.SetTargetTransform(_arrowSpawnPoint.transform); _arrowComponent.SetTargetTransform(_arrowSpawnPoint.transform);
} }
/// <summary>
/// Updates the Rogue's behavior, including cooldown management and target rotation.
/// </summary>
private void Update() private void Update()
{ {
if (!IsServer) return; if (!IsServer) return;
if (_shootingCooldown > 0) if (_shootingCooldown > 0)
{ {
_shootingCooldown -= Time.deltaTime; _shootingCooldown -= Time.deltaTime;
...@@ -90,6 +121,9 @@ public class Rogue : AnimatedEnemy ...@@ -90,6 +121,9 @@ public class Rogue : AnimatedEnemy
} }
} }
/// <summary>
/// Handles aiming at the target. If the arrow is inactive, triggers a reload.
/// </summary>
protected override void AimAtTarget() protected override void AimAtTarget()
{ {
if (!_instantiatedArrow.gameObject.activeSelf) if (!_instantiatedArrow.gameObject.activeSelf)
...@@ -101,6 +135,9 @@ public class Rogue : AnimatedEnemy ...@@ -101,6 +135,9 @@ public class Rogue : AnimatedEnemy
base.AimAtTarget(); base.AimAtTarget();
} }
/// <summary>
/// Rotates the Rogue to face the target and triggers the aim action.
/// </summary>
private void RotateTowardsTarget() private void RotateTowardsTarget()
{ {
_lookingDirection = (Target.position - transform.position).normalized; _lookingDirection = (Target.position - transform.position).normalized;
...@@ -110,12 +147,18 @@ public class Rogue : AnimatedEnemy ...@@ -110,12 +147,18 @@ public class Rogue : AnimatedEnemy
AimAtTarget(); AimAtTarget();
} }
/// <summary>
/// Handles shooting at the target and sets the shooting cooldown.
/// </summary>
private void ShootTarget() private void ShootTarget()
{ {
_enemyManager.enemyEvents.EnemyAttack(); _enemyManager.enemyEvents.EnemyAttack();
_shootingCooldown = enemySettings.shootingDelay; _shootingCooldown = enemySettings.shootingDelay;
} }
/// <summary>
/// Handles the event when the target is shot. Reloads the crossbow and applies velocity to the arrow.
/// </summary>
private void TargetShotEvent() private void TargetShotEvent()
{ {
_enemyManager.enemyEvents.EnemyReload(); _enemyManager.enemyEvents.EnemyReload();
...@@ -123,6 +166,9 @@ public class Rogue : AnimatedEnemy ...@@ -123,6 +166,9 @@ public class Rogue : AnimatedEnemy
_arrowRigidbody.linearVelocity = _lookingDirection * enemySettings.shootingRange; _arrowRigidbody.linearVelocity = _lookingDirection * enemySettings.shootingRange;
} }
/// <summary>
/// Reloads the crossbow by resetting the arrow's position and enabling it on clients.
/// </summary>
private void ReloadCrossbow() private void ReloadCrossbow()
{ {
_arrowRigidbody.linearVelocity = Vector3.zero; _arrowRigidbody.linearVelocity = Vector3.zero;
...@@ -131,7 +177,10 @@ public class Rogue : AnimatedEnemy ...@@ -131,7 +177,10 @@ public class Rogue : AnimatedEnemy
EnableArrowClientRpc(arrowReference); EnableArrowClientRpc(arrowReference);
} }
/// <summary>
/// Enables the arrow on all clients.
/// </summary>
/// <param name="arrowReference">A reference to the arrow's NetworkObject.</param>
[ClientRpc] [ClientRpc]
private void EnableArrowClientRpc(NetworkObjectReference arrowReference) private void EnableArrowClientRpc(NetworkObjectReference arrowReference)
{ {
......
using UnityEngine; using UnityEngine;
/// <summary>
/// Represents a Slime enemy, inheriting from the base Enemy class.
/// This class handles the initialization and movement behavior of the Slime enemy.
/// </summary>
public class Slime : Enemy public class Slime : Enemy
{ {
/// <summary>
/// Settings for the Slime enemy, including detection range, target layer, and movement speed.
/// </summary>
[SerializeField] private EnemySettings enemySettings; [SerializeField] private EnemySettings enemySettings;
/// <summary>
/// Reference to the Rigidbody component used for controlling the Slime's movement.
/// </summary>
private Rigidbody _rigidbody; private Rigidbody _rigidbody;
private int _targetLayer;
/// <summary>
/// Layer mask for identifying valid target objects.
/// </summary>
private int _targetLayer;
/// <summary>
/// Called when the Slime is spawned on the network.
/// Initializes the enemy with the specified settings.
/// </summary>
public override void OnNetworkSpawn() public override void OnNetworkSpawn()
{ {
if (IsServer) if (IsServer)
...@@ -15,12 +33,22 @@ public class Slime : Enemy ...@@ -15,12 +33,22 @@ public class Slime : Enemy
} }
} }
/// <summary>
/// Initializes the Slime with the specified detection range and target layer mask.
/// Sets up the Rigidbody component for movement.
/// </summary>
/// <param name="detectionRange">The range within which the Slime can detect targets.</param>
/// <param name="targetLayerMask">The layer mask used to identify valid targets.</param>
protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask) protected override void InitializeEnemy(int detectionRange, LayerMask targetLayerMask)
{ {
base.InitializeEnemy(detectionRange, targetLayerMask); base.InitializeEnemy(detectionRange, targetLayerMask);
_rigidbody = GetComponent<Rigidbody>(); _rigidbody = GetComponent<Rigidbody>();
} }
/// <summary>
/// Updates the Slime's movement behavior.
/// Moves the Slime towards its target if a target is detected.
/// </summary>
private void Update() private void Update()
{ {
if (Target) if (Target)
......
using System.Collections;
using Unity.Netcode;
using UnityEngine;
public class EnemySpawnerManager : NetworkBehaviour
{
[SerializeField] private GameObject _rogueEnemyPrefab;
[SerializeField] private GameObject _slimeEnemyPrefab;
private Transform[] _enemySpawnLocations;
#region EnemyConfig
private int _RougeEnemySpawnAmount;
private int _SlimeEnemySpawnAmount;
private float _RogueEnemySpawnCooldown;
private float _SlimeEnemySpawnCooldown;
#endregion
#region runtimeEnemyProperties
private float _RogueEnemySpawnTimer;
private float _SlimeEnemySpawnTimer;
private int _spawnedRogueEnemyCount;
private int _spawnedSlimeEnemyCount;
#endregion
void Start()
{
if (IsServer)
{
OnServerStarted();
}
}
private void OnServerStarted()
{
// ApplyExistingEnemyArrows();
FindEnemySpawnPositions();
FindEnemyConfig();
StartEnemySpawnTimers();
}
private void StartEnemySpawnTimers()
{
StartCoroutine(RogueSpawnTimerCoroutine());
StartCoroutine(SlimeSpawnTimerCoroutine());
}
private IEnumerator RogueSpawnTimerCoroutine()
{
while (_spawnedRogueEnemyCount < _RougeEnemySpawnAmount)
{
if (_RogueEnemySpawnTimer <= 0f)
{
var random = new Unity.Mathematics.Random((uint)System.DateTime.Now.Ticks);
Vector3 spawnPosition = GetSpawnPosition(_spawnedRogueEnemyCount);
spawnPosition += new Vector3(random.NextFloat(-5f, 5f), 0, random.NextFloat(-5f, 5f));
SpawnRogueEnemy(spawnPosition);
_spawnedRogueEnemyCount++;
_RogueEnemySpawnTimer = _RogueEnemySpawnCooldown;
}
_RogueEnemySpawnTimer -= Time.fixedDeltaTime; // Use Time.fixedDeltaTime for physics updates
yield return new WaitForFixedUpdate(); // Wait for the next physics update
}
}
private IEnumerator SlimeSpawnTimerCoroutine()
{
while (_spawnedSlimeEnemyCount < _SlimeEnemySpawnAmount)
{
if (_SlimeEnemySpawnTimer <= 0f)
{
var random = new Unity.Mathematics.Random((uint)System.DateTime.Now.Ticks);
Vector3 spawnPosition = GetSpawnPosition(_spawnedSlimeEnemyCount);
spawnPosition += new Vector3(random.NextFloat(-5f, 5f), 0, random.NextFloat(-5f, 5f));
SpawnSlimeEnemy(spawnPosition);
_spawnedSlimeEnemyCount++;
_SlimeEnemySpawnTimer = _SlimeEnemySpawnCooldown;
}
_SlimeEnemySpawnTimer -= Time.fixedDeltaTime; // Use Time.fixedDeltaTime for physics updates
yield return new WaitForFixedUpdate(); // Wait for the next physics update
}
}
private void SpawnRogueEnemy(Vector3 spawnPosition)
{
if (_rogueEnemyPrefab != null)
{
GameObject spawnedEnemy =
Instantiate(_rogueEnemyPrefab, spawnPosition, Quaternion.identity, gameObject.transform);
spawnedEnemy.GetComponent<NetworkObject>().Spawn();
TargetingManager.Instance.AddEnemyToTargetingList(spawnedEnemy.GetComponent<Enemy>());
}
}
private void SpawnSlimeEnemy(Vector3 spawnPosition)
{
if (_slimeEnemyPrefab != null)
{
GameObject spawnedEnemy =
Instantiate(_slimeEnemyPrefab, spawnPosition, Quaternion.identity, gameObject.transform);
spawnedEnemy.GetComponent<NetworkObject>().Spawn();
TargetingManager.Instance.AddEnemyToTargetingList(spawnedEnemy.GetComponent<Enemy>());
}
}
private Vector3 GetSpawnPosition(int spawnedCount)
{
int index = spawnedCount % _enemySpawnLocations.Length;
return _enemySpawnLocations[index].position;
}
private void FindEnemyConfig()
{
_RougeEnemySpawnAmount = GameDataConfig.Instance.RogueEnemyAmount;
_SlimeEnemySpawnAmount = GameDataConfig.Instance.SlimeEnemyAmount;
_RogueEnemySpawnCooldown = GameDataConfig.Instance.RogueEnemySpawnTimer;
_SlimeEnemySpawnCooldown = GameDataConfig.Instance.SlimeEnemySpawnTimer;
_RogueEnemySpawnTimer = _RogueEnemySpawnCooldown;
_SlimeEnemySpawnTimer = _SlimeEnemySpawnCooldown;
}
private void FindEnemySpawnPositions()
{
GameObject spawnLocationParent = GameObject.Find("EnemySpawnLocations");
if (spawnLocationParent == null)
{
Debug.LogError("Could not find GameObject named 'EnemySpawnLocations'!");
return;
}
_enemySpawnLocations = new Transform[spawnLocationParent.transform.childCount];
for (int i = 0; i < spawnLocationParent.transform.childCount; i++)
{
_enemySpawnLocations[i] = spawnLocationParent.transform.GetChild(i);
}
Vector3[] spawnPositions = new Vector3[_enemySpawnLocations.Length];
for (int i = 0; i < _enemySpawnLocations.Length; i++)
{
spawnPositions[i] = _enemySpawnLocations[i].position;
}
}
}
\ No newline at end of file
...@@ -10,46 +10,164 @@ using UnityEngine.Rendering; ...@@ -10,46 +10,164 @@ using UnityEngine.Rendering;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI; using UnityEngine.UI;
/// <summary>
/// Manages the connection process for a multiplayer game, including server and client setup,
/// player spawning, and game start countdown.
/// </summary>
public class ConnectionManager : NetworkBehaviour public class ConnectionManager : NetworkBehaviour
{ {
#region UIGameObjectReferences
/// <summary>
/// Panel displayed while waiting for players to join.
/// </summary>
[SerializeField] private GameObject _WaitingPlayerPanel; [SerializeField] private GameObject _WaitingPlayerPanel;
/// <summary>
/// Text displaying the number of players needed to start.
/// </summary>
[SerializeField] private TextMeshProUGUI _waitingText; [SerializeField] private TextMeshProUGUI _waitingText;
//[SerializeField] private GameObject _confirmQuitPanel; /// <summary>
/// Panel displayed during the game start countdown.
/// </summary>
[SerializeField] private GameObject _countdownPanel; [SerializeField] private GameObject _countdownPanel;
/// <summary>
/// Text displaying the countdown timer.
/// </summary>
[SerializeField] private TextMeshProUGUI _countdownText; [SerializeField] private TextMeshProUGUI _countdownText;
/// <summary>
/// Panel for connection settings.
/// </summary>
[SerializeField] private GameObject _connectionPanel; [SerializeField] private GameObject _connectionPanel;
/// <summary>
/// Input field for the server address.
/// </summary>
[SerializeField] private TMP_InputField _addressField; [SerializeField] private TMP_InputField _addressField;
/// <summary>
/// Input field for the server port.
/// </summary>
[SerializeField] private TMP_InputField _portField; [SerializeField] private TMP_InputField _portField;
/// <summary>
/// Dropdown to select connection mode (host/client).
/// </summary>
[SerializeField] private TMP_Dropdown _connectionModeDropdown; [SerializeField] private TMP_Dropdown _connectionModeDropdown;
/// <summary>
/// Input field for the number of players.
/// </summary>
[SerializeField] private TMP_InputField _playerAmountField; [SerializeField] private TMP_InputField _playerAmountField;
/// <summary>
/// Input field for the number of Rogue enemies.
/// </summary>
[SerializeField] private TMP_InputField _RogueEnemyAmountField; [SerializeField] private TMP_InputField _RogueEnemyAmountField;
/// <summary>
/// Input field for the number of Slime enemies.
/// </summary>
[SerializeField] private TMP_InputField _SlimeEnemyAmountField; [SerializeField] private TMP_InputField _SlimeEnemyAmountField;
/// <summary>
/// UI container for lobby-related settings.
/// </summary>
[SerializeField] private GameObject LobbyAmountContainer; [SerializeField] private GameObject LobbyAmountContainer;
/// <summary>
/// UI container for Ranger enemy settings.
/// </summary>
[SerializeField] private GameObject RangerAmountContainer; [SerializeField] private GameObject RangerAmountContainer;
/// <summary>
/// UI container for Slime enemy settings.
/// </summary>
[SerializeField] private GameObject SlimeAmountContainer; [SerializeField] private GameObject SlimeAmountContainer;
/// <summary>
/// Button to initiate the connection process.
/// </summary>
[SerializeField] private Button _connectButton; [SerializeField] private Button _connectButton;
[SerializeField] private int _gameStartCountDownTime;
/// <summary>
/// Cooldown time for spawning Slime enemies.
/// </summary>
[SerializeField] private float _slimeSpawnCooldownTime; [SerializeField] private float _slimeSpawnCooldownTime;
/// <summary>
/// Cooldown time for spawning Rogue enemies.
/// </summary>
[SerializeField] private float _rogueSpawnCooldownTime; [SerializeField] private float _rogueSpawnCooldownTime;
[SerializeField] private GameObject playerPrefab;
[SerializeField] private int playerHealth;
/// <summary>
/// Default countdown timer value.
/// </summary>
[SerializeField] private int _startGameCountdownTimer = 10; [SerializeField] private int _startGameCountdownTimer = 10;
/// <summary>
/// Prefab for player objects.
/// </summary>
[SerializeField] private GameObject playerPrefab;
/// <summary>
/// Initial health for players.
/// </summary>
[SerializeField] private int playerHealth;
/// <summary>
/// Temporary object to hold game configuration data.
/// </summary>
private GameObject gameConfigHolder; private GameObject gameConfigHolder;
private List<ulong> connectedClientIds = new List<ulong>(); // Use a List for dynamic size /// <summary>
/// List of connected client IDs.
/// </summary>
private List<ulong> connectedClientIds = new List<ulong>();
/// <summary>
/// Port number parsed from the input field.
/// </summary>
private ushort Port => ushort.Parse(_portField.text); private ushort Port => ushort.Parse(_portField.text);
/// <summary>
/// Number of players parsed from the input field.
/// </summary>
private int PlayerAmount => int.Parse(_playerAmountField.text); private int PlayerAmount => int.Parse(_playerAmountField.text);
/// <summary>
/// Number of Rogue enemies parsed from the input field.
/// </summary>
private int RogueEnemyAmount => int.Parse(_RogueEnemyAmountField.text); private int RogueEnemyAmount => int.Parse(_RogueEnemyAmountField.text);
/// <summary>
/// Number of Slime enemies parsed from the input field.
/// </summary>
private int SlimeEnemyAmount => int.Parse(_SlimeEnemyAmountField.text); private int SlimeEnemyAmount => int.Parse(_SlimeEnemyAmountField.text);
/// <summary>
/// Server address parsed from the input field.
/// </summary>
private string Address => _addressField.text; private string Address => _addressField.text;
/// <summary>
/// Indicates whether the game start timer is running.
/// </summary>
private bool _timerRunning = false; private bool _timerRunning = false;
/// <summary>
/// Countdown timer value on the server.
/// </summary>
private int _serverCountdown; private int _serverCountdown;
#endregion
/// <summary>
/// Subscribes to UI events when the object is enabled.
/// </summary>
private void OnEnable() private void OnEnable()
{ {
_connectionModeDropdown.onValueChanged.AddListener(OnConnectionModeChanged); _connectionModeDropdown.onValueChanged.AddListener(OnConnectionModeChanged);
...@@ -57,12 +175,19 @@ public class ConnectionManager : NetworkBehaviour ...@@ -57,12 +175,19 @@ public class ConnectionManager : NetworkBehaviour
OnConnectionModeChanged(_connectionModeDropdown.value); OnConnectionModeChanged(_connectionModeDropdown.value);
} }
/// <summary>
/// Unsubscribes from UI events when the object is disabled.
/// </summary>
private void OnDisable() private void OnDisable()
{ {
_connectionModeDropdown.onValueChanged.RemoveAllListeners(); _connectionModeDropdown.onValueChanged.RemoveAllListeners();
_connectButton.onClick.RemoveAllListeners(); _connectButton.onClick.RemoveAllListeners();
} }
/// <summary>
/// Updates the UI based on the selected connection mode (host or client).
/// </summary>
/// <param name="connectionMode">The selected connection mode.</param>
private void OnConnectionModeChanged(int connectionMode) private void OnConnectionModeChanged(int connectionMode)
{ {
string buttonLabel; string buttonLabel;
...@@ -92,7 +217,9 @@ public class ConnectionManager : NetworkBehaviour ...@@ -92,7 +217,9 @@ public class ConnectionManager : NetworkBehaviour
buttonText.text = buttonLabel; buttonText.text = buttonLabel;
} }
/// <summary>
/// Handles the connection button click event and starts the host or client based on the selected mode.
/// </summary>
private void OnButtonConnect() private void OnButtonConnect()
{ {
_connectionPanel.SetActive(false); _connectionPanel.SetActive(false);
...@@ -112,17 +239,22 @@ public class ConnectionManager : NetworkBehaviour ...@@ -112,17 +239,22 @@ public class ConnectionManager : NetworkBehaviour
} }
} }
/// <summary>
/// Sets up the game configuration by creating a temporary object to hold enemy amounts.
/// </summary>
private void SetupGameConfig() private void SetupGameConfig()
{ {
gameConfigHolder = new GameObject("GameConfigHolder"); gameConfigHolder = new GameObject("GameConfigHolder");
GameDataConfig configComponent = gameConfigHolder.AddComponent<GameDataConfig>(); GameDataConfig configComponent = gameConfigHolder.AddComponent<GameDataConfig>();
configComponent.RogueEnemyAmount = RogueEnemyAmount; configComponent.RogueEnemyAmount = RogueEnemyAmount;
configComponent.SlimeEnemyAmount = SlimeEnemyAmount; configComponent.SlimeEnemyAmount = SlimeEnemyAmount;
configComponent.SlimeEnemySpawnTimer = _slimeSpawnCooldownTime;
// SceneManager.MoveGameObjectToScene(gameConfigHolder, targetScene); configComponent.RogueEnemySpawnTimer = _rogueSpawnCooldownTime;
} }
/// <summary>
/// Starts the server and sets up the host connection.
/// </summary>
private void StartServer() private void StartServer()
{ {
NetworkManager.Singleton.GetComponent<UnityTransport>().SetConnectionData(Address, Port); NetworkManager.Singleton.GetComponent<UnityTransport>().SetConnectionData(Address, Port);
...@@ -132,7 +264,11 @@ public class ConnectionManager : NetworkBehaviour ...@@ -132,7 +264,11 @@ public class ConnectionManager : NetworkBehaviour
CheckConnectedClientAmount(); CheckConnectedClientAmount();
} }
/// <summary>
/// Handles network connection events such as client connections and disconnections.
/// </summary>
/// <param name="networkManager">The NetworkManager instance.</param>
/// <param name="connectionEvent">The connection event data.</param>
private void OnNetworkConnectionEvent(NetworkManager networkManager, ConnectionEventData connectionEvent) private void OnNetworkConnectionEvent(NetworkManager networkManager, ConnectionEventData connectionEvent)
{ {
if (IsServer) if (IsServer)
...@@ -142,7 +278,6 @@ public class ConnectionManager : NetworkBehaviour ...@@ -142,7 +278,6 @@ public class ConnectionManager : NetworkBehaviour
Debug.Log($"Client connected with ID: {connectionEvent.ClientId}"); Debug.Log($"Client connected with ID: {connectionEvent.ClientId}");
connectedClientIds.Add(connectionEvent.ClientId); connectedClientIds.Add(connectionEvent.ClientId);
Debug.Log($"Connected Client Count: {connectedClientIds.Count}"); Debug.Log($"Connected Client Count: {connectedClientIds.Count}");
// Update your UI here based on connectedClientIds.Count
} }
else if (connectionEvent.EventType == ConnectionEvent.ClientDisconnected) else if (connectionEvent.EventType == ConnectionEvent.ClientDisconnected)
{ {
...@@ -155,7 +290,9 @@ public class ConnectionManager : NetworkBehaviour ...@@ -155,7 +290,9 @@ public class ConnectionManager : NetworkBehaviour
} }
} }
//must be executed only by the server /// <summary>
/// Checks the number of connected clients and starts the game if the required number is met.
/// </summary>
private void CheckConnectedClientAmount() private void CheckConnectedClientAmount()
{ {
if (connectedClientIds.Count >= PlayerAmount && !_timerRunning) if (connectedClientIds.Count >= PlayerAmount && !_timerRunning)
...@@ -168,16 +305,19 @@ public class ConnectionManager : NetworkBehaviour ...@@ -168,16 +305,19 @@ public class ConnectionManager : NetworkBehaviour
} }
} }
//must be executed only by the server /// <summary>
/// Begins the game start countdown and notifies clients.
/// </summary>
private void BeginGameStart() private void BeginGameStart()
{ {
_serverCountdown = _startGameCountdownTimer; _serverCountdown = _startGameCountdownTimer;
StartCoroutine(StartGameTimer()); StartCoroutine(StartGameTimer());
BeginGameStartClientRpc(_serverCountdown); // Initial notification BeginGameStartClientRpc(_serverCountdown);
} }
//must be executed only by the server /// <summary>
/// Starts the game countdown timer on the server.
/// </summary>
private IEnumerator StartGameTimer() private IEnumerator StartGameTimer()
{ {
_timerRunning = true; _timerRunning = true;
...@@ -187,38 +327,49 @@ public class ConnectionManager : NetworkBehaviour ...@@ -187,38 +327,49 @@ public class ConnectionManager : NetworkBehaviour
{ {
yield return new WaitForSeconds(1f); yield return new WaitForSeconds(1f);
_serverCountdown--; _serverCountdown--;
UpdateCountdownClientRpc(_serverCountdown); // Update clients with the current value UpdateCountdownClientRpc(_serverCountdown);
} }
UnloadSceneClientRpc("ConnectionScene"); UnloadSceneClientRpc("ConnectionScene");
SpawnPlayers(); SpawnPlayers();
InvokeDestroyGameObjectClientRpc(); EnemySpawnerManager.Instance.StartEnemySpawnTimers();
Destroy(gameObject); gameObject.GetComponent<NetworkObject>().Despawn();
}
[ClientRpc]
private void InvokeDestroyGameObjectClientRpc()
{
Destroy(gameObject);
} }
/// <summary>
/// Unloads the specified scene on all clients.
/// </summary>
/// <param name="sceneName">The name of the scene to unload.</param>
[ClientRpc] [ClientRpc]
private void UnloadSceneClientRpc(string sceneName) private void UnloadSceneClientRpc(string sceneName)
{ {
SceneManager.UnloadSceneAsync(sceneName); SceneManager.UnloadSceneAsync(sceneName);
} }
/// <summary>
/// Closes the game start panel.
/// </summary>
private void CloseGameStartPanel() private void CloseGameStartPanel()
{ {
_countdownPanel.SetActive(false); _countdownPanel.SetActive(false);
} }
/// <summary>
/// Prepares the server to load the game scene asynchronously.
/// </summary>
private void PrepareGameLoadSceneForServerAsync() private void PrepareGameLoadSceneForServerAsync()
{ {
NetworkManager.Singleton.SceneManager.LoadScene("TestScene", LoadSceneMode.Additive); NetworkManager.Singleton.SceneManager.LoadScene("SC", LoadSceneMode.Additive);
NetworkManager.Singleton.SceneManager.OnLoadEventCompleted += OnSceneLoadCompleted; NetworkManager.Singleton.SceneManager.OnLoadEventCompleted += OnSceneLoadCompleted;
} }
/// <summary>
/// Handles the completion of the scene load event.
/// </summary>
/// <param name="scenename">The name of the loaded scene.</param>
/// <param name="loadscenemode">The mode in which the scene was loaded.</param>
/// <param name="clientscompleted">List of clients that completed the load.</param>
/// <param name="clientstimedout">List of clients that timed out during the load.</param>
private void OnSceneLoadCompleted(string scenename, LoadSceneMode loadscenemode, List<ulong> clientscompleted, private void OnSceneLoadCompleted(string scenename, LoadSceneMode loadscenemode, List<ulong> clientscompleted,
List<ulong> clientstimedout) List<ulong> clientstimedout)
{ {
...@@ -229,7 +380,10 @@ public class ConnectionManager : NetworkBehaviour ...@@ -229,7 +380,10 @@ public class ConnectionManager : NetworkBehaviour
MoveNetworkManagerToNewSceneClientRpc(scenename); MoveNetworkManagerToNewSceneClientRpc(scenename);
} }
/// <summary>
/// Moves the NetworkManager to the new scene on all clients.
/// </summary>
/// <param name="scenename">The name of the new scene.</param>
[ClientRpc] [ClientRpc]
private void MoveNetworkManagerToNewSceneClientRpc(string scenename) private void MoveNetworkManagerToNewSceneClientRpc(string scenename)
{ {
...@@ -238,7 +392,12 @@ public class ConnectionManager : NetworkBehaviour ...@@ -238,7 +392,12 @@ public class ConnectionManager : NetworkBehaviour
SceneManager.SetActiveScene(scene); SceneManager.SetActiveScene(scene);
} }
/// <summary>
/// Checks the completion status of the scene load for all clients.
/// </summary>
/// <param name="initialConnectedClientIds">List of initially connected client IDs.</param>
/// <param name="clientsCompleted">List of clients that completed the load.</param>
/// <param name="clientsTimedOut">List of clients that timed out during the load.</param>
private void CheckSceneLoadCompletion(List<ulong> initialConnectedClientIds, List<ulong> clientsCompleted, private void CheckSceneLoadCompletion(List<ulong> initialConnectedClientIds, List<ulong> clientsCompleted,
List<ulong> clientsTimedOut) List<ulong> clientsTimedOut)
{ {
...@@ -260,7 +419,10 @@ public class ConnectionManager : NetworkBehaviour ...@@ -260,7 +419,10 @@ public class ConnectionManager : NetworkBehaviour
} }
} }
/// <summary>
/// Notifies clients to begin the game start countdown.
/// </summary>
/// <param name="initialCountdownValue">The initial countdown value.</param>
[ClientRpc] [ClientRpc]
private void BeginGameStartClientRpc(int initialCountdownValue) private void BeginGameStartClientRpc(int initialCountdownValue)
{ {
...@@ -269,7 +431,10 @@ public class ConnectionManager : NetworkBehaviour ...@@ -269,7 +431,10 @@ public class ConnectionManager : NetworkBehaviour
_countdownText.text = initialCountdownValue.ToString(); _countdownText.text = initialCountdownValue.ToString();
} }
/// <summary>
/// Updates the remaining player count text on all clients.
/// </summary>
/// <param name="remainingPlayers">The number of players still needed to start the game.</param>
[ClientRpc] [ClientRpc]
private void UpdatePlayerRemainingTextClientRpc(int remainingPlayers) private void UpdatePlayerRemainingTextClientRpc(int remainingPlayers)
{ {
...@@ -277,19 +442,28 @@ public class ConnectionManager : NetworkBehaviour ...@@ -277,19 +442,28 @@ public class ConnectionManager : NetworkBehaviour
_waitingText.text = $"Waiting for {remainingPlayers} more {playersText} to join..."; _waitingText.text = $"Waiting for {remainingPlayers} more {playersText} to join...";
} }
/// <summary>
/// Updates the countdown timer text on all clients.
/// </summary>
/// <param name="currentCountdownValue">The current countdown value.</param>
[ClientRpc] [ClientRpc]
private void UpdateCountdownClientRpc(int currentCountdownValue) private void UpdateCountdownClientRpc(int currentCountdownValue)
{ {
_countdownText.text = currentCountdownValue.ToString(); _countdownText.text = currentCountdownValue.ToString();
} }
/// <summary>
/// Opens the countdown panel on all clients.
/// </summary>
[ClientRpc] [ClientRpc]
private void OpenCountDownPanelClientRpc() private void OpenCountDownPanelClientRpc()
{ {
CloseGameStartPanel(); CloseGameStartPanel();
} }
/// <summary>
/// Spawns player objects for all connected clients.
/// </summary>
private void SpawnPlayers() private void SpawnPlayers()
{ {
foreach (ulong clientId in connectedClientIds) foreach (ulong clientId in connectedClientIds)
...@@ -313,6 +487,9 @@ public class ConnectionManager : NetworkBehaviour ...@@ -313,6 +487,9 @@ public class ConnectionManager : NetworkBehaviour
} }
} }
/// <summary>
/// Starts the client and connects to the server.
/// </summary>
private void StartClient() private void StartClient()
{ {
UnityTransport transport = NetworkManager.Singleton.GetComponent<UnityTransport>(); UnityTransport transport = NetworkManager.Singleton.GetComponent<UnityTransport>();
...@@ -326,6 +503,4 @@ public class ConnectionManager : NetworkBehaviour ...@@ -326,6 +503,4 @@ public class ConnectionManager : NetworkBehaviour
Debug.LogError("Unity Transport component not found on the NetworkManager!"); Debug.LogError("Unity Transport component not found on the NetworkManager!");
} }
} }
} }
// would be ideal to reject connections if the game has already started but unity does not have a way to do this \ No newline at end of file
// one way would be rejecting the connections in the OnNetworkConnectionEvent method or setting strange values in server connection data
\ No newline at end of file
using UnityEngine;
/// <summary>
/// Manages enemy-related functionality in the game, including initializing enemy events.
/// </summary>
public class EnemyManager : MonoBehaviour
{
/// <summary>
/// Handles events related to enemy actions such as attacking, aiming, and reloading.
/// </summary>
public EnemyEvents enemyEvents;
/// <summary>
/// Initializes the EnemyManager by creating a new instance of EnemyEvents.
/// </summary>
public void Initialize()
{
enemyEvents = new EnemyEvents();
}
}
\ No newline at end of file
fileFormatVersion: 2 fileFormatVersion: 2
guid: cb139732cb33148458fab05d76c66791 guid: 6b51ffc7252b86b43a0b4806229fd39d
\ No newline at end of file \ No newline at end of file
using System.Collections;
using Unity.Netcode;
using UnityEngine; using UnityEngine;
public class EnemyManager : MonoBehaviour /// <summary>
/// Manages the spawning of enemies in the game, including Rogue and Slime enemies.
/// Handles spawn timers, spawn locations, and enemy instantiation.
/// </summary>
public class EnemySpawnerManager : NetworkBehaviour
{ {
public EnemyEvents enemyEvents; /// <summary>
/// Singleton instance of the EnemySpawnerManager.
/// </summary>
public static EnemySpawnerManager Instance { get; private set; }
public void Initialize() [SerializeField] private GameObject _rogueEnemyPrefab; // Prefab for Rogue enemies.
[SerializeField] private GameObject _slimeEnemyPrefab; // Prefab for Slime enemies.
private Transform[] _enemySpawnLocations; // Array of spawn locations for enemies.
#region EnemyConfig
private int _RougeEnemySpawnAmount; // Total number of Rogue enemies to spawn.
private int _SlimeEnemySpawnAmount; // Total number of Slime enemies to spawn.
private float _RogueEnemySpawnCooldown; // Cooldown time between Rogue enemy spawns.
private float _SlimeEnemySpawnCooldown; // Cooldown time between Slime enemy spawns.
#endregion
#region runtimeEnemyProperties
private float _RogueEnemySpawnTimer; // Timer for Rogue enemy spawning.
private float _SlimeEnemySpawnTimer; // Timer for Slime enemy spawning.
private int _spawnedRogueEnemyCount; // Count of spawned Rogue enemies.
private int _spawnedSlimeEnemyCount; // Count of spawned Slime enemies.
#endregion
/// <summary>
/// Ensures only one instance of EnemySpawnerManager exists and persists across scenes.
/// </summary>
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
/// <summary>
/// Initializes the server-specific logic when the game starts.
/// </summary>
private void Start()
{
if (IsServer)
{
OnServerStarted();
}
}
/// <summary>
/// Sets up enemy spawn positions and configurations when the server starts.
/// </summary>
private void OnServerStarted()
{ {
enemyEvents = new EnemyEvents(); FindEnemySpawnPositions();
FindEnemyConfig();
}
/// <summary>
/// Starts the spawn timers for Rogue and Slime enemies.
/// </summary>
public void StartEnemySpawnTimers()
{
StartCoroutine(RogueSpawnTimerCoroutine());
StartCoroutine(SlimeSpawnTimerCoroutine());
}
/// <summary>
/// Coroutine to handle Rogue enemy spawning based on the spawn timer.
/// </summary>
private IEnumerator RogueSpawnTimerCoroutine()
{
while (_spawnedRogueEnemyCount < _RougeEnemySpawnAmount)
{
if (_RogueEnemySpawnTimer <= 0f)
{
var random = new Unity.Mathematics.Random((uint)System.DateTime.Now.Ticks);
Vector3 spawnPosition = GetSpawnPosition(_spawnedRogueEnemyCount);
spawnPosition += new Vector3(random.NextFloat(-5f, 5f), 0, random.NextFloat(-5f, 5f));
SpawnRogueEnemy(spawnPosition);
_spawnedRogueEnemyCount++;
_RogueEnemySpawnTimer = _RogueEnemySpawnCooldown;
}
_RogueEnemySpawnTimer -= Time.fixedDeltaTime;
yield return new WaitForFixedUpdate();
}
}
/// <summary>
/// Coroutine to handle Slime enemy spawning based on the spawn timer.
/// </summary>
private IEnumerator SlimeSpawnTimerCoroutine()
{
while (_spawnedSlimeEnemyCount < _SlimeEnemySpawnAmount)
{
if (_SlimeEnemySpawnTimer <= 0f)
{
var random = new Unity.Mathematics.Random((uint)System.DateTime.Now.Ticks);
Vector3 spawnPosition = GetSpawnPosition(_spawnedSlimeEnemyCount);
spawnPosition += new Vector3(random.NextFloat(-5f, 5f), 0, random.NextFloat(-5f, 5f));
SpawnSlimeEnemy(spawnPosition);
_spawnedSlimeEnemyCount++;
_SlimeEnemySpawnTimer = _SlimeEnemySpawnCooldown;
}
_SlimeEnemySpawnTimer -= Time.fixedDeltaTime;
yield return new WaitForFixedUpdate();
}
}
/// <summary>
/// Spawns a Rogue enemy at the specified position.
/// </summary>
/// <param name="spawnPosition">The position to spawn the Rogue enemy.</param>
private void SpawnRogueEnemy(Vector3 spawnPosition)
{
if (_rogueEnemyPrefab != null)
{
GameObject spawnedEnemy =
Instantiate(_rogueEnemyPrefab, spawnPosition, Quaternion.identity, gameObject.transform);
spawnedEnemy.GetComponent<NetworkObject>().Spawn();
TargetingManager.Instance.AddEnemyToTargetingList(spawnedEnemy.GetComponent<Enemy>());
}
}
/// <summary>
/// Spawns a Slime enemy at the specified position.
/// </summary>
/// <param name="spawnPosition">The position to spawn the Slime enemy.</param>
private void SpawnSlimeEnemy(Vector3 spawnPosition)
{
if (_slimeEnemyPrefab != null)
{
GameObject spawnedEnemy =
Instantiate(_slimeEnemyPrefab, spawnPosition, Quaternion.identity, gameObject.transform);
spawnedEnemy.GetComponent<NetworkObject>().Spawn();
TargetingManager.Instance.AddEnemyToTargetingList(spawnedEnemy.GetComponent<Enemy>());
}
}
/// <summary>
/// Gets the spawn position for an enemy based on the spawn count.
/// </summary>
/// <param name="spawnedCount">The number of enemies already spawned.</param>
/// <returns>The spawn position for the next enemy.</returns>
private Vector3 GetSpawnPosition(int spawnedCount)
{
int index = spawnedCount % _enemySpawnLocations.Length;
return _enemySpawnLocations[index].position;
}
/// <summary>
/// Retrieves enemy configuration data from the game configuration.
/// </summary>
private void FindEnemyConfig()
{
_RougeEnemySpawnAmount = GameDataConfig.Instance.RogueEnemyAmount;
_SlimeEnemySpawnAmount = GameDataConfig.Instance.SlimeEnemyAmount;
_RogueEnemySpawnCooldown = GameDataConfig.Instance.RogueEnemySpawnTimer;
_SlimeEnemySpawnCooldown = GameDataConfig.Instance.SlimeEnemySpawnTimer;
_RogueEnemySpawnTimer = _RogueEnemySpawnCooldown;
_SlimeEnemySpawnTimer = _SlimeEnemySpawnCooldown;
}
/// <summary>
/// Finds and stores enemy spawn locations from the scene.
/// </summary>
private void FindEnemySpawnPositions()
{
GameObject spawnLocationParent = GameObject.Find("EnemySpawnLocations");
if (spawnLocationParent == null)
{
Debug.LogError("Could not find GameObject named 'EnemySpawnLocations'!");
return;
}
_enemySpawnLocations = new Transform[spawnLocationParent.transform.childCount];
for (int i = 0; i < spawnLocationParent.transform.childCount; i++)
{
_enemySpawnLocations[i] = spawnLocationParent.transform.GetChild(i);
}
} }
} }
\ No newline at end of file
fileFormatVersion: 2 fileFormatVersion: 2
guid: 6b51ffc7252b86b43a0b4806229fd39d guid: cb139732cb33148458fab05d76c66791
\ No newline at end of file \ No newline at end of file
using System; using System;
/// <summary>
/// Manages events related to enemy actions such as attacking, aiming, and reloading.
/// Provides methods to trigger these events and allows other components to subscribe to them.
/// </summary>
public class EnemyEvents public class EnemyEvents
{ {
/// <summary>
/// Event triggered when an enemy performs an attack.
/// </summary>
public event Action onEnemyAttack; public event Action onEnemyAttack;
/// <summary>
/// Event triggered when an enemy starts aiming.
/// </summary>
public event Action onEnemyAim; public event Action onEnemyAim;
/// <summary>
/// Event triggered when an enemy reloads its weapon.
/// </summary>
public event Action onEnemyReload; public event Action onEnemyReload;
/// <summary>
/// Triggers the onEnemyAttack event to notify subscribers that an enemy has attacked.
/// </summary>
public void EnemyAttack() public void EnemyAttack()
{ {
if (onEnemyAttack != null) if (onEnemyAttack != null)
...@@ -14,6 +32,9 @@ public class EnemyEvents ...@@ -14,6 +32,9 @@ public class EnemyEvents
} }
} }
/// <summary>
/// Triggers the onEnemyAim event to notify subscribers that an enemy has started aiming.
/// </summary>
public void EnemyAim() public void EnemyAim()
{ {
if (onEnemyAim != null) if (onEnemyAim != null)
...@@ -22,6 +43,9 @@ public class EnemyEvents ...@@ -22,6 +43,9 @@ public class EnemyEvents
} }
} }
/// <summary>
/// Triggers the onEnemyReload event to notify subscribers that an enemy has reloaded its weapon.
/// </summary>
public void EnemyReload() public void EnemyReload()
{ {
if (onEnemyReload != null) if (onEnemyReload != null)
......
using System; using System;
/// <summary>
/// Manages events related to player actions such as walking, running, defending, interacting, and attacking.
/// Provides methods to trigger these events and allows other components to subscribe to them.
/// </summary>
public class PlayerEvents public class PlayerEvents
{ {
/// <summary>
/// Event triggered when the player starts or stops walking.
/// The boolean parameter indicates whether the player is walking (true) or not (false).
/// </summary>
public event Action<bool> onPlayerWalk; public event Action<bool> onPlayerWalk;
/// <summary>
/// Event triggered when the player starts or stops running.
/// The boolean parameter indicates whether the player is running (true) or not (false).
/// </summary>
public event Action<bool> onPlayerRun; public event Action<bool> onPlayerRun;
/// <summary>
/// Event triggered when the player starts or stops defending.
/// The boolean parameter indicates whether the player is defending (true) or not (false).
/// </summary>
public event Action<bool> onPlayerDefence; public event Action<bool> onPlayerDefence;
/// <summary>
/// Event triggered when the player interacts with an object.
/// </summary>
public event Action onPlayerInteract; public event Action onPlayerInteract;
public event Action onPlayerAttack;
/// <summary>
/// Event triggered when the player performs an attack.
/// </summary>
public event Action onPlayerAttack;
/// <summary>
/// Triggers the onPlayerDefence event to notify subscribers that the player has started or stopped defending.
/// </summary>
/// <param name="state">Indicates whether the player is defending (true) or not (false).</param>
public void PlayerDefence(bool state) public void PlayerDefence(bool state)
{ {
if (onPlayerDefence != null) if (onPlayerDefence != null)
...@@ -17,6 +46,10 @@ public class PlayerEvents ...@@ -17,6 +46,10 @@ public class PlayerEvents
} }
} }
/// <summary>
/// Triggers the onPlayerWalk event to notify subscribers that the player has started or stopped walking.
/// </summary>
/// <param name="state">Indicates whether the player is walking (true) or not (false).</param>
public void PlayerWalk(bool state) public void PlayerWalk(bool state)
{ {
if (onPlayerWalk != null) if (onPlayerWalk != null)
...@@ -25,6 +58,10 @@ public class PlayerEvents ...@@ -25,6 +58,10 @@ public class PlayerEvents
} }
} }
/// <summary>
/// Triggers the onPlayerRun event to notify subscribers that the player has started or stopped running.
/// </summary>
/// <param name="state">Indicates whether the player is running (true) or not (false).</param>
public void PlayerRun(bool state) public void PlayerRun(bool state)
{ {
if (onPlayerRun != null) if (onPlayerRun != null)
...@@ -33,6 +70,9 @@ public class PlayerEvents ...@@ -33,6 +70,9 @@ public class PlayerEvents
} }
} }
/// <summary>
/// Triggers the onPlayerInteract event to notify subscribers that the player has interacted with an object.
/// </summary>
public void PlayerInteract() public void PlayerInteract()
{ {
if (onPlayerInteract != null) if (onPlayerInteract != null)
...@@ -41,6 +81,9 @@ public class PlayerEvents ...@@ -41,6 +81,9 @@ public class PlayerEvents
} }
} }
/// <summary>
/// Triggers the onPlayerAttack event to notify subscribers that the player has performed an attack.
/// </summary>
public void PlayerAttack() public void PlayerAttack()
{ {
if (onPlayerAttack != null) if (onPlayerAttack != null)
......
...@@ -5,119 +5,119 @@ using UnityEngine; ...@@ -5,119 +5,119 @@ using UnityEngine;
public class GameManager : NetworkBehaviour public class GameManager : NetworkBehaviour
{ {
[SerializeField] private GameObject keyPrefab; // [SerializeField] private GameObject keyPrefab;
[SerializeField] private bool startGame; // [SerializeField] private bool startGame;
private TextMeshProUGUI _timerText; // private TextMeshProUGUI _timerText;
private float _initialTimer = 10f; // private float _initialTimer = 10f;
private float _startGameTimer = 10f; // private float _startGameTimer = 10f;
private bool _initialTimerActive = true; // private bool _initialTimerActive = true;
private bool _startGameTimerActive; // private bool _startGameTimerActive;
//
//
private void Start() // private void Start()
{ // {
_timerText = GameObject.Find("Start_Game").GetComponent<TextMeshProUGUI>(); // _timerText = GameObject.Find("Start_Game").GetComponent<TextMeshProUGUI>();
if (_timerText == null) // if (_timerText == null)
{ // {
Debug.LogError("TextMeshPro component not found on Start Game GameObject!"); // Debug.LogError("TextMeshPro component not found on Start Game GameObject!");
return; // return;
} // }
//
if (IsServer) // if (IsServer)
{ // {
// _initialTimerActive = startGame; // // _initialTimerActive = startGame;
} // }
//
_initialTimerActive = startGame; // _initialTimerActive = startGame;
} // }
//
private void Update() // private void Update()
{ // {
if (!IsServer) return; // if (!IsServer) return;
//
if (_initialTimerActive) // if (_initialTimerActive)
{ // {
_initialTimer -= Time.deltaTime; // _initialTimer -= Time.deltaTime;
if (_initialTimer <= 0) // if (_initialTimer <= 0)
{ // {
_initialTimerActive = false; // _initialTimerActive = false;
_startGameTimerActive = true; // _startGameTimerActive = true;
EnableTimerTextClientRpc(true); // EnableTimerTextClientRpc(true);
} // }
} // }
//
if (_startGameTimerActive) // if (_startGameTimerActive)
{ // {
_startGameTimer -= Time.deltaTime; // _startGameTimer -= Time.deltaTime;
if (_startGameTimer > 0) // if (_startGameTimer > 0)
{ // {
UpdateTimerClientRpc(_startGameTimer); // UpdateTimerClientRpc(_startGameTimer);
} // }
else // else
{ // {
_startGameTimerActive = false; // _startGameTimerActive = false;
UpdateTimerClientRpc(0); // UpdateTimerClientRpc(0);
EnableTimerTextClientRpc(false); // EnableTimerTextClientRpc(false);
TimersEndedServerRpc(); // TimersEndedServerRpc();
} // }
} // }
} // }
//
[ClientRpc] // [ClientRpc]
private void UpdateTimerClientRpc(float timeRemaining) // private void UpdateTimerClientRpc(float timeRemaining)
{ // {
if (_timerText != null) // if (_timerText != null)
{ // {
_timerText.text = $"Starting Game in {Mathf.Ceil(timeRemaining)}"; // _timerText.text = $"Starting Game in {Mathf.Ceil(timeRemaining)}";
} // }
} // }
//
[ClientRpc] // [ClientRpc]
private void EnableTimerTextClientRpc(bool state) // private void EnableTimerTextClientRpc(bool state)
{ // {
if (_timerText != null) // if (_timerText != null)
{ // {
_timerText.enabled = state; // _timerText.enabled = state;
} // }
} // }
//
[ServerRpc] // [ServerRpc]
private void TimersEndedServerRpc() // private void TimersEndedServerRpc()
{ // {
for (int i = 0; i < 2; i++) // for (int i = 0; i < 2; i++)
{ // {
Vector3 spawnPosition = new Vector3(10 + UnityEngine.Random.Range(-5f, 5f), 0, // Vector3 spawnPosition = new Vector3(10 + UnityEngine.Random.Range(-5f, 5f), 0,
10 + Random.Range(-5f, 5f)); // 10 + Random.Range(-5f, 5f));
GameObject obj = Instantiate(keyPrefab, spawnPosition, Quaternion.identity); // GameObject obj = Instantiate(keyPrefab, spawnPosition, Quaternion.identity);
obj.GetComponent<NetworkObject>().Spawn(); // obj.GetComponent<NetworkObject>().Spawn();
} // }
} // }
//
//
[ServerRpc(RequireOwnership = false)] // [ServerRpc(RequireOwnership = false)]
public void RequestTimerStateServerRpc(ServerRpcParams rpcParams = default) // public void RequestTimerStateServerRpc(ServerRpcParams rpcParams = default)
{ // {
if (_initialTimerActive) // if (_initialTimerActive)
{ // {
RespondTimerStateClientRpc(_initialTimer, true, rpcParams.Receive.SenderClientId); // RespondTimerStateClientRpc(_initialTimer, true, rpcParams.Receive.SenderClientId);
} // }
else if (_startGameTimerActive) // else if (_startGameTimerActive)
{ // {
RespondTimerStateClientRpc(_startGameTimer, true, rpcParams.Receive.SenderClientId); // RespondTimerStateClientRpc(_startGameTimer, true, rpcParams.Receive.SenderClientId);
} // }
else // else
{ // {
RespondTimerStateClientRpc(0, false, rpcParams.Receive.SenderClientId); // RespondTimerStateClientRpc(0, false, rpcParams.Receive.SenderClientId);
} // }
} // }
//
[ClientRpc] // [ClientRpc]
private void RespondTimerStateClientRpc(float timeRemaining, bool timerActive, ulong clientId) // private void RespondTimerStateClientRpc(float timeRemaining, bool timerActive, ulong clientId)
{ // {
if (NetworkManager.Singleton.LocalClientId == clientId) // if (NetworkManager.Singleton.LocalClientId == clientId)
{ // {
_timerText.enabled = timerActive; // _timerText.enabled = timerActive;
_timerText.text = $"Starting Game in {Mathf.Ceil(timeRemaining)}"; // _timerText.text = $"Starting Game in {Mathf.Ceil(timeRemaining)}";
} // }
} // }
} }
\ No newline at end of file
using UnityEngine; using UnityEngine;
/// <summary>
/// Manages player-related functionality, including input handling and player events.
/// </summary>
public class PlayerManager : MonoBehaviour public class PlayerManager : MonoBehaviour
{ {
/// <summary>
/// Handles player input and provides input data to other systems.
/// </summary>
public InputReader inputReader; public InputReader inputReader;
/// <summary>
/// Handles events related to player actions such as movement, interaction, and combat.
/// </summary>
public PlayerEvents playerEvents; public PlayerEvents playerEvents;
/// <summary>
/// Initializes the PlayerManager by setting up input handling and player events.
/// </summary>
public void Initialize() public void Initialize()
{ {
inputReader.InitializeInput(); inputReader.InitializeInput();
......
...@@ -5,18 +5,23 @@ using TMPro; ...@@ -5,18 +5,23 @@ using TMPro;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Manages the respawn process for players, including UI updates, countdowns, and player reinitialization.
/// </summary>
public class RespawnManager : NetworkBehaviour public class RespawnManager : NetworkBehaviour
{ {
[SerializeField] private GameObject _respawnPlayerPanel; [SerializeField] private GameObject _respawnPlayerPanel; // UI panel displayed during respawn countdown.
[SerializeField] private TextMeshProUGUI _countdownTimeText; [SerializeField] private TextMeshProUGUI _countdownTimeText; // Text element for displaying countdown time.
[SerializeField] private int _playerDeadLayer = 11; [SerializeField] private int _playerDeadLayer = 11; // Layer assigned to players during respawn.
public static RespawnManager Instance { get; private set; } public static RespawnManager Instance { get; private set; } // Singleton instance of the RespawnManager.
private int _respawnTime = 10; private int _respawnTime = 10; // Time (in seconds) for the respawn countdown.
private int _health = 100; private int _health = 100; // Initial health value for respawned players.
private Coroutine _countdownCoroutine; private Coroutine _countdownCoroutine; // Reference to the active countdown coroutine.
/// <summary>
/// Ensures only one instance of RespawnManager exists and persists across scenes.
/// </summary>
private void Awake() private void Awake()
{ {
if (Instance == null) if (Instance == null)
...@@ -29,6 +34,10 @@ public class RespawnManager : NetworkBehaviour ...@@ -29,6 +34,10 @@ public class RespawnManager : NetworkBehaviour
} }
} }
/// <summary>
/// Initiates the respawn process for a player, including disabling controls and starting the countdown.
/// </summary>
/// <param name="player">The player GameObject to respawn.</param>
public void StartRespawnPlayer(GameObject player) public void StartRespawnPlayer(GameObject player)
{ {
if (IsServer) if (IsServer)
...@@ -45,6 +54,10 @@ public class RespawnManager : NetworkBehaviour ...@@ -45,6 +54,10 @@ public class RespawnManager : NetworkBehaviour
} }
} }
/// <summary>
/// Disables player controls for the specified client.
/// </summary>
/// <param name="clientId">The ID of the client whose controls should be disabled.</param>
[ClientRpc] [ClientRpc]
private void TurnOffPlayerControlsClientRpc(ulong clientId) private void TurnOffPlayerControlsClientRpc(ulong clientId)
{ {
...@@ -59,6 +72,10 @@ public class RespawnManager : NetworkBehaviour ...@@ -59,6 +72,10 @@ public class RespawnManager : NetworkBehaviour
} }
} }
/// <summary>
/// Displays the respawn UI and starts the countdown for the specified client.
/// </summary>
/// <param name="clientId">The ID of the client to show the respawn UI for.</param>
[ClientRpc] [ClientRpc]
private void ShowRespawnUIClientRpc(ulong clientId) private void ShowRespawnUIClientRpc(ulong clientId)
{ {
...@@ -72,6 +89,9 @@ public class RespawnManager : NetworkBehaviour ...@@ -72,6 +89,9 @@ public class RespawnManager : NetworkBehaviour
} }
} }
/// <summary>
/// Handles the respawn countdown and triggers player respawn when the countdown ends.
/// </summary>
private IEnumerator RespawnCountdownCoroutine() private IEnumerator RespawnCountdownCoroutine()
{ {
int currentTime = _respawnTime; int currentTime = _respawnTime;
...@@ -99,6 +119,10 @@ public class RespawnManager : NetworkBehaviour ...@@ -99,6 +119,10 @@ public class RespawnManager : NetworkBehaviour
} }
} }
/// <summary>
/// Despawns the player object for the specified client.
/// </summary>
/// <param name="clientId">The ID of the client whose player object should be despawned.</param>
[ServerRpc(RequireOwnership = false)] [ServerRpc(RequireOwnership = false)]
private void DespawnPlayerServerRpc(ulong clientId) private void DespawnPlayerServerRpc(ulong clientId)
{ {
...@@ -112,7 +136,10 @@ public class RespawnManager : NetworkBehaviour ...@@ -112,7 +136,10 @@ public class RespawnManager : NetworkBehaviour
playerNetworkObjectToRemove.Despawn(); playerNetworkObjectToRemove.Despawn();
} }
/// <summary>
/// Spawns a new player object for the specified client and reinitializes its state.
/// </summary>
/// <param name="clientId">The ID of the client to spawn a new player for.</param>
[ServerRpc(RequireOwnership = false)] [ServerRpc(RequireOwnership = false)]
private void RequestSpawnPlayerServerRpc(ulong clientId) private void RequestSpawnPlayerServerRpc(ulong clientId)
{ {
......
...@@ -2,12 +2,22 @@ using System.Collections.Generic; ...@@ -2,12 +2,22 @@ using System.Collections.Generic;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Manages the targeting system for enemies, allowing them to detect and target players within a specified radius.
/// </summary>
public class TargetingManager : NetworkBehaviour public class TargetingManager : NetworkBehaviour
{ {
/// <summary>
/// Singleton instance of the TargetingManager.
/// </summary>
public static TargetingManager Instance { get; private set; } public static TargetingManager Instance { get; private set; }
private Collider[] playerColliders;
private List<Enemy> enemies = new List<Enemy>();
private Collider[] playerColliders; // Array to store colliders of detected players.
private List<Enemy> enemies = new List<Enemy>(); // List of enemies managed by the targeting system.
/// <summary>
/// Called when the object is spawned on the network. Initializes player colliders on the server.
/// </summary>
public override void OnNetworkSpawn() public override void OnNetworkSpawn()
{ {
base.OnNetworkSpawn(); base.OnNetworkSpawn();
...@@ -17,6 +27,9 @@ public class TargetingManager : NetworkBehaviour ...@@ -17,6 +27,9 @@ public class TargetingManager : NetworkBehaviour
} }
} }
/// <summary>
/// Updates the targeting system every frame. Searches for players in the detection radius of each enemy.
/// </summary>
private void Update() private void Update()
{ {
if (IsServer) if (IsServer)
...@@ -25,20 +38,27 @@ public class TargetingManager : NetworkBehaviour ...@@ -25,20 +38,27 @@ public class TargetingManager : NetworkBehaviour
} }
} }
/// <summary>
/// Searches for players within the detection radius of each enemy and assigns the closest player as the target.
/// </summary>
private void SearchForPlayersInEnemyRadius() private void SearchForPlayersInEnemyRadius()
{ {
foreach (var enemy in enemies) foreach (var enemy in enemies)
{ {
if (enemy != null) if (enemy != null)
{ {
int numColliders = Physics.OverlapSphereNonAlloc(enemy.transform.position, int numColliders = Physics.OverlapSphereNonAlloc(
enemy.transform.position,
enemy.DetectionRadius, enemy.DetectionRadius,
playerColliders, enemy.TargetLayerMask); playerColliders,
enemy.TargetLayerMask
);
if (numColliders > 0) if (numColliders > 0)
{ {
Transform closestPlayer = null; Transform closestPlayer = null;
float closestDistanceSqr = Mathf.Infinity; float closestDistanceSqr = Mathf.Infinity;
for (int i = 0; i < numColliders; i++) for (int i = 0; i < numColliders; i++)
{ {
float distanceSqr = (playerColliders[i].transform.position - enemy.transform.position) float distanceSqr = (playerColliders[i].transform.position - enemy.transform.position)
...@@ -61,16 +81,27 @@ public class TargetingManager : NetworkBehaviour ...@@ -61,16 +81,27 @@ public class TargetingManager : NetworkBehaviour
} }
} }
/// <summary>
/// Adds an enemy to the targeting system's list of managed enemies.
/// </summary>
/// <param name="enemy">The enemy to add.</param>
public void AddEnemyToTargetingList(Enemy enemy) public void AddEnemyToTargetingList(Enemy enemy)
{ {
enemies.Add(enemy); enemies.Add(enemy);
} }
/// <summary>
/// Removes an enemy from the targeting system's list of managed enemies.
/// </summary>
/// <param name="enemy">The enemy to remove.</param>
public void RemoveEnemyFromTargetingList(Enemy enemy) public void RemoveEnemyFromTargetingList(Enemy enemy)
{ {
enemies.Remove(enemy); enemies.Remove(enemy);
} }
/// <summary>
/// Ensures only one instance of TargetingManager exists and persists across scenes.
/// </summary>
private void Awake() private void Awake()
{ {
if (Instance != null && Instance != this) if (Instance != null && Instance != this)
......
...@@ -2,15 +2,24 @@ using System; ...@@ -2,15 +2,24 @@ using System;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
/// <summary>
/// Represents an arrow that can follow a target's position and rotation.
/// </summary>
public class Arrow : MonoBehaviour public class Arrow : MonoBehaviour
{ {
private Transform _targetTransform; private Transform _targetTransform; // The transform of the target the arrow will follow.
/// <summary>
/// Updates the arrow's position and rotation to follow the target.
/// </summary>
private void Update() private void Update()
{ {
FollowTarget(); FollowTarget();
} }
/// <summary>
/// Makes the arrow follow the target's position and rotation.
/// </summary>
private void FollowTarget() private void FollowTarget()
{ {
if (_targetTransform != null) if (_targetTransform != null)
...@@ -20,11 +29,18 @@ public class Arrow : MonoBehaviour ...@@ -20,11 +29,18 @@ public class Arrow : MonoBehaviour
} }
} }
/// <summary>
/// Sets the target transform for the arrow to follow.
/// </summary>
/// <param name="targetTransform">The transform of the target.</param>
public void SetTargetTransform(Transform targetTransform) public void SetTargetTransform(Transform targetTransform)
{ {
_targetTransform = targetTransform; _targetTransform = targetTransform;
} }
/// <summary>
/// Removes the target transform, stopping the arrow from following it.
/// </summary>
public void RemoveTargetTransform() public void RemoveTargetTransform()
{ {
_targetTransform = null; _targetTransform = null;
......
using DG.Tweening; using DG.Tweening;
using UnityEngine; using UnityEngine;
/// <summary>
/// Handles the movement and rotation of a GameObject to follow a target transform or player controls.
/// </summary>
public class FollowTransform : MonoBehaviour public class FollowTransform : MonoBehaviour
{ {
private ISwitchPlayerMap _targetPlayerControls; private ISwitchPlayerMap _targetPlayerControls; // Interface for managing player control states.
private Transform _targetTransform; private Transform _targetTransform; // The transform to follow.
private Quaternion _startingRotation; private Quaternion _startingRotation; // The initial rotation of the GameObject.
[SerializeField]
private FollowTransformSettings followTransformSettings; // Settings for movement and rotation behavior.
[SerializeField] private FollowTransformSettings followTransformSettings; /// <summary>
/// Initializes the starting rotation of the GameObject.
/// </summary>
private void Start() private void Start()
{ {
_startingRotation = transform.rotation; _startingRotation = transform.rotation;
} }
/// <summary>
/// Sets the target player controls to manage during the follow process.
/// </summary>
/// <param name="targetPlayerControls">The player controls to manage.</param>
public void SetTargetPlayerControls(ISwitchPlayerMap targetPlayerControls) public void SetTargetPlayerControls(ISwitchPlayerMap targetPlayerControls)
{ {
this._targetPlayerControls = targetPlayerControls; this._targetPlayerControls = targetPlayerControls;
} }
/// <summary>
/// Sets the target transform for the GameObject to follow.
/// </summary>
/// <param name="targetTransform">The transform to follow.</param>
public void SetTargetTransform(Transform targetTransform) public void SetTargetTransform(Transform targetTransform)
{ {
if (targetTransform != null) if (targetTransform != null)
...@@ -33,6 +47,10 @@ public class FollowTransform : MonoBehaviour ...@@ -33,6 +47,10 @@ public class FollowTransform : MonoBehaviour
} }
} }
/// <summary>
/// Removes the target transform and moves the GameObject to a specified position.
/// </summary>
/// <param name="putDownPosition">The position to move the GameObject to.</param>
public void RemoveTargetTransform(Vector3 putDownPosition) public void RemoveTargetTransform(Vector3 putDownPosition)
{ {
_targetPlayerControls.TurnOffPlayerControls(); _targetPlayerControls.TurnOffPlayerControls();
...@@ -45,6 +63,9 @@ public class FollowTransform : MonoBehaviour ...@@ -45,6 +63,9 @@ public class FollowTransform : MonoBehaviour
}); });
} }
/// <summary>
/// Updates the GameObject's position and rotation to match the target transform.
/// </summary>
private void LateUpdate() private void LateUpdate()
{ {
if (_targetTransform == null) if (_targetTransform == null)
......
using Unity.Netcode.Components; using Unity.Netcode.Components;
/// <summary>
/// A custom implementation of NetworkAnimator that allows client authority over animation synchronization.
/// </summary>
public class OwnerNetworkAnimator : NetworkAnimator public class OwnerNetworkAnimator : NetworkAnimator
{ {
/// <summary>
/// Determines whether the server is authoritative for this animator.
/// This implementation makes the owner client authoritative instead of the server.
/// </summary>
/// <returns>False, indicating that the owner client is authoritative.</returns>
protected override bool OnIsServerAuthoritative() protected override bool OnIsServerAuthoritative()
{ {
return false; return false;
......
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Handles player animation states and synchronizes them with player events.
/// </summary>
public class PlayerAnimator : NetworkBehaviour public class PlayerAnimator : NetworkBehaviour
{ {
private const string IS_WALKING = "IsWalking"; private const string IS_WALKING = "IsWalking"; // Animation parameter for walking state.
private const string IS_RUNNING = "IsRunning"; private const string IS_RUNNING = "IsRunning"; // Animation parameter for running state.
private const string IS_INTERACTING = "Interact"; private const string IS_INTERACTING = "Interact"; // Animation trigger for interaction.
private const string IS_ATTACKING = "Attack"; private const string IS_ATTACKING = "Attack"; // Animation trigger for attacking.
private const string IS_DEFENDING = "IsDefending"; private const string IS_DEFENDING = "IsDefending"; // Animation parameter for defending state.
private PlayerEvents _playerEvents; // Reference to player events for subscribing to animation triggers.
private Animator _animator; // Reference to the Animator component.
private PlayerEvents _playerEvents; /// <summary>
private Animator _animator; /// Initializes the Animator component.
/// </summary>
private void Start() private void Start()
{ {
_animator = GetComponentInChildren<Animator>(); _animator = GetComponentInChildren<Animator>();
} }
/// <summary>
/// Unsubscribes from player events when the object is disabled.
/// </summary>
private void OnDisable() private void OnDisable()
{ {
if (_playerEvents != null) if (_playerEvents != null)
...@@ -31,6 +38,10 @@ public class PlayerAnimator : NetworkBehaviour ...@@ -31,6 +38,10 @@ public class PlayerAnimator : NetworkBehaviour
} }
} }
/// <summary>
/// Subscribes to player events to handle animation state changes.
/// </summary>
/// <param name="playerEvents">The PlayerEvents instance to subscribe to.</param>
public void InitializeEvents(PlayerEvents playerEvents) public void InitializeEvents(PlayerEvents playerEvents)
{ {
this._playerEvents = playerEvents; this._playerEvents = playerEvents;
...@@ -44,27 +55,44 @@ public class PlayerAnimator : NetworkBehaviour ...@@ -44,27 +55,44 @@ public class PlayerAnimator : NetworkBehaviour
} }
} }
/// <summary>
/// Sets the running animation state.
/// </summary>
/// <param name="state">True if the player is running, false otherwise.</param>
private void SetPlayerRunBool(bool state) private void SetPlayerRunBool(bool state)
{ {
_animator.SetBool(IS_RUNNING, state); _animator.SetBool(IS_RUNNING, state);
} }
/// <summary>
/// Sets the walking animation state.
/// </summary>
/// <param name="state">True if the player is walking, false otherwise.</param>
private void SetPlayerWalkBool(bool state) private void SetPlayerWalkBool(bool state)
{ {
_animator.SetBool(IS_WALKING, state); _animator.SetBool(IS_WALKING, state);
} }
/// <summary>
/// Triggers the interaction animation.
/// </summary>
private void SetPlayerInteract() private void SetPlayerInteract()
{ {
_animator.CrossFade(IS_INTERACTING, 0.1f, -1, 0, 1f); _animator.CrossFade(IS_INTERACTING, 0.1f, -1, 0, 1f);
} }
/// <summary>
/// Triggers the attack animation.
/// </summary>
private void SetPlayerAttack() private void SetPlayerAttack()
{ {
_animator.CrossFade(IS_ATTACKING, 0.1f, -1, 0, 1f); _animator.CrossFade(IS_ATTACKING, 0.1f, -1, 0, 1f);
} }
/// <summary>
/// Sets the defending animation state.
/// </summary>
/// <param name="state">True if the player is defending, false otherwise.</param>
private void SetPlayerDefence(bool state) private void SetPlayerDefence(bool state)
{ {
_animator.SetBool(IS_DEFENDING, state); _animator.SetBool(IS_DEFENDING, state);
......
...@@ -3,85 +3,87 @@ using DG.Tweening; ...@@ -3,85 +3,87 @@ using DG.Tweening;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
/// <summary>
/// Manages player controls, including movement, interaction, sprinting, attacking, and defending.
/// </summary>
public class PlayerController : NetworkBehaviour public class PlayerController : NetworkBehaviour
{ {
#region components #region components
[SerializeField] private PlayerInteractionSettings playerInteractionSettings; [SerializeField] private PlayerInteractionSettings playerInteractionSettings; // Settings for player interaction.
private PlayerPlacements _playerPlacements; private PlayerPlacements _playerPlacements; // Manages player item placements.
private PlayerManager _playerManager; private PlayerManager _playerManager; // Manages player-related events and input.
private PlayerAnimator _playerAnimator; private PlayerAnimator _playerAnimator; // Handles player animations.
private Rigidbody _rb; private Rigidbody _rb; // Rigidbody component for physics-based movement.
private Camera _camera; private Camera _camera; // Main camera reference.
#endregion #endregion
#region cameraProperties #region cameraProperties
public Vector3 offset = new Vector3(0, 7.4f, -6.4f); public Vector3 offset = new Vector3(0, 7.4f, -6.4f); // Offset for the camera position.
#endregion #endregion
#region movementProperties #region movementProperties
public bool enableSprint = true; public bool enableSprint = true; // Determines if sprinting is enabled.
public bool unlimitedSprint; public bool unlimitedSprint; // Determines if sprinting is unlimited.
public float sprintSpeed = 7f; public float sprintSpeed = 7f; // Speed multiplier when sprinting.
public float sprintDuration = 5f; public float sprintDuration = 5f; // Maximum duration of sprinting.
public float sprintCooldown = .5f; public float sprintCooldown = .5f; // Cooldown time after sprinting.
public float sprintFOV = 80f; public float sprintFOV = 80f; // Field of view during sprinting.
public float sprintFOVStepTime = 10f; public float sprintFOVStepTime = 10f; // Speed of FOV transition during sprinting.
public float zoomStepTime = 5f; public float zoomStepTime = 5f; // Speed of FOV transition when not sprinting.
public bool playerCanMove = true; public bool playerCanMove = true; // Determines if the player can move.
public float walkSpeed = 5f; public float walkSpeed = 5f; // Speed multiplier when walking.
public float maxVelocityChange = 10f; public float maxVelocityChange = 10f; // Maximum change in velocity per frame.
public float fov = 60; public float fov = 60; // Default field of view.
private bool _isWalking; private bool _isWalking; // Tracks if the player is walking.
private Vector2 _movementInput; // Input for movement.
private bool _isSprinting; // Tracks if the player is sprinting.
private float _sprintRemaining; // Remaining sprint duration.
private bool _isSprintCooldown; // Tracks if sprint is on cooldown.
private float _sprintCooldownReset; // Resets sprint cooldown.
// Internal Variables private Vector3 _jointOriginalPos; // Original position of the joint.
private Vector2 _movementInput; private float _timer; // General-purpose timer.
private bool _isSprinting;
private float _sprintRemaining;
private bool _isSprintCooldown;
private float _sprintCooldownReset;
private float _walkingSoundTimer; // Timer for walking sound cooldown.
private bool _isWalkingSoundCooldown; // Tracks if walking sound is on cooldown.
// Internal Variables private float _sprintingSoundTimer; // Timer for sprinting sound cooldown.
private Vector3 _jointOriginalPos; private bool _isSprintingSoundCooldown; // Tracks if sprinting sound is on cooldown.
private float _timer;
private float _walkingSoundTimer;
private bool _isWalkingSoundCooldown;
private float _sprintingSoundTimer;
private bool _isSprintingSoundCooldown;
#endregion #endregion
#region defenceProperties #region defenceProperties
public float defenceCooldown = 0.5f; public float defenceCooldown = 0.5f; // Cooldown time for defending.
private float _defenceCooldownTimer; private float _defenceCooldownTimer; // Tracks remaining cooldown for defending.
#endregion #endregion
#region attackProperties #region attackProperties
public float hitDamage = 5f; public float hitDamage = 5f; // Damage dealt by attacks.
public float attackCooldown = 1f; public float attackCooldown = 1f; // Cooldown time for attacking.
private float _attackCooldownTimer; private float _attackCooldownTimer; // Tracks remaining cooldown for attacking.
#endregion #endregion
#region PickupPropertios #region PickupProperties
private bool isRightHandFull; private bool isRightHandFull; // Tracks if the player's right hand is holding an item.
#endregion #endregion
/// <summary>
/// Unsubscribes from input events when the object is disabled.
/// </summary>
private void OnDisable() private void OnDisable()
{ {
if (_playerManager.inputReader != null) if (_playerManager.inputReader != null)
...@@ -94,6 +96,9 @@ public class PlayerController : NetworkBehaviour ...@@ -94,6 +96,9 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Initializes movement-related input events.
/// </summary>
private void InitializeMovements() private void InitializeMovements()
{ {
_playerManager.inputReader.MoveEvent += OnMove; _playerManager.inputReader.MoveEvent += OnMove;
...@@ -103,6 +108,9 @@ public class PlayerController : NetworkBehaviour ...@@ -103,6 +108,9 @@ public class PlayerController : NetworkBehaviour
_playerManager.inputReader.DefenceEvent += OnDefence; _playerManager.inputReader.DefenceEvent += OnDefence;
} }
/// <summary>
/// Initializes player components and settings.
/// </summary>
private void Start() private void Start()
{ {
_sprintRemaining = sprintDuration; _sprintRemaining = sprintDuration;
...@@ -138,9 +146,6 @@ public class PlayerController : NetworkBehaviour ...@@ -138,9 +146,6 @@ public class PlayerController : NetworkBehaviour
_camera.transform.rotation = Quaternion.Euler(40.45f, 0, 0); _camera.transform.rotation = Quaternion.Euler(40.45f, 0, 0);
} }
//_playerManager.inputReader.InitializeInput();
_rb = GetComponent<Rigidbody>(); _rb = GetComponent<Rigidbody>();
if (_rb == null) if (_rb == null)
{ {
...@@ -158,30 +163,45 @@ public class PlayerController : NetworkBehaviour ...@@ -158,30 +163,45 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Handles sprint input.
/// </summary>
/// <param name="state">True if sprinting, false otherwise.</param>
private void OnSprint(bool state) private void OnSprint(bool state)
{ {
_isSprinting = state; _isSprinting = state;
} }
/// <summary>
/// Handles movement input.
/// </summary>
/// <param name="movement">Movement input vector.</param>
private void OnMove(Vector2 movement) private void OnMove(Vector2 movement)
{ {
_movementInput = movement; _movementInput = movement;
} }
/// <summary>
/// Handles attack input.
/// </summary>
private void OnAttack() private void OnAttack()
{ {
if (_attackCooldownTimer > 0) return; if (_attackCooldownTimer > 0) return;
CheckForWeapons(); CheckForWeapons();
_attackCooldownTimer = attackCooldown; // Set cooldown duration _attackCooldownTimer = attackCooldown;
} }
/// <summary>
/// Handles defence input.
/// </summary>
/// <param name="state">True if defending, false otherwise.</param>
private void OnDefence(bool state) private void OnDefence(bool state)
{ {
if (state) if (state)
{ {
if (_defenceCooldownTimer > 0) return; if (_defenceCooldownTimer > 0) return;
PlayerDefend(state); PlayerDefend(state);
_defenceCooldownTimer = defenceCooldown; // Set cooldown duration _defenceCooldownTimer = defenceCooldown;
} }
else else
{ {
...@@ -189,11 +209,17 @@ public class PlayerController : NetworkBehaviour ...@@ -189,11 +209,17 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Handles interaction input.
/// </summary>
private void OnInteract() private void OnInteract()
{ {
CheckForPickupableAndInteractableCollision(); CheckForPickupableAndInteractableCollision();
} }
/// <summary>
/// Updates player state and handles cooldowns.
/// </summary>
private void Update() private void Update()
{ {
if (!IsOwner) if (!IsOwner)
...@@ -213,63 +239,13 @@ public class PlayerController : NetworkBehaviour ...@@ -213,63 +239,13 @@ public class PlayerController : NetworkBehaviour
if (enableSprint) if (enableSprint)
{ {
if (_isSprinting && !_isSprintCooldown) HandleSprint();
{
if (_isSprintingSoundCooldown)
{
// if flash is on cooldown, increase the timer
_sprintingSoundTimer += Time.deltaTime;
// if the timer is greater than the cooldown, refresh the cooldown boolean and reset the timer
if (_sprintingSoundTimer >= 0.3f)
{
_isSprintingSoundCooldown = false;
_sprintingSoundTimer = 0f;
}
}
if (!_isSprintingSoundCooldown)
{
_isSprintingSoundCooldown = true;
}
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, sprintFOV,
sprintFOVStepTime * Time.deltaTime);
// Drain sprint remaining while sprinting
if (!unlimitedSprint)
{
_sprintRemaining -= 1 * Time.deltaTime;
if (_sprintRemaining <= 0)
{
_isSprinting = false;
_isSprintCooldown = true;
}
}
}
else
{
// Regain sprint while not sprinting
_sprintRemaining = Mathf.Clamp(_sprintRemaining += 1 * Time.deltaTime, 0, sprintDuration);
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, fov, zoomStepTime * Time.deltaTime);
}
// Handles sprint cooldown
// When sprint remaining == 0 stops sprint ability until hitting cooldown
if (_isSprintCooldown)
{
sprintCooldown -= 1 * Time.deltaTime;
if (sprintCooldown <= 0)
{
_isSprintCooldown = false;
}
}
else
{
sprintCooldown = _sprintCooldownReset;
}
} }
} }
/// <summary>
/// Handles player movement and camera updates.
/// </summary>
private void FixedUpdate() private void FixedUpdate()
{ {
if (!IsOwner) if (!IsOwner)
...@@ -277,91 +253,35 @@ public class PlayerController : NetworkBehaviour ...@@ -277,91 +253,35 @@ public class PlayerController : NetworkBehaviour
return; return;
} }
#region Movement
if (playerCanMove) if (playerCanMove)
{ {
// Use the input from _movementInput to determine movement HandleMovement();
//Vector3 targetVelocity = new Vector3(_movementInput.x, 0, _movementInput.y);
//the line below doesn't let the player move backwards
Vector3 targetVelocity = new Vector3(_movementInput.x, 0, Mathf.Max(0, _movementInput.y));
targetVelocity = transform.TransformDirection(targetVelocity);
// Checks if player is walking and is grounded
if (targetVelocity.x != 0 || targetVelocity.z != 0)
{
_isWalking = true;
if (_isWalkingSoundCooldown)
{
// if flash is on cooldown, increase the timer
_walkingSoundTimer += Time.fixedDeltaTime;
// if the timer is greater than the cooldown, refresh the cooldown boolean and reset the timer
if (_walkingSoundTimer >= 0.5f)
{
_isWalkingSoundCooldown = false;
_walkingSoundTimer = 0f;
}
}
if (!_isWalkingSoundCooldown)
{
_isWalkingSoundCooldown = true;
}
}
else
{
_isWalking = false;
}
// All movement calculations while sprint is active
if (enableSprint && _isSprinting && _sprintRemaining > 0f && !_isSprintCooldown)
{
targetVelocity *= sprintSpeed;
}
else
{
targetVelocity *= walkSpeed;
}
_playerManager.playerEvents.PlayerRun(_isSprinting);
_playerManager.playerEvents.PlayerWalk(_isWalking);
Vector3 velocity = _rb.linearVelocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
_rb.AddForce(velocityChange, ForceMode.VelocityChange);
// this check doesn't rotate player if he's not moving
if (targetVelocity != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(targetVelocity);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 0.1f);
}
} }
UpdateCamera(); UpdateCamera();
#endregion
} }
/// <summary>
/// Updates the camera position based on the player's position.
/// </summary>
private void UpdateCamera() private void UpdateCamera()
{ {
_camera.transform.position = offset + gameObject.transform.position; _camera.transform.position = offset + gameObject.transform.position;
} }
/// <summary>
/// Checks for interactable or pickupable objects and interacts with them.
/// </summary>
private void CheckForPickupableAndInteractableCollision() private void CheckForPickupableAndInteractableCollision()
{ {
if (CheckForInteractableCollision()) return; if (CheckForInteractableCollision()) return;
CheckForPickupables(); CheckForPickupables();
} }
/// <summary>
/// Checks for interactable objects within range and interacts with them.
/// </summary>
/// <returns>True if an interaction occurred, false otherwise.</returns>
private bool CheckForInteractableCollision() private bool CheckForInteractableCollision()
{ {
Collider closestCollider = FindClosestCollider(transform.position, Collider closestCollider = FindClosestCollider(transform.position,
...@@ -381,6 +301,9 @@ public class PlayerController : NetworkBehaviour ...@@ -381,6 +301,9 @@ public class PlayerController : NetworkBehaviour
return false; return false;
} }
/// <summary>
/// Checks for pickupable objects within range and picks them up.
/// </summary>
private void CheckForPickupables() private void CheckForPickupables()
{ {
Collider closestCollider = FindClosestCollider(transform.position, Collider closestCollider = FindClosestCollider(transform.position,
...@@ -403,6 +326,10 @@ public class PlayerController : NetworkBehaviour ...@@ -403,6 +326,10 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Plays the interaction animation if the interaction was successful.
/// </summary>
/// <param name="state">True if the interaction was successful, false otherwise.</param>
private void PlayPlayerInteract(bool state) private void PlayPlayerInteract(bool state)
{ {
if (state) if (state)
...@@ -411,10 +338,13 @@ public class PlayerController : NetworkBehaviour ...@@ -411,10 +338,13 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Picks up or puts down an object.
/// </summary>
/// <param name="pickupable">The object to pick up or put down.</param>
/// <returns>True if the action was successful, false otherwise.</returns>
private bool PickupObject(Pickupable pickupable) private bool PickupObject(Pickupable pickupable)
{ {
//you can always put down the pickupable, but you can only pick it up
//if your right hand is empty and it's not held by anyone else.
if (!_playerPlacements.IsRightHandFull()) if (!_playerPlacements.IsRightHandFull())
{ {
return pickupable.RequestPickupObject( return pickupable.RequestPickupObject(
...@@ -428,32 +358,28 @@ public class PlayerController : NetworkBehaviour ...@@ -428,32 +358,28 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Handles the player's defence state.
/// </summary>
/// <param name="state">True if defending, false otherwise.</param>
private void PlayerDefend(bool state) private void PlayerDefend(bool state)
{ {
Debug.Log("player defending" + state); Debug.Log("player defending" + state);
_playerManager.playerEvents.PlayerDefence(state); _playerManager.playerEvents.PlayerDefence(state);
} }
/// <summary>
/// Checks for weapons and performs an attack.
/// </summary>
private void CheckForWeapons() private void CheckForWeapons()
{ {
//TODO: here it has to make a request to server and check playerRightHandItem
// if (_playerPlacements.playerRightHand != null)
// {
// Debug.Log(_playerPlacements.playerRightHand.name);
// var explosive = _playerPlacements.playerRightHand.GetComponent<Explosive>();
// if (explosive != null)
// {
// Vector3 throwDirection = transform.forward;
// explosive.Throw(throwDirection);
// }
// }
// else
// {
// Debug.Log("hitobject");
HitObject(hitDamage); HitObject(hitDamage);
//}
} }
/// <summary>
/// Deals damage to the closest destructible object within range.
/// </summary>
/// <param name="weaponHitDamage">The amount of damage to deal.</param>
private void HitObject(float weaponHitDamage) private void HitObject(float weaponHitDamage)
{ {
Collider closestCollider = FindClosestCollider(transform.position, Collider closestCollider = FindClosestCollider(transform.position,
...@@ -477,6 +403,13 @@ public class PlayerController : NetworkBehaviour ...@@ -477,6 +403,13 @@ public class PlayerController : NetworkBehaviour
} }
} }
/// <summary>
/// Finds the closest collider within a specified radius and layer mask.
/// </summary>
/// <param name="position">The position to search from.</param>
/// <param name="radius">The search radius.</param>
/// <param name="layerMask">The layer mask to filter colliders.</param>
/// <returns>The closest collider, or null if none are found.</returns>
private Collider FindClosestCollider(Vector3 position, float radius, LayerMask layerMask) private Collider FindClosestCollider(Vector3 position, float radius, LayerMask layerMask)
{ {
Collider[] hitColliders = Physics.OverlapSphere(position, radius, layerMask); Collider[] hitColliders = Physics.OverlapSphere(position, radius, layerMask);
...@@ -496,10 +429,128 @@ public class PlayerController : NetworkBehaviour ...@@ -496,10 +429,128 @@ public class PlayerController : NetworkBehaviour
return closestCollider; return closestCollider;
} }
/// <summary>
/// Rotates the player to face a target collider.
/// </summary>
/// <param name="hit">The target collider.</param>
private void RotatePlayerTowardsTarget(Collider hit) private void RotatePlayerTowardsTarget(Collider hit)
{ {
Vector3 direction = (hit.transform.position - transform.position).normalized; Vector3 direction = (hit.transform.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.DORotateQuaternion(lookRotation, 0.3f); transform.DORotateQuaternion(lookRotation, 0.3f);
} }
/// <summary>
/// Handles sprinting logic, including cooldowns and FOV adjustments.
/// </summary>
private void HandleSprint()
{
if (_isSprinting && !_isSprintCooldown)
{
if (_isSprintingSoundCooldown)
{
_sprintingSoundTimer += Time.deltaTime;
if (_sprintingSoundTimer >= 0.3f)
{
_isSprintingSoundCooldown = false;
_sprintingSoundTimer = 0f;
}
}
if (!_isSprintingSoundCooldown)
{
_isSprintingSoundCooldown = true;
}
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, sprintFOV,
sprintFOVStepTime * Time.deltaTime);
if (!unlimitedSprint)
{
_sprintRemaining -= 1 * Time.deltaTime;
if (_sprintRemaining <= 0)
{
_isSprinting = false;
_isSprintCooldown = true;
}
}
}
else
{
_sprintRemaining = Mathf.Clamp(_sprintRemaining += 1 * Time.deltaTime, 0, sprintDuration);
_camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, fov, zoomStepTime * Time.deltaTime);
}
if (_isSprintCooldown)
{
sprintCooldown -= 1 * Time.deltaTime;
if (sprintCooldown <= 0)
{
_isSprintCooldown = false;
}
}
else
{
sprintCooldown = _sprintCooldownReset;
}
}
/// <summary>
/// Handles player movement, including walking and sprinting.
/// </summary>
private void HandleMovement()
{
Vector3 targetVelocity = new Vector3(_movementInput.x, 0, Mathf.Max(0, _movementInput.y));
targetVelocity = transform.TransformDirection(targetVelocity);
if (targetVelocity.x != 0 || targetVelocity.z != 0)
{
_isWalking = true;
if (_isWalkingSoundCooldown)
{
_walkingSoundTimer += Time.fixedDeltaTime;
if (_walkingSoundTimer >= 0.5f)
{
_isWalkingSoundCooldown = false;
_walkingSoundTimer = 0f;
}
}
if (!_isWalkingSoundCooldown)
{
_isWalkingSoundCooldown = true;
}
}
else
{
_isWalking = false;
}
if (enableSprint && _isSprinting && _sprintRemaining > 0f && !_isSprintCooldown)
{
targetVelocity *= sprintSpeed;
}
else
{
targetVelocity *= walkSpeed;
}
_playerManager.playerEvents.PlayerRun(_isSprinting);
_playerManager.playerEvents.PlayerWalk(_isWalking);
Vector3 velocity = _rb.linearVelocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
_rb.AddForce(velocityChange, ForceMode.VelocityChange);
if (targetVelocity != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(targetVelocity);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 0.1f);
}
}
} }
\ No newline at end of file
...@@ -2,14 +2,24 @@ using Unity.Netcode; ...@@ -2,14 +2,24 @@ using Unity.Netcode;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
/// <summary>
/// Manages the player's health, including health bar updates and respawn logic.
/// </summary>
public class PlayerHealth : NetworkBehaviour public class PlayerHealth : NetworkBehaviour
{ {
[SerializeField] private GameObject _healthCanvas; [SerializeField] private GameObject _healthCanvas; // The canvas displaying the player's health bar.
private Slider _healthSlider; private Slider _healthSlider; // The slider component representing the health bar.
private NetworkVariable<int> playerHealth = new NetworkVariable<int>();
private Vector3 _healthBarOffset;
private bool isRespawning;
private NetworkVariable<int>
playerHealth = new NetworkVariable<int>(); // The player's health value synchronized across the network.
private Vector3 _healthBarOffset; // Offset for positioning the health bar above the player.
private bool isRespawning; // Tracks whether the player is currently respawning.
/// <summary>
/// Called when the object is spawned on the network.
/// Initializes the health bar and its position.
/// </summary>
public override void OnNetworkSpawn() public override void OnNetworkSpawn()
{ {
_healthBarOffset = _healthCanvas.transform.localPosition; _healthBarOffset = _healthCanvas.transform.localPosition;
...@@ -17,13 +27,10 @@ public class PlayerHealth : NetworkBehaviour ...@@ -17,13 +27,10 @@ public class PlayerHealth : NetworkBehaviour
_healthSlider = _healthCanvas.GetComponentInChildren<Slider>(); _healthSlider = _healthCanvas.GetComponentInChildren<Slider>();
} }
[ClientRpc] /// <summary>
private void StartHealthBarClientRpc(int health) /// Initializes the player's health and starts the health bar.
{ /// </summary>
_healthSlider.maxValue = health; /// <param name="health">The initial health value.</param>
}
public void InitializePlayerHealth(int health) public void InitializePlayerHealth(int health)
{ {
if (IsServer) if (IsServer)
...@@ -34,12 +41,19 @@ public class PlayerHealth : NetworkBehaviour ...@@ -34,12 +41,19 @@ public class PlayerHealth : NetworkBehaviour
} }
} }
/// <summary>
/// Updates the health bar's position and value.
/// </summary>
private void Update() private void Update()
{ {
_healthCanvas.transform.position = gameObject.transform.position + _healthBarOffset; _healthCanvas.transform.position = gameObject.transform.position + _healthBarOffset;
_healthSlider.value = playerHealth.Value; _healthSlider.value = playerHealth.Value;
} }
/// <summary>
/// Decreases the player's health and triggers respawn if health reaches zero.
/// </summary>
/// <param name="health">The amount of health to decrease.</param>
public void decreaseHealth(int health) public void decreaseHealth(int health)
{ {
if (IsServer) if (IsServer)
...@@ -54,34 +68,19 @@ public class PlayerHealth : NetworkBehaviour ...@@ -54,34 +68,19 @@ public class PlayerHealth : NetworkBehaviour
} }
} }
// [ClientRpc] /// <summary>
// private void UpdateHealthClientRpc(int curHealth) /// Starts the health bar on the client with the specified maximum health.
// { /// </summary>
// _healthSlider.value = curHealth; /// <param name="health">The maximum health value.</param>
// } [ClientRpc]
private void StartHealthBarClientRpc(int health)
{
_healthSlider.maxValue = health;
}
// private void OnDestroy() /// <summary>
// { /// Initiates the destruction of the health bar on all clients.
// if (IsServer) /// </summary>
// {
// Destroy(_healthCanvas);
//
// DestroyHealthBarClientRpc();
// }
// }
//
// [ClientRpc]
// private void DestroyHealthBarClientRpc()
// {
// if (_healthCanvas != null)
// {
// Destroy(_healthCanvas);
// }
// else
// {
// Debug.LogError("Cant find canvas");
// }
// }
[ClientRpc] [ClientRpc]
public void InitiateHealthBarDestructionClientRpc() public void InitiateHealthBarDestructionClientRpc()
{ {
......
...@@ -2,21 +2,26 @@ using System; ...@@ -2,21 +2,26 @@ using System;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
/// <summary>
/// Handles player input using Unity's Input System and provides events for various player actions.
/// </summary>
[CreateAssetMenu(fileName = "InputReader", menuName = "Scriptable Objects/InputReader")] [CreateAssetMenu(fileName = "InputReader", menuName = "Scriptable Objects/InputReader")]
public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, IInputHandler, ISwitchPlayerMap public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, IInputHandler, ISwitchPlayerMap
{ {
private InputSystem_Actions inputActions; private InputSystem_Actions inputActions; // Input actions generated by Unity's Input System.
public event Action<Vector2> MoveEvent;
public event Action<Vector2> LookEvent; public event Action<Vector2> MoveEvent; // Event triggered when the player moves.
public event Action InteractEvent; public event Action<Vector2> LookEvent; // Event triggered when the player looks around.
public event Action JumpEvent; public event Action InteractEvent; // Event triggered when the player interacts.
public event Action AttackEvent; public event Action JumpEvent; // Event triggered when the player jumps.
public event Action<bool> SprintEvent; public event Action AttackEvent; // Event triggered when the player attacks.
public event Action<bool> CrouchEvent; public event Action<bool> SprintEvent; // Event triggered when the player sprints.
public event Action<bool> CrouchEvent; // Event triggered when the player crouches.
public event Action<bool> DefenceEvent; public event Action<bool> DefenceEvent; // Event triggered when the player defends.
/// <summary>
/// Initializes the input system and sets up callbacks for player actions.
/// </summary>
public void InitializeInput() public void InitializeInput()
{ {
if (inputActions == null) if (inputActions == null)
...@@ -28,6 +33,9 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -28,6 +33,9 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
inputActions.Enable(); inputActions.Enable();
} }
/// <summary>
/// Disables the input system when the object is disabled.
/// </summary>
private void OnDisable() private void OnDisable()
{ {
if (inputActions != null) if (inputActions != null)
...@@ -38,6 +46,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -38,6 +46,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles movement input and triggers the MoveEvent.
/// </summary>
/// <param name="context">The input context for movement.</param>
public void OnMove(InputAction.CallbackContext context) public void OnMove(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -50,6 +62,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -50,6 +62,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles look input and triggers the LookEvent.
/// </summary>
/// <param name="context">The input context for looking.</param>
public void OnLook(InputAction.CallbackContext context) public void OnLook(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -62,6 +78,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -62,6 +78,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles attack input and triggers the AttackEvent.
/// </summary>
/// <param name="context">The input context for attacking.</param>
public void OnAttack(InputAction.CallbackContext context) public void OnAttack(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -70,6 +90,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -70,6 +90,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles defence input and triggers the DefenceEvent.
/// </summary>
/// <param name="context">The input context for defending.</param>
public void OnDefence(InputAction.CallbackContext context) public void OnDefence(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -82,6 +106,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -82,6 +106,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles interaction input and triggers the InteractEvent.
/// </summary>
/// <param name="context">The input context for interacting.</param>
public void OnInteract(InputAction.CallbackContext context) public void OnInteract(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -90,6 +118,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -90,6 +118,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles crouch input and triggers the CrouchEvent.
/// </summary>
/// <param name="context">The input context for crouching.</param>
public void OnCrouch(InputAction.CallbackContext context) public void OnCrouch(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -102,6 +134,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -102,6 +134,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles jump input and triggers the JumpEvent.
/// </summary>
/// <param name="context">The input context for jumping.</param>
public void OnJump(InputAction.CallbackContext context) public void OnJump(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -110,6 +146,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -110,6 +146,10 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Handles sprint input and triggers the SprintEvent.
/// </summary>
/// <param name="context">The input context for sprinting.</param>
public void OnSprint(InputAction.CallbackContext context) public void OnSprint(InputAction.CallbackContext context)
{ {
if (context.performed) if (context.performed)
...@@ -122,26 +162,43 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions, ...@@ -122,26 +162,43 @@ public class InputReader : ScriptableObject, InputSystem_Actions.IPlayerActions,
} }
} }
/// <summary>
/// Simulates movement input (not implemented).
/// </summary>
/// <param name="movement">The movement vector to simulate.</param>
public void SimulateMove(Vector2 movement) public void SimulateMove(Vector2 movement)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Simulates interaction input (not implemented).
/// </summary>
public void SimulateInteract() public void SimulateInteract()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Simulates sprint input (not implemented).
/// </summary>
/// <param name="isSprinting">True if sprinting, false otherwise.</param>
public void SimulateSprint(bool isSprinting) public void SimulateSprint(bool isSprinting)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Disables player controls by disabling the input actions.
/// </summary>
public void TurnOffPlayerControls() public void TurnOffPlayerControls()
{ {
inputActions.Player.Disable(); inputActions.Player.Disable();
} }
/// <summary>
/// Enables player controls by enabling the input actions.
/// </summary>
public void TurnOnPlayerControls() public void TurnOnPlayerControls()
{ {
inputActions.Player.Enable(); inputActions.Player.Enable();
......
...@@ -15,7 +15,7 @@ GameObject: ...@@ -15,7 +15,7 @@ GameObject:
- component: {fileID: 3234479000206332123} - component: {fileID: 3234479000206332123}
- component: {fileID: 5394816119229616792} - component: {fileID: 5394816119229616792}
- component: {fileID: 2649082171887839502} - component: {fileID: 2649082171887839502}
- component: {fileID: 6070314325824568771} - component: {fileID: 8688275168607712535}
m_Layer: 10 m_Layer: 10
m_Name: Cube m_Name: Cube
m_TagString: Untagged m_TagString: Untagged
...@@ -179,7 +179,7 @@ MonoBehaviour: ...@@ -179,7 +179,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
ShowTopMostFoldoutHeaderGroup: 1 ShowTopMostFoldoutHeaderGroup: 1
enemySettings: {fileID: 11400000, guid: 9fdb93bec43a5104295cc3583f523a20, type: 2} enemySettings: {fileID: 11400000, guid: 9fdb93bec43a5104295cc3583f523a20, type: 2}
--- !u!114 &6070314325824568771 --- !u!114 &8688275168607712535
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
......
...@@ -9,6 +9,7 @@ GameObject: ...@@ -9,6 +9,7 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 5647974449618258513} - component: {fileID: 5647974449618258513}
- component: {fileID: 8466409412588946250}
m_Layer: 0 m_Layer: 0
m_Name: EnemySpawnLocations m_Name: EnemySpawnLocations
m_TagString: Untagged m_TagString: Untagged
...@@ -25,7 +26,7 @@ Transform: ...@@ -25,7 +26,7 @@ Transform:
m_GameObject: {fileID: 354072136138752549} m_GameObject: {fileID: 354072136138752549}
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: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0.2, 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:
...@@ -35,6 +36,19 @@ Transform: ...@@ -35,6 +36,19 @@ Transform:
- {fileID: 5019612241553091319} - {fileID: 5019612241553091319}
m_Father: {fileID: 3251327355353088423} m_Father: {fileID: 3251327355353088423}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8466409412588946250
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 354072136138752549}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a22d62560c8f61a4fbd55236631e8334, type: 3}
m_Name:
m_EditorClassIdentifier:
radius: 5
--- !u!1 &381795952518723057 --- !u!1 &381795952518723057
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -123,7 +137,7 @@ Transform: ...@@ -123,7 +137,7 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 728568152667097525} m_GameObject: {fileID: 728568152667097525}
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: 0, y: 0, z: 0} 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
...@@ -152,7 +166,7 @@ GameObject: ...@@ -152,7 +166,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &5581542974833947271 --- !u!4 &5581542974833947271
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -162,7 +176,7 @@ Transform: ...@@ -162,7 +176,7 @@ Transform:
m_GameObject: {fileID: 1342101318069946295} m_GameObject: {fileID: 1342101318069946295}
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: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0.2, 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:
...@@ -215,7 +229,7 @@ GameObject: ...@@ -215,7 +229,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &5001222007940412494 --- !u!4 &5001222007940412494
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -225,7 +239,7 @@ Transform: ...@@ -225,7 +239,7 @@ Transform:
m_GameObject: {fileID: 5250389714568146909} m_GameObject: {fileID: 5250389714568146909}
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: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0.7, 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:
...@@ -247,7 +261,7 @@ GameObject: ...@@ -247,7 +261,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &2438670058733636552 --- !u!4 &2438670058733636552
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -368,7 +382,7 @@ GameObject: ...@@ -368,7 +382,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &5981432708657565925 --- !u!4 &5981432708657565925
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -400,7 +414,7 @@ GameObject: ...@@ -400,7 +414,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &1806774946114198236 --- !u!4 &1806774946114198236
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -410,7 +424,7 @@ Transform: ...@@ -410,7 +424,7 @@ Transform:
m_GameObject: {fileID: 7584320928867012029} m_GameObject: {fileID: 7584320928867012029}
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: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0.9, 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:
...@@ -458,7 +472,7 @@ PrefabInstance: ...@@ -458,7 +472,7 @@ PrefabInstance:
m_Modifications: m_Modifications:
- target: {fileID: 163114042722539874, guid: 835d789898f8f3a4d97189425e75e8f6, type: 3} - target: {fileID: 163114042722539874, guid: 835d789898f8f3a4d97189425e75e8f6, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 3307046875 value: 2546934904
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 163114042722539874, guid: 835d789898f8f3a4d97189425e75e8f6, type: 3} - target: {fileID: 163114042722539874, guid: 835d789898f8f3a4d97189425e75e8f6, type: 3}
propertyPath: InScenePlacedSourceGlobalObjectIdHash propertyPath: InScenePlacedSourceGlobalObjectIdHash
...@@ -1708,7 +1722,7 @@ PrefabInstance: ...@@ -1708,7 +1722,7 @@ PrefabInstance:
m_Modifications: m_Modifications:
- target: {fileID: 1580681325717503087, guid: 525df842114a50742b87e2282140ad02, type: 3} - target: {fileID: 1580681325717503087, guid: 525df842114a50742b87e2282140ad02, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 1549677047 value: 1793678996
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4727207244663773237, guid: 525df842114a50742b87e2282140ad02, type: 3} - target: {fileID: 4727207244663773237, guid: 525df842114a50742b87e2282140ad02, type: 3}
propertyPath: m_Name propertyPath: m_Name
...@@ -1870,7 +1884,7 @@ PrefabInstance: ...@@ -1870,7 +1884,7 @@ PrefabInstance:
m_Modifications: m_Modifications:
- target: {fileID: 1580681325717503087, guid: 525df842114a50742b87e2282140ad02, type: 3} - target: {fileID: 1580681325717503087, guid: 525df842114a50742b87e2282140ad02, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 1334992784 value: 2157953702
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 4727207244663773237, guid: 525df842114a50742b87e2282140ad02, type: 3} - target: {fileID: 4727207244663773237, guid: 525df842114a50742b87e2282140ad02, type: 3}
propertyPath: m_Name propertyPath: m_Name
...@@ -2152,7 +2166,7 @@ MonoBehaviour: ...@@ -2152,7 +2166,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
GlobalObjectIdHash: 2408943373 GlobalObjectIdHash: 1212816001
InScenePlacedSourceGlobalObjectIdHash: 0 InScenePlacedSourceGlobalObjectIdHash: 0
DeferredDespawnTick: 0 DeferredDespawnTick: 0
Ownership: 1 Ownership: 1
...@@ -2630,7 +2644,7 @@ PrefabInstance: ...@@ -2630,7 +2644,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 3719657908984160168, guid: dc502d59cef13ed40b07aa18bd1a4167, type: 3} - target: {fileID: 3719657908984160168, guid: dc502d59cef13ed40b07aa18bd1a4167, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 870031014 value: 745029092
objectReference: {fileID: 0} objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
...@@ -2656,7 +2670,7 @@ PrefabInstance: ...@@ -2656,7 +2670,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 1667863745995374288, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3} - target: {fileID: 1667863745995374288, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3}
propertyPath: m_LocalPosition.y propertyPath: m_LocalPosition.y
value: 0.5 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 1667863745995374288, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3} - target: {fileID: 1667863745995374288, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
...@@ -2692,7 +2706,7 @@ PrefabInstance: ...@@ -2692,7 +2706,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 3668773499323874180, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3} - target: {fileID: 3668773499323874180, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 2909008999 value: 2706695298
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8050255731901760503, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3} - target: {fileID: 8050255731901760503, guid: 1d9ae894a89fd38449f1ce889f52d1ad, type: 3}
propertyPath: m_Name propertyPath: m_Name
......
...@@ -10,6 +10,7 @@ GameObject: ...@@ -10,6 +10,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 1774531537854147144} - component: {fileID: 1774531537854147144}
- component: {fileID: 2847495381736913473} - component: {fileID: 2847495381736913473}
- component: {fileID: -3393537255742368440}
m_Layer: 0 m_Layer: 0
m_Name: EnemySpawner m_Name: EnemySpawner
m_TagString: Untagged m_TagString: Untagged
...@@ -48,6 +49,31 @@ MonoBehaviour: ...@@ -48,6 +49,31 @@ MonoBehaviour:
ShowTopMostFoldoutHeaderGroup: 1 ShowTopMostFoldoutHeaderGroup: 1
_rogueEnemyPrefab: {fileID: 0} _rogueEnemyPrefab: {fileID: 0}
_slimeEnemyPrefab: {fileID: 0} _slimeEnemyPrefab: {fileID: 0}
--- !u!114 &-3393537255742368440
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6866275124911934084}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name:
m_EditorClassIdentifier:
GlobalObjectIdHash: 2930372943
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!1 &7258924596401886573 --- !u!1 &7258924596401886573
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -47,7 +47,7 @@ MonoBehaviour: ...@@ -47,7 +47,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
GlobalObjectIdHash: 2107378644 GlobalObjectIdHash: 1523420517
InScenePlacedSourceGlobalObjectIdHash: 389880154 InScenePlacedSourceGlobalObjectIdHash: 389880154
DeferredDespawnTick: 0 DeferredDespawnTick: 0
Ownership: 1 Ownership: 1
...@@ -161,6 +161,14 @@ PrefabInstance: ...@@ -161,6 +161,14 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 7801895876235266027} m_TransformParent: {fileID: 7801895876235266027}
m_Modifications: m_Modifications:
- target: {fileID: -3393537255742368440, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
propertyPath: GlobalObjectIdHash
value: 1523420517
objectReference: {fileID: 0}
- target: {fileID: -3393537255742368440, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
propertyPath: InScenePlacedSourceGlobalObjectIdHash
value: 389880154
objectReference: {fileID: 0}
- target: {fileID: 941907791769148275, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3} - target: {fileID: 941907791769148275, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 3612224711 value: 3612224711
...@@ -171,7 +179,7 @@ PrefabInstance: ...@@ -171,7 +179,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 1774531537854147144, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3} - target: {fileID: 1774531537854147144, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
propertyPath: m_LocalPosition.y propertyPath: m_LocalPosition.y
value: 0.5603608 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 1774531537854147144, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3} - target: {fileID: 1774531537854147144, guid: 97ac290fc57dc044a9e439c8e5a05a23, type: 3}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
......
...@@ -111,7 +111,7 @@ MonoBehaviour: ...@@ -111,7 +111,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
GlobalObjectIdHash: 2011270040 GlobalObjectIdHash: 3486418551
InScenePlacedSourceGlobalObjectIdHash: 0 InScenePlacedSourceGlobalObjectIdHash: 0
DeferredDespawnTick: 0 DeferredDespawnTick: 0
Ownership: 1 Ownership: 1
......
...@@ -333,12 +333,11 @@ MonoBehaviour: ...@@ -333,12 +333,11 @@ MonoBehaviour:
RangerAmountContainer: {fileID: 1018751068} RangerAmountContainer: {fileID: 1018751068}
SlimeAmountContainer: {fileID: 1544296584} SlimeAmountContainer: {fileID: 1544296584}
_connectButton: {fileID: 251032852} _connectButton: {fileID: 251032852}
_gameStartCountDownTime: 2 _slimeSpawnCooldownTime: 1
_slimeSpawnCooldownTime: 0.01 _rogueSpawnCooldownTime: 2
_rogueSpawnCooldownTime: 0.3
playerPrefab: {fileID: 7039287367920326276, guid: 702bb31d143eeaa4792be36b28160445, type: 3}
playerHealth: 100
_startGameCountdownTimer: 10 _startGameCountdownTimer: 10
playerPrefab: {fileID: 7039287367920326276, guid: 702bb31d143eeaa4792be36b28160445, type: 3}
playerHealth: 200
--- !u!114 &529219308 --- !u!114 &529219308
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -653,6 +652,10 @@ PrefabInstance: ...@@ -653,6 +652,10 @@ PrefabInstance:
propertyPath: m_AnchoredPosition.y propertyPath: m_AnchoredPosition.y
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 309593061376755853, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_text
value: "4\u200B"
objectReference: {fileID: 0}
- target: {fileID: 920270909126316112, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3} - target: {fileID: 920270909126316112, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 0 value: 0
...@@ -781,6 +784,10 @@ PrefabInstance: ...@@ -781,6 +784,10 @@ PrefabInstance:
propertyPath: m_AnchoredPosition.y propertyPath: m_AnchoredPosition.y
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 3534326167216121825, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_Text
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4034502693420905108, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3} - target: {fileID: 4034502693420905108, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 0 value: 0
...@@ -869,6 +876,10 @@ PrefabInstance: ...@@ -869,6 +876,10 @@ PrefabInstance:
propertyPath: m_AnchoredPosition.y propertyPath: m_AnchoredPosition.y
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 5737202750316455812, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_Text
value: 127.0.0.1
objectReference: {fileID: 0}
- target: {fileID: 5802551866461339365, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3} - target: {fileID: 5802551866461339365, guid: 72327351aa28fbe4fb4c16c3d17e4de5, type: 3}
propertyPath: m_AnchorMax.y propertyPath: m_AnchorMax.y
value: 0 value: 0
......
...@@ -581,24 +581,6 @@ Transform: ...@@ -581,24 +581,6 @@ 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!1 &1538239691 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 354072136138752549, guid: 2533a95934a9ea044a5454189730090b, type: 3}
m_PrefabInstance: {fileID: 4656849397191549919}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1538239693
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1538239691}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a22d62560c8f61a4fbd55236631e8334, type: 3}
m_Name:
m_EditorClassIdentifier:
radius: 5
--- !u!1 &1594659819 --- !u!1 &1594659819
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -990,14 +972,6 @@ PrefabInstance: ...@@ -990,14 +972,6 @@ PrefabInstance:
propertyPath: m_Name propertyPath: m_Name
value: Environment value: Environment
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 1342101318069946295, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1806774946114198236, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_LocalPosition.y
value: 0.9
objectReference: {fileID: 0}
- target: {fileID: 2571745861886921497, guid: 2533a95934a9ea044a5454189730090b, type: 3} - target: {fileID: 2571745861886921497, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 2157953702 value: 2157953702
...@@ -1046,46 +1020,14 @@ PrefabInstance: ...@@ -1046,46 +1020,14 @@ PrefabInstance:
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 1793678996 value: 1793678996
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 5001222007940412494, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_LocalPosition.y
value: 0.7
objectReference: {fileID: 0}
- target: {fileID: 5250389714568146909, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5281452119083837664, guid: 2533a95934a9ea044a5454189730090b, type: 3} - target: {fileID: 5281452119083837664, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 1212816001 value: 1212816001
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 5510887720992502651, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5581542974833947271, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_LocalPosition.y
value: 0.2
objectReference: {fileID: 0}
- target: {fileID: 5647974449618258513, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_LocalPosition.y
value: 0.2
objectReference: {fileID: 0}
- target: {fileID: 5718679709133256066, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7270026267180335326, guid: 2533a95934a9ea044a5454189730090b, type: 3} - target: {fileID: 7270026267180335326, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 745029092 value: 745029092
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 7466567691796396836, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7584320928867012029, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7679692720847302870, guid: 2533a95934a9ea044a5454189730090b, type: 3} - target: {fileID: 7679692720847302870, guid: 2533a95934a9ea044a5454189730090b, type: 3}
propertyPath: GlobalObjectIdHash propertyPath: GlobalObjectIdHash
value: 2706695298 value: 2706695298
...@@ -1093,10 +1035,7 @@ PrefabInstance: ...@@ -1093,10 +1035,7 @@ PrefabInstance:
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects: []
m_AddedComponents: m_AddedComponents: []
- targetCorrespondingSourceObject: {fileID: 354072136138752549, guid: 2533a95934a9ea044a5454189730090b, type: 3}
insertIndex: -1
addedObject: {fileID: 1538239693}
m_SourcePrefab: {fileID: 100100000, guid: 2533a95934a9ea044a5454189730090b, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 2533a95934a9ea044a5454189730090b, type: 3}
--- !u!1001 &6950935288098905811 --- !u!1001 &6950935288098905811
PrefabInstance: PrefabInstance:
...@@ -1106,10 +1045,6 @@ PrefabInstance: ...@@ -1106,10 +1045,6 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 0} m_TransformParent: {fileID: 0}
m_Modifications: m_Modifications:
- target: {fileID: 4464205841933766465, guid: c3c6003d148e24045a5699c460b258c9, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4994959905079220019, guid: c3c6003d148e24045a5699c460b258c9, type: 3} - target: {fileID: 4994959905079220019, guid: c3c6003d148e24045a5699c460b258c9, type: 3}
propertyPath: m_Name propertyPath: m_Name
value: Managers value: Managers
...@@ -1166,6 +1101,10 @@ PrefabInstance: ...@@ -1166,6 +1101,10 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z propertyPath: m_LocalEulerAnglesHint.z
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8481359329700982849, guid: c3c6003d148e24045a5699c460b258c9, type: 3}
propertyPath: GlobalObjectIdHash
value: 3413010678
objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects: []
......
...@@ -15,7 +15,7 @@ MonoBehaviour: ...@@ -15,7 +15,7 @@ MonoBehaviour:
targetLayer: targetLayer:
serializedVersion: 2 serializedVersion: 2
m_Bits: 512 m_Bits: 512
detectionRange: 80 detectionRange: 13
shootingRange: 15 shootingRange: 25
shootingDelay: 5 shootingDelay: 5
speed: 0 speed: 0
...@@ -15,7 +15,7 @@ MonoBehaviour: ...@@ -15,7 +15,7 @@ MonoBehaviour:
targetLayer: targetLayer:
serializedVersion: 2 serializedVersion: 2
m_Bits: 512 m_Bits: 512
detectionRange: 80 detectionRange: 10
shootingRange: 0 shootingRange: 0
shootingDelay: 0 shootingDelay: 0
speed: 5 speed: 4
using System; using System;
using UnityEngine; using UnityEngine;
/// <summary>
/// A singleton configuration class for managing game data related to enemy amounts and spawn timers.
/// </summary>
public class GameDataConfig : MonoBehaviour public class GameDataConfig : MonoBehaviour
{ {
/// <summary>
/// The singleton instance of the GameDataConfig class.
/// </summary>
public static GameDataConfig Instance { get; private set; } public static GameDataConfig Instance { get; private set; }
/// <summary>
/// The number of rogue enemies in the game.
/// </summary>
public int RogueEnemyAmount; public int RogueEnemyAmount;
/// <summary>
/// The number of slime enemies in the game.
/// </summary>
public int SlimeEnemyAmount; public int SlimeEnemyAmount;
public float RogueEnemySpawnTimer = 2f; /// <summary>
public float SlimeEnemySpawnTimer = 0.5f; /// The spawn timer for rogue enemies.
/// </summary>
public float RogueEnemySpawnTimer;
/// <summary>
/// The spawn timer for slime enemies.
/// </summary>
public float SlimeEnemySpawnTimer;
/// <summary>
/// Ensures that only one instance of the GameDataConfig class exists.
/// If another instance is found, it is destroyed.
/// </summary>
private void Awake() private void Awake()
{ {
if (Instance != null && Instance != this) if (Instance != null && Instance != this)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment