spell refactor part 2

This commit is contained in:
2026-01-22 14:54:35 +01:00
parent 1beff44ada
commit a7f91bcd67
30 changed files with 589 additions and 931 deletions

View File

@@ -4,14 +4,20 @@ using Invector;
namespace Beyond
{
[CreateAssetMenu(menuName = "Magic/Spells/Projectile Spell")]
[CreateAssetMenu(menuName = "Magic/Spells/Projectile (Fireball)")]
public class ProjectileSpell : SpellDefinition
{
[Header("Projectile Settings")]
public GameObject projectilePrefab;
public float spawnDelay = 0.2f; // Sync with animation hand throw
public float lifeTime = 5f;
public float aimHeightOffset = 1.0f;
public float spawnDelay = 0.2f;
public float lifeTime = 10f;
[Header("Spawn Adjustments")]
[Tooltip("Position relative to Player Root. X=Right, Y=Up, Z=Forward.\nExample: (0, 1.5, 1.0) is Chest Height, 1m forward.")]
public Vector3 spawnOffset = new Vector3(0f, 1.5f, 1.0f);
[Tooltip("Offset for aiming logic only. Usually slightly higher than the target's pivot.")]
public float aimHeightOffset = 0.75f;
public override void Cast(MagicAttacks caster, Transform target)
{
@@ -23,21 +29,44 @@ namespace Beyond
// 1. Rotate
yield return caster.RotateTowardsTargetRoutine(target, rotationDuration);
// 2. Wait for animation point
yield return new WaitForSeconds(Mathf.Max(0, spawnDelay - rotationDuration));
// 2. Wait
float remainingDelay = spawnDelay - rotationDuration;
if (remainingDelay > 0) yield return new WaitForSeconds(remainingDelay);
// 3. Calculate Spawn Position (Relative to Player)
// TransformPoint converts local (Offset) to world space based on Player position/rotation
Vector3 spawnPos = caster.transform.TransformPoint(spawnOffset);
// 4. Calculate Rotation (Aiming)
Quaternion spawnRot = caster.transform.rotation; // Default forward
// 3. Spawn
Vector3 spawnPos = caster.transform.position + caster.transform.forward + Vector3.up * 1.5f;
GameObject obj = Instantiate(projectilePrefab, spawnPos, caster.transform.rotation);
// 4. Aim
if (target != null)
{
Vector3 aimDir = (target.position + Vector3.up * aimHeightOffset) - spawnPos;
obj.transform.rotation = Quaternion.LookRotation(aimDir);
Vector3 targetPos = target.position;
targetPos.y += aimHeightOffset;
Vector3 aimDir = (targetPos - spawnPos).normalized;
// Slight arc adjustment
aimDir.y += 0.1f;
if (aimDir.sqrMagnitude > 0.001f)
spawnRot = Quaternion.LookRotation(aimDir);
}
// 5. Apply Modifiers
// 5. Instantiate
GameObject obj = Instantiate(projectilePrefab, spawnPos, spawnRot);
// 6. Ignore Collision with Caster (Crucial!)
Collider projectileCollider = obj.GetComponentInChildren<Collider>();
Collider playerCollider = caster.GetComponent<Collider>();
if (projectileCollider != null && playerCollider != null)
{
Physics.IgnoreCollision(projectileCollider, playerCollider);
}
// 7. Register Events & Modifiers
caster.RegisterSpellDamageEvents(obj, this);
caster.ApplyDamageModifiers(obj);
Destroy(obj, lifeTime);