Added the DashNCrash

dev-hazimBeforeMerge
Hazim Bin Ijaz 3 weeks ago
parent 0f36b90290
commit bab271e4b3

@ -10,13 +10,14 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e7350d0607d7cc46a92f7ff596ad88d, type: 3} m_Script: {fileID: 11500000, guid: 4e7350d0607d7cc46a92f7ff596ad88d, type: 3}
m_Name: SlowZoneAbility m_Name: DashNCrash
m_EditorClassIdentifier: m_EditorClassIdentifier:
abilityName: Slowdown Area abilityKey: DashNCrash
abilityKey: Slowdown abilityName: DashNCrash
keybind: 113
cooldownTime: 3
abilityRadius: 3 abilityRadius: 3
abilityDuration: 3
abilityMagnitude: 0.3 abilityMagnitude: 0.3
abilityPrefab: {fileID: 5818330108676053786, guid: 4979352732bf84b44a9c789bef80b18a, type: 3} abilityDuration: 3
abilityCooldownTime: 3
prefab: {fileID: 5818330108676053786, guid: 4979352732bf84b44a9c789bef80b18a, type: 3}
dashSpeed: 10
dashDuration: 0.5

@ -15,7 +15,7 @@ GameObject:
- component: {fileID: 7596904637393423818} - component: {fileID: 7596904637393423818}
- component: {fileID: 1396255635289861961} - component: {fileID: 1396255635289861961}
m_Layer: 0 m_Layer: 0
m_Name: SlowDownZonePrefab m_Name: DashNCrashPrefab
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1 m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0} m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0} m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.12731749, g: 0.13414757, b: 0.1210787, a: 1} m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0 m_UseRadianceAmbientProbe: 0
--- !u!157 &3 --- !u!157 &3
LightmapSettings: LightmapSettings:
@ -1524,6 +1524,10 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 0} m_TransformParent: {fileID: 0}
m_Modifications: m_Modifications:
- target: {fileID: 370034730102636685, guid: 4512c09d24f3fa147afb198fa90d63c6, type: 3}
propertyPath: SlowDownAbilityKey
value: DashNCrash
objectReference: {fileID: 0}
- target: {fileID: 370034730102636685, guid: 4512c09d24f3fa147afb198fa90d63c6, type: 3} - target: {fileID: 370034730102636685, guid: 4512c09d24f3fa147afb198fa90d63c6, type: 3}
propertyPath: m_GeneralSwapActionPrototype propertyPath: m_GeneralSwapActionPrototype
value: value:

@ -1,28 +1,29 @@
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using UnityEngine; using UnityEngine;
public abstract class Ability : ScriptableObject public abstract class Ability : ScriptableObject
{ {
[Header("Ability Settings")]
public string abilityName;
public string abilityKey; public string abilityKey;
public KeyCode keybind; // Key to activate the ability public string abilityName;
public float cooldownTime; // Cooldown duration in seconds
[Header("Common Ability Settings")]
public float abilityRadius; public float abilityRadius;
public float abilityDuration;
public float abilityMagnitude; public float abilityMagnitude;
public float abilityDuration;
public float abilityCooldownTime;
[Header("Ability Prefab")]
public GameObject prefab;
[SerializeField] /// <summary>
private GameObject abilityPrefab; // Prefab associated with this ability /// Executes the ability's specific behavior.
/// </summary>
public abstract void Execute(ServerCharacter character, Vector3 targetPosition);
/// <summary>
/// Retrieves the prefab associated with this ability.
/// </summary>
public GameObject GetPrefab() public GameObject GetPrefab()
{ {
return abilityPrefab; return prefab;
} }
}
public void ActivateAbility(GameObject owner)
{
Activate(owner);
}
protected abstract void Activate(GameObject owner); // Logic for the specific ability
}

