using UnityEngine; [CreateAssetMenu(menuName = "Abilities/Fireball")] public class FireballAbility : Ability { public GameObject projectilePrefab; public float speed = 22f; public float damage = 20f; public float lifeTime = 4f; public override void Activate(AbilityUser user) { if (!user || !projectilePrefab) return; // 1) Figure out an aim direction that includes camera pitch // Try to use an "aim camera" on the user if you have one; otherwise Camera.main. Camera cam = null; if (Polyart.FirstPersonController.instance) cam = Polyart.FirstPersonController.instance.PlayerCamera; if (!cam) cam = Camera.main; Vector3 castPos = user.CastPos(); Vector3 dir = user.Forward(); // safe fallback if (cam) { // Ray from camera forward Ray ray = new Ray(cam.transform.position, cam.transform.forward); // If we hit something, aim at that point; otherwise aim far away Vector3 targetPoint; if (Physics.Raycast(ray, out RaycastHit hit, 1000f, ~0, QueryTriggerInteraction.Ignore)) targetPoint = hit.point; else targetPoint = ray.origin + ray.direction * 1000f; dir = (targetPoint - castPos).normalized; } // 2) Spawn & orient the projectile along that 3D direction var go = Instantiate(projectilePrefab, castPos, Quaternion.LookRotation(dir)); // 3) Give it velocity along the aimed direction var rb = go.GetComponent(); if (rb) { rb.velocity = dir * speed; // or: rb.AddForce(dir * speed, ForceMode.VelocityChange); rb.useGravity = false; // optional: keep straight flight rb.collisionDetectionMode = CollisionDetectionMode.Continuous; // nicer for fast shots } // 4) Damage component (unchanged) var dmg = go.GetComponent(); if (!dmg) dmg = go.AddComponent(); dmg.damage = damage; Destroy(go, lifeTime); } }