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); } } }