@ -1,5 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
@ -8,9 +10,8 @@ public class AbilitySystem : NetworkBehaviour
[Header("Assigned Abilities")] [Header("Assigned Abilities")]
public List<Ability> abilities = new List<Ability>(); public List<Ability> abilities = new List<Ability>();
private Ability activeAbility; // Tracks the currently active ability in "spawn mode" private Ability activeAbility;
private bool isAbilityActive = false; private bool isAbilityActive = false;
private HashSet<Ability> abilitiesOnCooldown = new HashSet<Ability>(); private HashSet<Ability> abilitiesOnCooldown = new HashSet<Ability>();
[SerializeField] private GameObject currentAbilityIndicator; [SerializeField] private GameObject currentAbilityIndicator;
@ -27,9 +28,6 @@ public class AbilitySystem : NetworkBehaviour
} }
} }
/// <summary>
/// Activates an ability by its keybind.
/// </summary>
public void ActivateAbilityByKey(string key) public void ActivateAbilityByKey(string key)
{ {
foreach (var ability in abilities) foreach (var ability in abilities)
@ -52,7 +50,7 @@ public class AbilitySystem : NetworkBehaviour
public bool IsAbilityModeActive() public bool IsAbilityModeActive()
{ {
return isAbilityActive; // Returns true if an ability mode is currently active return isAbilityActive;
} }
private void ToggleAbilityMode(Ability ability) private void ToggleAbilityMode(Ability ability)
@ -71,7 +69,7 @@ public class AbilitySystem : NetworkBehaviour
{ {
isAbilityActive = true; isAbilityActive = true;
activeAbility = ability; activeAbility = ability;
currentAbilityIndicator.SetActive(true); currentAbilityIndicator?.SetActive(true);
Debug.Log($"Ability {ability.abilityName} activated! Click to use."); Debug.Log($"Ability {ability.abilityName} activated! Click to use.");
} }
@ -79,67 +77,70 @@ public class AbilitySystem : NetworkBehaviour
{ {
isAbilityActive = false; isAbilityActive = false;
activeAbility = null; activeAbility = null;
currentAbilityIndicator.SetActive(false); currentAbilityIndicator?.SetActive(false);
Debug.Log("Ability mode deactivated."); Debug.Log("Ability mode deactivated.");
} }
private void UseActiveAbility() public void UseActiveAbility()
{ {
if (activeAbility != null) if (activeAbility != null)
{ {
var spawnPosition = currentAbilityIndicator.transform.position; Debug.Log($"[AbilitySystem] Using active ability {activeAbility.abilityName}.");
SpawnAbilityServerRpc(activeAbility.abilityKey, spawnPosition); Vector3 targetPosition = currentAbilityIndicator.transform.position;
RequestAbilityActivationServerRpc(activeAbility.abilityKey, targetPosition);
StartCoroutine(StartCooldown(activeAbility)); StartCoroutine(StartCooldown(activeAbility));
DeactivateAbilityMode(); DeactivateAbilityMode();
} }
else
{
Debug.LogWarning("[AbilitySystem] No active ability to use.");
}
} }
/// <summary> [ServerRpc(RequireOwnership = false)]
/// Starts the cooldown coroutine for the ability. private void RequestAbilityActivationServerRpc(string abilityKey, Vector3 targetPosition, ServerRpcParams rpcParams = default)
/// </summary>
private IEnumerator StartCooldown(Ability ability)
{ {
abilitiesOnCooldown.Add(ability); ulong ownerClientId = rpcParams.Receive.SenderClientId;
Debug.Log($"{ability.abilityName} is now on cooldown for {ability.cooldownTime} seconds.");
yield return new WaitForSeconds(ability.cooldownTime); Debug.Log($"[AbilitySystem] Received activation request for ability '{abilityKey}' from client {ownerClientId} at position {targetPosition}.");
abilitiesOnCooldown.Remove(ability); ExecuteAbilityOnServer(abilityKey, ownerClientId, targetPosition);
Debug.Log($"{ability.abilityName} is off cooldown.");
} }
/// <summary> private void ExecuteAbilityOnServer(string abilityKey, ulong ownerClientId, Vector3 targetPosition)
/// Spawns the requested ability on the server.
/// </summary>
[ServerRpc(RequireOwnership = false)]
private void SpawnAbilityServerRpc(string abilityKey, Vector3 position, ServerRpcParams rpcParams = default)
{ {
var ability = abilities.Find(a => a.abilityKey == abilityKey); // Find the player's ServerCharacter
if (ability == null) var playerObject = NetworkManager.Singleton.SpawnManager.SpawnedObjectsList
.FirstOrDefault(obj => obj.OwnerClientId == ownerClientId && obj.GetComponent<ServerCharacter>());
if (playerObject == null || !playerObject.TryGetComponent(out ServerCharacter character))
{ {
Debug.LogError($"Ability {abilityKey} not found in the Ability System!"); Debug.LogError($"[AbilitySystem] No ServerCharacter component found for player {ownerClientId}.");
return; return;
} }
var prefab = ability.GetPrefab(); // Ensure your Ability class has a method to get the prefab // Find the ability
if (prefab == null) var ability = abilities.Find(a => a.abilityKey == abilityKey);
if (ability == null)
{ {
Debug.LogError($"Prefab for Ability {abilityKey} is not assigned!"); Debug.LogError($"[AbilitySystem] Ability {abilityKey} not found in the Ability System.");
return; return;
} }
GameObject abilityInstance = Instantiate(prefab, position, Quaternion.identity); // Activate the ability
var networkObject = abilityInstance.GetComponent<NetworkObject>(); Debug.Log($"[AbilitySystem] Activating ability {ability.abilityName} for player {ownerClientId} at {targetPosition}.");
ability.Execute(character, targetPosition);
}
if (networkObject != null) private IEnumerator StartCooldown(Ability ability)
{ {
networkObject.Spawn(); abilitiesOnCooldown.Add(ability);
Debug.Log($"Spawned {abilityKey} at {position}."); Debug.Log($"{ability.abilityName} is now on cooldown for {ability.abilityCooldownTime} seconds.");
}
else yield return new WaitForSeconds(ability.abilityCooldownTime);
{
Debug.LogError($"Ability prefab {abilityKey} must have a NetworkObject component."); abilitiesOnCooldown.Remove(ability);
} Debug.Log($"{ability.abilityName} is off cooldown.");
} }
private void UpdateIndicatorPosition() private void UpdateIndicatorPosition()
@ -148,8 +149,11 @@ public class AbilitySystem : NetworkBehaviour
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit)) if (Physics.Raycast(ray, out RaycastHit hit))
{ {
currentAbilityIndicator.transform.position = hit.point; if (currentAbilityIndicator != null)
currentAbilityIndicator.transform.localScale = Vector3.one * activeAbility.abilityRadius; {
currentAbilityIndicator.transform.position = hit.point;
currentAbilityIndicator.transform.localScale = Vector3.one * activeAbility.abilityRadius;
}
} }
} }
} }

