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.
237 lines
8.2 KiB
C#
237 lines
8.2 KiB
C#
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;
|
|
private HashSet<Ability> abilitiesOnCooldown = new HashSet<Ability>();
|
|
[SerializeField] private GameObject currentAbilityIndicator;
|
|
[SerializeField] private GameObject wallIndicator; // Separate indicator for the wall
|
|
|
|
|
|
void Update()
|
|
{
|
|
if (isAbilityActive)
|
|
{
|
|
if (activeAbility.abilityKey == "VectorFence")
|
|
{
|
|
// Use wallIndicator for VectorFence
|
|
if (!wallIndicator.activeSelf)
|
|
{
|
|
wallIndicator.SetActive(true);
|
|
currentAbilityIndicator.SetActive(false);
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
// Save the spawn position for the wall
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
if (Physics.Raycast(ray, out RaycastHit hit))
|
|
{
|
|
wallIndicator.transform.position = hit.point;
|
|
// wallIndicator.transform.rotation = Quaternion.identity; // Reset rotation
|
|
wallIndicator.transform.localScale = new Vector3(((VectorFenceAbility) activeAbility).wallLength,
|
|
((VectorFenceAbility) activeAbility).wallHeight,
|
|
((VectorFenceAbility) activeAbility).wallWidth);
|
|
}
|
|
}
|
|
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
// Rotate the wall using Mouse X for Y-axis rotation
|
|
float mouseX = Input.GetAxis("Mouse X");
|
|
wallIndicator.transform.Rotate(Vector3.up, mouseX); // Adjust rotation speed if needed
|
|
}
|
|
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
// Place the wall at the saved position and rotation
|
|
UseActiveAbility();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Use currentAbilityIndicator for all other abilities
|
|
if (!currentAbilityIndicator.activeSelf)
|
|
{
|
|
currentAbilityIndicator.SetActive(true);
|
|
wallIndicator.SetActive(false);
|
|
}
|
|
|
|
UpdateIndicatorPosition();
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
UseActiveAbility();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Deactivate both indicators when ability mode is inactive
|
|
currentAbilityIndicator.SetActive(false);
|
|
wallIndicator.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void UpdateIndicatorForVectorFence(Vector3 center, Vector3 direction, float length)
|
|
{
|
|
if (wallIndicator != null)
|
|
{
|
|
wallIndicator.transform.position = center;
|
|
wallIndicator.transform.rotation = Quaternion.LookRotation(direction);
|
|
wallIndicator.transform.localScale = new Vector3(length, 1, 0.2f); // Adjust wall width & height
|
|
}
|
|
}
|
|
|
|
public void ActivateAbilityByKey(string key)
|
|
{
|
|
foreach (var ability in abilities)
|
|
{
|
|
if (ability.abilityKey == key)
|
|
{
|
|
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;
|
|
Debug.Log($"Ability {ability.abilityName} activated! Click to use.");
|
|
}
|
|
|
|
private void DeactivateAbilityMode()
|
|
{
|
|
isAbilityActive = false;
|
|
activeAbility = null;
|
|
Debug.Log("Ability mode deactivated.");
|
|
}
|
|
|
|
public void UseActiveAbility()
|
|
{
|
|
if (activeAbility != null)
|
|
{
|
|
Debug.Log($"[AbilitySystem] Using active ability {activeAbility.abilityName}.");
|
|
|
|
Vector3 targetPosition;
|
|
Vector3 targetRotation;
|
|
|
|
if (activeAbility.abilityKey == "VectorFence")
|
|
{
|
|
targetPosition = wallIndicator.transform.position;
|
|
targetRotation = wallIndicator.transform.eulerAngles;
|
|
}
|
|
else
|
|
{
|
|
targetPosition = currentAbilityIndicator.transform.position;
|
|
targetRotation = currentAbilityIndicator.transform.eulerAngles; // Optional, depending on other abilities
|
|
}
|
|
|
|
RequestAbilityActivationServerRpc(activeAbility.abilityKey, targetPosition, targetRotation);
|
|
StartCoroutine(StartCooldown(activeAbility));
|
|
DeactivateAbilityMode();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[AbilitySystem] No active ability to use.");
|
|
}
|
|
}
|
|
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
private void RequestAbilityActivationServerRpc(string abilityKey, Vector3 targetPosition, Vector3 targetRotation, ServerRpcParams rpcParams = default)
|
|
{
|
|
ulong ownerClientId = rpcParams.Receive.SenderClientId;
|
|
|
|
Debug.Log($"[AbilitySystem] Received activation request for ability '{abilityKey}' from client {ownerClientId} at position {targetPosition} with rotation {targetRotation}.");
|
|
|
|
ExecuteAbilityOnServer(abilityKey, ownerClientId, targetPosition, targetRotation);
|
|
}
|
|
|
|
private void ExecuteAbilityOnServer(string abilityKey, ulong ownerClientId, Vector3 targetPosition, Vector3 targetRotation)
|
|
{
|
|
// 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} with rotation {targetRotation}.");
|
|
ability.Execute(character, targetPosition, targetRotation);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|