You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HighGroundRoyaleNetcode/Assets/Scripts/Gameplay/AbilitySystem.cs

160 lines
5.1 KiB
C#

1 month ago
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using Unity.Netcode;
using UnityEngine;
public class AbilitySystem : NetworkBehaviour
{
[Header("Assigned Abilities")]
public List<Ability> abilities = new List<Ability>();
private Ability activeAbility;
private bool isAbilityActive = false;
1 month ago
private HashSet<Ability> abilitiesOnCooldown = new HashSet<Ability>();
[SerializeField] private GameObject currentAbilityIndicator;
void Update()
{
if (isAbilityActive)
{
UpdateIndicatorPosition();
if (Input.GetMouseButtonDown(0))
{
UseActiveAbility();
}
}
}
public void ActivateAbilityByKey(string key)
{
foreach (var ability in abilities)
{
if (ability.abilityKey == key)
{
1 month ago
if (!abilitiesOnCooldown.Contains(ability))
{
ToggleAbilityMode(ability);
}
else
{
Debug.Log($"{ability.abilityName} is on cooldown.");
}
return;
}
}
Debug.LogWarning($"No ability assigned to key {key}.");
}
public bool IsAbilityModeActive()
{
return isAbilityActive;
}
private void ToggleAbilityMode(Ability ability)
{
if (isAbilityActive && activeAbility == ability)
{
DeactivateAbilityMode();
}
else
{
ActivateAbilityMode(ability);
}
}
private void ActivateAbilityMode(Ability ability)
{
isAbilityActive = true;
activeAbility = ability;
currentAbilityIndicator?.SetActive(true);
1 month ago
Debug.Log($"Ability {ability.abilityName} activated! Click to use.");
}
private void DeactivateAbilityMode()
{
isAbilityActive = false;
activeAbility = null;
currentAbilityIndicator?.SetActive(false);
Debug.Log("Ability mode deactivated.");
}
public void UseActiveAbility()
{
if (activeAbility != null)
{
Debug.Log($"[AbilitySystem] Using active ability {activeAbility.abilityName}.");
Vector3 targetPosition = currentAbilityIndicator.transform.position;
RequestAbilityActivationServerRpc(activeAbility.abilityKey, targetPosition);
1 month ago
StartCoroutine(StartCooldown(activeAbility));
DeactivateAbilityMode();
}
else
{
Debug.LogWarning("[AbilitySystem] No active ability to use.");
}
}
1 month ago
[ServerRpc(RequireOwnership = false)]
private void RequestAbilityActivationServerRpc(string abilityKey, Vector3 targetPosition, ServerRpcParams rpcParams = default)
1 month ago
{
ulong ownerClientId = rpcParams.Receive.SenderClientId;
1 month ago
Debug.Log($"[AbilitySystem] Received activation request for ability '{abilityKey}' from client {ownerClientId} at position {targetPosition}.");
1 month ago
ExecuteAbilityOnServer(abilityKey, ownerClientId, targetPosition);
1 month ago
}
private void ExecuteAbilityOnServer(string abilityKey, ulong ownerClientId, Vector3 targetPosition)
{
// Find the player's ServerCharacter
var playerObject = NetworkManager.Singleton.SpawnManager.SpawnedObjectsList
.FirstOrDefault(obj => obj.OwnerClientId == ownerClientId && obj.GetComponent<ServerCharacter>());
if (playerObject == null || !playerObject.TryGetComponent(out ServerCharacter character))
{
Debug.LogError($"[AbilitySystem] No ServerCharacter component found for player {ownerClientId}.");
return;
}
// Find the ability
var ability = abilities.Find(a => a.abilityKey == abilityKey);
if (ability == null)
{
Debug.LogError($"[AbilitySystem] Ability {abilityKey} not found in the Ability System.");
return;
}
// Activate the ability
Debug.Log($"[AbilitySystem] Activating ability {ability.abilityName} for player {ownerClientId} at {targetPosition}.");
ability.Execute(character, targetPosition);
}
private IEnumerator StartCooldown(Ability ability)
{
abilitiesOnCooldown.Add(ability);
Debug.Log($"{ability.abilityName} is now on cooldown for {ability.abilityCooldownTime} seconds.");
yield return new WaitForSeconds(ability.abilityCooldownTime);
abilitiesOnCooldown.Remove(ability);
Debug.Log($"{ability.abilityName} is off cooldown.");
}
private void UpdateIndicatorPosition()
{
// Raycast to get the position of the cursor on the ground
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (currentAbilityIndicator != null)
{
currentAbilityIndicator.transform.position = hit.point;
currentAbilityIndicator.transform.localScale = Vector3.one * activeAbility.abilityRadius;
}
}
}
}