@ -0,0 +1,47 @@
using System.Collections;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using UnityEngine;
using Unity.Netcode;
[CreateAssetMenu(menuName = "Abilities/DashNCrash")]
public class DashNCrashAbility : Ability
{
[Header("Dash Settings")]
public float dashSpeed = 10f;
public float dashDuration = 0.5f;
public override void Execute(ServerCharacter character, Vector3 targetPosition)
{
Debug.Log($"Executing DashNCrash for character {character.OwnerClientId} at {targetPosition}.");
// Start the dash
character.Movement.StartDash(targetPosition, dashSpeed, dashDuration);
// Delay spawning the slow zone until after the dash
character.StartCoroutine(SpawnSlowZoneAfterDash(character, targetPosition));
}
private IEnumerator SpawnSlowZoneAfterDash(ServerCharacter character, Vector3 position)
{
yield return new WaitForSeconds(dashDuration + 0.25f);
// Spawn the slow zone prefab at the dash's end position
var prefab = GetPrefab();
if (prefab != null)
{
GameObject instance = Instantiate(prefab, character.transform.position, Quaternion.identity);
var networkObject = instance.GetComponent<NetworkObject>();
if (networkObject != null)
{
networkObject.Spawn();
Debug.Log($"Slow Zone spawned at {position}.");
}
else
{
Debug.LogError("Slow Zone prefab must have a NetworkObject component.");
}
}
}
}

