also contains changes to the animation controller for all the currently made animations, events for the singular attack animation, corresponding methods, and graph changes to utilize them
129 lines
4.6 KiB
C#
129 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Reset.Core.Tools;
|
|
using Reset.Units;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
public class UnitCombat : UnitComponent {
|
|
// public List<Collider> draggedUnits = new List<Collider>();
|
|
public Dictionary<Collider, float> draggedColliders = new Dictionary<Collider, float>();
|
|
|
|
private UnitMovementHandler movement;
|
|
|
|
private Vector3 lastPosition;
|
|
private Vector3 positionDelta;
|
|
|
|
private float lastSpeed;
|
|
private float speedDelta;
|
|
private float sinAmplitude;
|
|
private float sinOffset;
|
|
|
|
private List<Collider> activelyDraggedColliders;
|
|
private List<Collider> expiredColliders;
|
|
|
|
void Awake(){
|
|
movement = GetComponent<UnitMovementHandler>();
|
|
|
|
activelyDraggedColliders = new List<Collider>();
|
|
expiredColliders = new List<Collider>();
|
|
}
|
|
|
|
void Start(){
|
|
lastPosition = transform.position;
|
|
sinOffset = Random.value;
|
|
sinAmplitude = 1 + Random.value / 4f;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update(){
|
|
// Calculate movement for dragged units
|
|
DragAttackedUnits();
|
|
|
|
// Check timers to make sure an object doesn't stay dragged
|
|
CheckUnitTimers();
|
|
}
|
|
|
|
// dragTime is set as a maximum. If no time is provided then it defaults to two seconds.
|
|
public void AddDragCollider(Collider newCollider, float dragTime = 2f){
|
|
if (draggedColliders.ContainsKey(newCollider)) {
|
|
draggedColliders[newCollider] = dragTime;
|
|
} else {
|
|
draggedColliders.Add(newCollider, dragTime);
|
|
activelyDraggedColliders.Add(newCollider);
|
|
}
|
|
}
|
|
|
|
public void RemoveDragCollider(Collider colliderToRemove){
|
|
draggedColliders.Remove(colliderToRemove);
|
|
activelyDraggedColliders.Remove(colliderToRemove);
|
|
}
|
|
|
|
public void CallAttack(){
|
|
Debug.Log("Attacked!");
|
|
Unit.Graph.SendEvent("Call Attack");
|
|
}
|
|
|
|
void CheckUnitTimers(){
|
|
// Decrease the timer of the dragged colliders
|
|
foreach (Collider thisCollider in activelyDraggedColliders) {
|
|
draggedColliders[thisCollider] -= 1f * Time.deltaTime;
|
|
|
|
// Pend them for removal when ready
|
|
if (draggedColliders[thisCollider] < 0f) {
|
|
expiredColliders.Add(thisCollider);
|
|
}
|
|
}
|
|
|
|
// Remove expired colliders
|
|
for (int i = 0; i < expiredColliders.Count; i++) {
|
|
RemoveDragCollider(expiredColliders[i]);
|
|
}
|
|
|
|
// Clear list if not empty
|
|
if (expiredColliders.Count > 0f) {
|
|
expiredColliders.Clear();
|
|
}
|
|
}
|
|
|
|
void DragAttackedUnits(){
|
|
// Get the original difference in position for speed and direction
|
|
positionDelta = Vector3.Lerp(positionDelta, lastPosition.DirectionTo(transform.position), 5f * Time.deltaTime);
|
|
speedDelta = Vector3.Distance(lastPosition, transform.position) / Time.deltaTime;
|
|
|
|
// Add some randomness to the movements based on small offsets
|
|
float sinVal = Mathf.Sin(2f + sinOffset) * sinAmplitude;
|
|
speedDelta += sinVal;
|
|
|
|
// Set a floor to prevent them from not moving enough
|
|
speedDelta = Mathf.Max(3f, speedDelta);
|
|
|
|
// Multiply the speed to be lower when further, and faster when close
|
|
float speedDiff = Mathf.Lerp(.2f, 1.4f, speedDelta);
|
|
speedDelta *= speedDiff;
|
|
|
|
// Debug
|
|
DebugOverlayDrawer.ChangeValue($"Combat - {name}", "Position Delta", positionDelta);
|
|
DebugOverlayDrawer.ChangeValue($"Combat - {name}", "Speed Delta", speedDelta);
|
|
|
|
// Update last known position
|
|
lastPosition = transform.position;
|
|
|
|
// Apply the speed, direction, and rotation to each unit
|
|
foreach (Collider draggedUnit in activelyDraggedColliders) {
|
|
UnitMovementHandler draggedUnitMovement = draggedUnit.GetComponent<UnitMovementHandler>();
|
|
if (!draggedUnitMovement) {
|
|
Debug.LogError($"No available UnitMovement on {draggedUnit.name}. Aborting drag on this unit.");
|
|
continue;
|
|
}
|
|
|
|
// Prevent units from entering a runaway situation where they constantly pull each other at high speeds across the map
|
|
speedDelta = Mathf.Min(speedDelta, draggedUnitMovement.data.moveSpeed.Value);
|
|
|
|
draggedUnitMovement.SetNewRotation(-transform.position.DirectionTo(draggedUnit.transform.position), 1f, true);
|
|
draggedUnitMovement.SetNewDirection(positionDelta.ToVector2(), 1f, true);
|
|
draggedUnitMovement.SetNewSpeed(speedDelta, 1f, true);
|
|
}
|
|
}
|
|
} |