149 lines
5.4 KiB
C#
149 lines
5.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace BulletHellTemplate
|
|
{
|
|
/// <summary>
|
|
/// Manages the orbit of multiple DamageEntity objects around a character.
|
|
/// </summary>
|
|
public class OrbitManager : MonoBehaviour
|
|
{
|
|
private Transform target; // The character to orbit
|
|
private SkillData skillData;
|
|
private List<DamageEntity> orbitingOrbs = new List<DamageEntity>(); // List of orbs
|
|
private List<float> orbAngles = new List<float>(); // Stores the angle of each orb
|
|
private float orbitDistance;
|
|
private float orbitSpeed;
|
|
public int orbCount;
|
|
private float lifeTime;
|
|
private bool isPaused = false;
|
|
|
|
/// <summary>
|
|
/// Initializes the OrbitManager with the necessary parameters.
|
|
/// </summary>
|
|
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
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pauses or resumes the orbs when the game is paused or unpaused.
|
|
/// </summary>
|
|
private void HandlePauseState()
|
|
{
|
|
if (GameplayManager.Singleton.IsPaused())
|
|
{
|
|
isPaused = true;
|
|
}
|
|
else
|
|
{
|
|
isPaused = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Destroys an orb after its lifetime expires, and checks if the OrbitManager should be destroyed.
|
|
/// </summary>
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rotates the orbs around the target at a specified speed and keeps them synchronized.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
}
|
|
}
|