@ -5,7 +5,7 @@ using Unity.Netcode;
using UnityEngine; using UnityEngine;
[RequireComponent(typeof(SphereCollider))] [RequireComponent(typeof(SphereCollider))]
public class SlowZonePrefab : NetworkBehaviour public class DashNCrashPrefab : NetworkBehaviour
{ {
[Header("Slow Zone Settings")] [Header("Slow Zone Settings")]
public Ability Ability; public Ability Ability;

@ -185,6 +185,19 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
} }
} }
public void SetKinematic(bool isKinematic)
{
if (physicsWrapper != null)
{
var rigidbody = physicsWrapper.GetComponent<Rigidbody>();
if (rigidbody != null)
{
rigidbody.isKinematic = isKinematic;
}
}
}
public void SetAsCrow(bool status) public void SetAsCrow(bool status)
{ {
if (IsServer) if (IsServer)

@ -91,14 +91,74 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
m_NavPath.SetTargetPosition(position); m_NavPath.SetTargetPosition(position);
} }
public void StartDash(Vector3 targetPosition, float dashSpeed, float duration)
{
if (!IsServer)
{
Debug.LogWarning("[ServerCharacterMovement] StartDash called on a client. This should only run on the server.");
return;
}
if (m_NavMeshAgent == null || m_Rigidbody == null)
{
Debug.LogError("[ServerCharacterMovement] NavMeshAgent or Rigidbody is null. Ensure they are assigned.");
return;
}
Debug.Log($"[ServerCharacterMovement] StartDash initiated. Target position: {targetPosition}, Speed: {dashSpeed}, Duration: {duration}");
Vector3 direction = (targetPosition - transform.position).normalized;
if (direction.sqrMagnitude > 0.001f)
{
transform.rotation = Quaternion.LookRotation(direction);
Debug.Log($"[ServerCharacterMovement] Adjusted rotation towards {targetPosition}.");
}
else
{
Debug.LogWarning("[ServerCharacterMovement] Dash direction vector is too small. Aborting dash.");
return;
}
StartForwardCharge(dashSpeed, duration);
Debug.Log("[ServerCharacterMovement] Dash executed successfully.");
}
public void StartForwardCharge(float speed, float duration) public void StartForwardCharge(float speed, float duration)
{ {
if (!IsServer)
{
Debug.LogWarning("[ServerCharacterMovement] StartForwardCharge called on a client. This should only run on the server.");
return;
}
if (m_NavMeshAgent == null)
{
Debug.LogError("[ServerCharacterMovement] NavMeshAgent is null. Ensure it is assigned.");
return;
}
Debug.Log($"[ServerCharacterMovement] Starting forward charge for {name} with speed {speed} and duration {duration}.");
m_NavPath.Clear(); m_NavPath.Clear();
m_MovementState = MovementState.Charging; m_MovementState = MovementState.Charging;
m_ForcedSpeed = speed; m_ForcedSpeed = speed;
m_SpecialModeDurationRemaining = duration; m_SpecialModeDurationRemaining = duration;
} }
public void SetKinematic(bool isKinematic)
{
m_Rigidbody.isKinematic = isKinematic;
m_NavMeshAgent.enabled = !isKinematic; // Disable NavMeshAgent while kinematic
if (isKinematic)
{
m_Rigidbody.velocity = Vector3.zero; // Stop ongoing movement
}
}
public void StartKnockback(Vector3 knocker, float speed, float duration) public void StartKnockback(Vector3 knocker, float speed, float duration)
{ {
m_NavPath.Clear(); m_NavPath.Clear();

@ -81,7 +81,7 @@ namespace Unity.BossRoom.Gameplay.GameplayObjects
public Action DropActionPrototype => m_DropActionPrototype; public Action DropActionPrototype => m_DropActionPrototype;
public Action PickUpActionPrototype => m_PickUpActionPrototype; public Action PickUpActionPrototype => m_PickUpActionPrototype;
public string SlowDownAbilityKey = "Slowdown"; public string SlowDownAbilityKey = "DashNCrash";
List<Action> m_AllActions; List<Action> m_AllActions;

@ -1,11 +0,0 @@
using UnityEngine;
[CreateAssetMenu(menuName = "Abilities/Slow Zone Ability")]
public class SlowZoneAbility : Ability
{
protected override void Activate(GameObject owner)
{
// No direct logic here, spawning is handled in AbilitySystem
Debug.Log($"SlowZoneAbility activated by {owner.name}.");
}
}
Loading…
Cancel
Save