using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BulletHellTemplate
{
///
/// Manages the orbit of multiple DamageEntity objects around a character.
///
public class OrbitManager : MonoBehaviour
{
private Transform target; // The character to orbit
private SkillData skillData;
private List orbitingOrbs = new List(); // List of orbs
private List orbAngles = new List(); // Stores the angle of each orb
private float orbitDistance;
private float orbitSpeed;
public int orbCount;
private float lifeTime;
private bool isPaused = false;
///
/// Initializes the OrbitManager with the necessary parameters.
///
public void InitializeOrbital(SkillData _skillData, SkillLevel levelData, CharacterEntity attacker, int finalShots, DamageEntity damageEntityPrefab, Vector3 velocity)
{
skillData = _skillData;
target = attacker.transform;
orbCount = finalShots;
orbitDistance = _skillData.orbitalDistance;
orbitSpeed = levelData.speed * 10;
lifeTime = levelData.lifeTime;
// Calculate the angle between each orb for 360-degree spread
float angleStep = 360f / orbCount;
// Spawn the orbs around the target
for (int i = 0; i < orbCount; i++)
{
float angle = i * angleStep;
Quaternion rotation = Quaternion.Euler(0, angle, 0);
Vector3 spawnDirection = rotation * Vector3.forward; // Forward from target
// Instantiate each orb and set its position relative to the target
Vector3 spawnPosition = target.position + spawnDirection * orbitDistance;
DamageEntity orb = Instantiate(damageEntityPrefab, spawnPosition, Quaternion.identity);
orb.SetSkill(_skillData, levelData.baseDamage, levelData.attackerDamageRate, levelData.canCauseCriticalDamage, attacker,levelData.lifeTime ,velocity);
orbitingOrbs.Add(orb);
orbAngles.Add(angle); // Store the initial angle for this orb
}
}
///
/// Pauses or resumes the orbs when the game is paused or unpaused.
///
private void HandlePauseState()
{
if (GameplayManager.Singleton.IsPaused())
{
isPaused = true;
}
else
{
isPaused = false;
}
}
///
/// Destroys an orb after its lifetime expires, and checks if the OrbitManager should be destroyed.
///
private IEnumerator DestroyOrbAfterLifetime(DamageEntity orb, float lifetime)
{
float elapsedTime = 0f;
while (elapsedTime < lifetime)
{
if (!isPaused)
{
elapsedTime += Time.deltaTime;
}
yield return null;
}
// Destroy the orb
if (orb != null)
{
orbitingOrbs.Remove(orb);
Destroy(orb.gameObject);
}
// If all orbs are destroyed, destroy the OrbitManager
if (orbitingOrbs.Count == 0)
{
Destroy(gameObject);
}
}
private void Update()
{
HandlePauseState(); // Check and handle pause state
if (target == null || isPaused) return;
for (int i = 0; i < orbitingOrbs.Count; i++)
{
if (orbitingOrbs[i] != null && orbitingOrbs[i].gameObject != null)
{
OrbitAroundTarget(orbitingOrbs[i], orbAngles[i]);
}
}
}
///
/// Rotates the orbs around the target at a specified speed and keeps them synchronized.
///
private void OrbitAroundTarget(DamageEntity orb, float initialAngle)
{
if (target == null || isPaused || orb == null || orb.gameObject == null) return;
// Update the angle of rotation over time based on the orbit speed
float angle = initialAngle + orbitSpeed * Time.time;
// Calculate the new position based on the angle
Vector3 offset = new Vector3(
Mathf.Sin(angle * Mathf.Deg2Rad) * orbitDistance,
0,
Mathf.Cos(angle * Mathf.Deg2Rad) * orbitDistance
);
// Apply the position relative to the target's position
orb.transform.position = target.position + offset;
// Calculate the direction from the target to the orb
Vector3 directionToOrb = offset.normalized;
// Set the rotation of the orb to face along its movement path
// This will make the sword appear to swing as it orbits
Quaternion rotation = Quaternion.LookRotation(directionToOrb);
orb.transform.rotation = rotation;
// Optional: Add spin around the forward axis to simulate swinging
// float spinSpeed = 360f; // degrees per second
// orb.transform.Rotate(Vector3.forward, spinSpeed * Time.deltaTime);
}
}
}