Ejemplo n.º 1
0
        protected override void Activate(params object[] args)
        {
            //Initialize collider stats
            float powerScale = (float)args[0];

            _shotDamage         = abilityData.GetCustomStatValue("Damage") * powerScale;
            _shotKnockBack      = abilityData.GetCustomStatValue("KnockBackScale") * powerScale;
            _projectileCollider = new HitColliderBehaviour(_shotDamage, _shotKnockBack,
                                                           abilityData.GetCustomStatValue("HitAngle"), true, abilityData.GetCustomStatValue("Lifetime"), owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));
            _projectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _projectileCollider.Priority        = abilityData.ColliderPriority;

            CleanProjectileList();

            Vector2 moveDir = owner.transform.forward;

            //If the maximum amount of instances has been reached for this owner, don't spawn a new one
            if (_activeProjectiles.Count < abilityData.GetCustomStatValue("MaxInstances") || abilityData.GetCustomStatValue("MaxInstances") < 0)
            {
                if (_ownerMoveScript.MoveToPanel(_ownerMoveScript.Position + moveDir))
                {
                    _ownerMoveScript.AddOnMoveEndTempAction(SpawnProjectile);
                }
                else
                {
                    SpawnProjectile();
                }
            }
        }
Ejemplo n.º 2
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            //Create barrier collider
            _barrierCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                        abilityData.GetCustomStatValue("HitAngle"), true, abilityData.timeActive, owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));
            //Allow canceling on hit
            _barrierCollider.onHit += arguments => { abilityData.canCancelActive = true; abilityData.canCancelRecover = true; EndAbility(); };

            //Set the position of the barrier in relation to the character
            Vector3 offset = new Vector3(abilityData.GetCustomStatValue("XOffset") * owner.transform.forward.x, abilityData.GetCustomStatValue("YOffset"), 0);

            //Create barrier
            _visualPrefabInstance = MonoBehaviour.Instantiate(abilityData.visualPrefab, owner.transform.position + offset, new Quaternion());

            //Attach hit box to barrier
            HitColliderBehaviour instanceBehaviour = _visualPrefabInstance.AddComponent <HitColliderBehaviour>();

            HitColliderBehaviour.Copy(_barrierCollider, instanceBehaviour);

            //Store barrier collider
            _prefabeInstanceCollider = _visualPrefabInstance.GetComponent <BoxCollider>();

            //Give the player invinicibility while using the barrier to prevent easy over-head hits
            _ownerHealth.SetInvincibilityByCondition(condition => !InUse || CurrentAbilityPhase == AbilityPhase.RECOVER);
        }
Ejemplo n.º 3
0
        private void SpawnHitBox()
        {
            //Don't spawn the hitbox if the ability was told to deactivate
            if (_deactivated)
            {
                return;
            }

            //Play animation now that the character has reached the target panel
            EnableAnimation();

            _ownerMoveScript.MoveToAlignedSideWhenStuck = false;

            //Mark that the target position has been reached
            _inPosition = true;

            //Instantiate particles and hit box
            _visualPrefabInstance = MonoBehaviour.Instantiate(abilityData.visualPrefab, owner.transform);
            Vector3 hitBoxDimensions            = new Vector3(abilityData.GetCustomStatValue("HitBoxScaleX"), abilityData.GetCustomStatValue("HitBoxScaleY"), abilityData.GetCustomStatValue("HitBoxScaleZ"));
            HitColliderBehaviour hitColliderRef = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("Knockback"),
                                                                           abilityData.GetCustomStatValue("HitAngle"), true, abilityData.timeActive, owner, false, false, true, abilityData.GetCustomStatValue("HitStun"));

            HitColliderBehaviour hitCollider = HitColliderSpawner.SpawnBoxCollider(_visualPrefabInstance.transform, hitBoxDimensions, hitColliderRef);

            hitCollider.debuggingEnabled = true;

            //Set hitbox position
            _visualPrefabInstance.transform.position = owner.transform.position + (owner.transform.forward * abilityData.GetCustomStatValue("HitBoxDistanceZ") +
                                                                                   (owner.transform.right * abilityData.GetCustomStatValue("HitBoxDistanceX")));
        }
Ejemplo n.º 4
0
        protected override void Activate(params object[] args)
        {
            ProjectileCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                          abilityData.GetCustomStatValue("HitAngle"), despawnAfterTimeLimit, abilityData.GetCustomStatValue("Lifetime"), owner, DestroyOnHit, IsMultiHit, true, abilityData.GetCustomStatValue("HitStun"));

            //Log if a projectile couldn't be found
            if (!Projectile)
            {
                Debug.LogError("Projectile for " + abilityData.abilityName + " could not be found.");
                return;
            }

            //Create object to spawn projectile from
            GameObject spawnerObject = new GameObject();

            spawnerObject.transform.parent        = SpawnTransform;
            spawnerObject.transform.localPosition = Vector3.zero;
            spawnerObject.transform.position      = new Vector3(spawnerObject.transform.position.x, spawnerObject.transform.position.y, owner.transform.position.z);
            spawnerObject.transform.forward       = owner.transform.forward;

            //Initialize and attach spawn script
            ProjectileSpawnerBehaviour spawnScript = spawnerObject.AddComponent <ProjectileSpawnerBehaviour>();

            spawnScript.projectile = Projectile;

            //Fire projectile
            ActiveProjectiles.Add(spawnScript.FireProjectile(spawnerObject.transform.forward * abilityData.GetCustomStatValue("Speed"), ProjectileCollider));

            MonoBehaviour.Destroy(spawnerObject);
        }
 /// <summary>
 /// Copies the values in collider 1 to collider 2
 /// </summary>
 /// <param name="collider1"></param>
 /// <param name="collider2"></param>
 public static void Copy(HitColliderBehaviour collider1, HitColliderBehaviour collider2)
 {
     collider2.Init(collider1._damage, collider1._knockBackScale, collider1._hitAngle, collider1.DespawnsAfterTimeLimit, collider1.TimeActive, collider1.Owner, collider1.DestroyOnHit, collider1.IsMultiHit, collider1._adjustAngleBasedOnCollision, collider1._hitStunTime);
     collider2.onHit           = collider1.onHit;
     collider2.IgnoreColliders = collider1.IgnoreColliders;
     collider2.Priority        = collider1.Priority;
     collider2.LayersToIgnore  = collider1.LayersToIgnore;
 }
Ejemplo n.º 6
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            _projectileCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                           abilityData.GetCustomStatValue("HitAngle"), true, abilityData.GetCustomStatValue("Lifetime"), owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));

            _projectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _projectileCollider.Priority        = abilityData.ColliderPriority;

            //If no spawn transform has been set, use the default owner transform
            if (!ownerMoveset.ProjectileSpawnTransform)
            {
                spawnTransform = owner.transform;
            }
            else
            {
                spawnTransform = ownerMoveset.ProjectileSpawnTransform;
            }

            //Log if a projectile couldn't be found
            if (!_projectile)
            {
                Debug.LogError("Projectile for " + abilityData.abilityName + " could not be found.");
                return;
            }

            CleanProjectileList();

            if (_activeProjectiles.Count >= abilityData.GetCustomStatValue("MaxInstances") && abilityData.GetCustomStatValue("MaxInstances") >= 0)
            {
                return;
            }

            //Create object to spawn laser from
            GameObject spawnerObject = new GameObject();

            spawnerObject.transform.parent        = spawnTransform;
            spawnerObject.transform.localPosition = Vector3.zero;
            spawnerObject.transform.position      = new Vector3(spawnerObject.transform.position.x, spawnerObject.transform.position.y, owner.transform.position.z);
            spawnerObject.transform.forward       = owner.transform.forward;

            //Initialize and attach spawn script
            ProjectileSpawnerBehaviour spawnScript = spawnerObject.AddComponent <ProjectileSpawnerBehaviour>();

            spawnScript.projectile = _projectile;

            Vector2 offSet = new Vector2(1, 0) * -owner.transform.forward;

            offSet.x = Mathf.RoundToInt(offSet.x);
            offSet.y = Mathf.RoundToInt(offSet.y);

            _ownerMoveScript.MoveToPanel(_ownerMoveScript.Position + offSet);
            //Fire laser
            spawnScript.FireProjectile(CalculateProjectileForce(), _projectileCollider);

            MonoBehaviour.Destroy(spawnerObject);
        }
Ejemplo n.º 7
0
        public override void Init(GameObject newOwner)
        {
            base.Init(newOwner);
            //initialize default stats
            abilityData         = (ScriptableObjects.AbilityData)(Resources.Load("AbilityData/WF_ForwardShot_Data"));
            owner               = newOwner;
            _projectileCollider = new HitColliderBehaviour(1, 1, 0.2f, true, 1.5f, owner, true);

            //Load the projectile prefab
            _projectile = abilityData.visualPrefab;
        }
Ejemplo n.º 8
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            //Create collider for attack
            _fistCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                     abilityData.GetCustomStatValue("HitAngle"), true, abilityData.timeActive, owner, false, false, true, abilityData.GetCustomStatValue("HitStun"));

            //Spawn particles
            _visualPrefabInstance = MonoBehaviour.Instantiate(abilityData.visualPrefab, ownerMoveset.MeleeHitBoxSpawnTransform);

            //Spawn a game object with the collider attached
            HitColliderBehaviour hitScript = HitColliderSpawner.SpawnBoxCollider(owner.transform, new Vector3(1, 0.5f, 0.2f), _fistCollider);

            hitScript.debuggingEnabled = true;
            Rigidbody rigid = hitScript.gameObject.AddComponent <Rigidbody>();

            rigid.useGravity = false;

            //Set the direction of the attack
            Vector2 attackPosition;

            if (_attackDirection == Vector2.zero)
            {
                _attackDirection = (Vector2)(owner.transform.forward);
            }

            //Get the panel position based on the direction of attack and distance given
            attackPosition = _ownerMoveScript.Position + (_attackDirection * abilityData.GetCustomStatValue("TravelDistance"));

            //Clamp to be sure the player doesn't go off grid
            attackPosition.x = Mathf.Clamp(attackPosition.x, 0, BlackBoardBehaviour.Instance.Grid.Dimensions.x - 1);
            attackPosition.y = Mathf.Clamp(attackPosition.y, 0, BlackBoardBehaviour.Instance.Grid.Dimensions.y - 1);

            //Equation to calculate speed of attack given the active time
            float distance = abilityData.GetCustomStatValue("TravelDistance") + (abilityData.GetCustomStatValue("TravelDistance") * BlackBoardBehaviour.Instance.Grid.PanelSpacing);

            _ownerMoveScript.Speed = (distance * 2 / abilityData.timeActive) * BlackBoardBehaviour.Instance.Grid.PanelSpacing;

            //Change move traits to allow for free movement on the other side of the grid
            _ownerMoveScript.canCancelMovement        = true;
            _ownerMoveScript.AlwaysLookAtOpposingSide = false;

            //Change rotation to the direction of movement
            owner.transform.forward = new Vector3(_attackDirection.x, 0, _attackDirection.y);

            //Move towards panel
            _ownerMoveScript.MoveToPanel(attackPosition, false, GridScripts.GridAlignment.ANY, true, false);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Spawns a new box collider
        /// </summary>
        /// <param name="position">The world position of this collider</param>
        /// <param name="size">The dimension of this collider</param>
        /// <param name="hitCollider">The hit collider this collider will copy its values from</param>
        /// <returns></returns>
        public static HitColliderBehaviour SpawnBoxCollider(Vector3 position, Vector3 size, HitColliderBehaviour hitCollider)
        {
            GameObject hitObject = new GameObject();

            hitObject.name = hitCollider.ColliderOwner.name + "BoxCollider";
            BoxCollider collider = hitObject.AddComponent <BoxCollider>();

            hitObject.transform.position = position;
            collider.isTrigger           = true;
            collider.size = size;

            HitColliderBehaviour hitScript = hitObject.AddComponent <HitColliderBehaviour>();

            HitColliderBehaviour.Copy(hitCollider, hitScript);

            return(hitScript);
        }
Ejemplo n.º 10
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            float powerScale = (float)args[0];

            //If no spawn transform has been set, use the default owner transform
            if (!ownerMoveset.ProjectileSpawnTransform)
            {
                spawnTransform = owner.transform;
            }
            else
            {
                spawnTransform = ownerMoveset.ProjectileSpawnTransform;
            }

            //Log if a projectile couldn't be found
            if (!_projectile)
            {
                Debug.LogError("Projectile for " + abilityData.abilityName + " could not be found.");
                return;
            }

            //Initialize collider stats
            shotDamage          = abilityData.GetCustomStatValue("Damage") * powerScale;
            knockBackScale      = abilityData.GetCustomStatValue("KnockBackScale") * powerScale;
            _projectileCollider = new HitColliderBehaviour(shotDamage, knockBackScale, abilityData.GetCustomStatValue("HitAngle"), true,
                                                           abilityData.GetCustomStatValue("Lifetime"), owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));
            _projectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _projectileCollider.Priority        = abilityData.ColliderPriority;

            //Create object to spawn laser from
            GameObject spawnerObject = new GameObject();

            spawnerObject.transform.parent        = spawnTransform;
            spawnerObject.transform.localPosition = Vector3.zero;
            spawnerObject.transform.position      = new Vector3(spawnerObject.transform.position.x, spawnerObject.transform.position.y, owner.transform.position.z);
            spawnerObject.transform.forward       = owner.transform.forward;

            //Initialize and attach spawn script
            ProjectileSpawnerBehaviour spawnScript = spawnerObject.AddComponent <ProjectileSpawnerBehaviour>();

            spawnScript.projectile = _projectile;

            //Fire laser
            spawnScript.FireProjectile(spawnerObject.transform.forward * abilityData.GetCustomStatValue("Speed"), _projectileCollider);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Spawns a new sphere collider
        /// </summary>
        /// <param name="parent">The game object this collider will be attached to</param>
        /// <param name="radius">The size of the sphere colliders radius</param>
        /// <param name="hitCollider">The hit collider this collider will copy its values from</param>
        /// <returns></returns>
        public static HitColliderBehaviour SpawnSphereCollider(Transform parent, float radius, HitColliderBehaviour hitCollider)
        {
            GameObject hitObject = new GameObject();

            hitObject.name = hitCollider.ColliderOwner.name + " SphereCollider";
            SphereCollider collider = hitObject.AddComponent <SphereCollider>();

            hitObject.transform.parent        = parent;
            hitObject.transform.localPosition = Vector3.zero;
            collider.isTrigger = true;
            collider.radius    = radius;

            HitColliderBehaviour hitScript = hitObject.AddComponent <HitColliderBehaviour>();

            HitColliderBehaviour.Copy(hitCollider, hitScript);

            return(hitScript);
        }
Ejemplo n.º 12
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            _projectileCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                           abilityData.GetCustomStatValue("HitAngle"), true, abilityData.GetCustomStatValue("Lifetime"), owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));
            _projectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _projectileCollider.Priority        = abilityData.ColliderPriority;


            CleanProjectileList();

            if (ActiveProjectiles.Count >= abilityData.GetCustomStatValue("MaxInstances") && abilityData.GetCustomStatValue("MaxInstances") >= 0)
            {
                return;
            }

            Vector2 direction = (Vector2)args[1];

            _ownerMoveScript.StartCoroutine(Shoot(direction));
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Activates the hitboxes along the path
        /// </summary>
        private void ActivateStunPath()
        {
            //Creates a new collider for the attackLinks in the path to use
            _stunCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                     abilityData.GetCustomStatValue("HitAngle"), true, abilityData.GetCustomStatValue("Lifetime"), owner);

            //When the attackLinks in the path collide with an something else, try to stun it
            _stunCollider.onHit += StunEntity;

            //Gets a path from the first link to the second link
            List <PanelBehaviour> panels = AI.AIUtilities.Instance.GetPath(_linkMoveScripts[0].CurrentPanel, _linkMoveScripts[1].CurrentPanel, true);

            //Spawns attackLinks on each panel in the path
            for (int i = 0; i < panels.Count; i++)
            {
                GameObject           attackLink = MonoBehaviour.Instantiate(_attackLinkVisual, panels[i].transform.position + new Vector3(0, .5f, 0), _attackLinkVisual.transform.rotation);
                HitColliderBehaviour collider   = attackLink.AddComponent <HitColliderBehaviour>();
                HitColliderBehaviour.Copy(_stunCollider, collider);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Spawns a new
        /// </summary>
        /// <param name="position"></param>
        /// <param name="size"></param>
        /// <param name="damage"></param>
        /// <param name="knockBackScale"></param>
        /// <param name="hitAngle"></param>
        /// <param name="despawnAfterTimeLimit"></param>
        /// <param name="timeActive"></param>
        /// <param name="owner"></param>
        /// <returns></returns>
        public static HitColliderBehaviour SpawnBoxCollider(Vector3 position, Vector3 size, float damage,
                                                            float knockBackScale, float hitAngle, bool despawnAfterTimeLimit,
                                                            float timeActive = 0, GameObject owner = null)
        {
            GameObject hitObject = new GameObject();

            hitObject.name = owner.name + "BoxCollider";
            BoxCollider collider = hitObject.AddComponent <BoxCollider>();

            hitObject.transform.position = position;
            collider.isTrigger           = true;
            collider.size = size;

            HitColliderBehaviour hitScript = hitObject.AddComponent <HitColliderBehaviour>();

            hitScript.Init(damage, knockBackScale, hitAngle, despawnAfterTimeLimit, timeActive,
                           owner, false, false, true);

            return(hitScript);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Spawns a new sphere collider
        /// </summary>
        /// <param name="parent">The game object this collider will be attached to</param>
        /// <param name="radius">The size of the sphere colliders radius</param>
        /// <param name="damage">The amount of damage this collider will do</param>
        /// <param name="knockBackScale">How far this object will knock others back</param>
        /// <param name="hitAngle">THe angle that objects hit by this collider will be launched at</param>
        /// <param name="despawnAfterTimeLimit">Whether or not this collider should despawn after a given time</param>
        /// <param name="timeActive">The amount of time this actor can be active for</param>
        /// <param name="owner">The owner of this collider. Collision with owner are ignored</param>
        /// <returns></returns>
        public static HitColliderBehaviour SpawnSphereCollider(Transform parent, float radius, float damage,
                                                               float knockBackScale, float hitAngle, bool despawnAfterTimeLimit, float timeActive = 0,
                                                               GameObject owner = null)
        {
            GameObject hitObject = new GameObject();

            hitObject.name = owner.name + " SphereCollider";
            SphereCollider collider = hitObject.AddComponent <SphereCollider>();

            hitObject.transform.parent = parent;
            collider.isTrigger         = true;
            collider.radius            = radius;

            HitColliderBehaviour hitScript = hitObject.AddComponent <HitColliderBehaviour>();

            hitScript.Init(damage, knockBackScale, hitAngle, despawnAfterTimeLimit, timeActive,
                           owner, false, false, true);

            return(hitScript);
        }
        /// <summary>
        /// Fires a projectile
        /// </summary>
        /// <param name="force">The amount of force to apply to the projectile</param>
        /// <param name="hitCollider">The hit collider to attach to the projectile</param>
        /// <returns></returns>
        public GameObject FireProjectile(Vector3 force, HitColliderBehaviour hitCollider)
        {
            if (!projectile)
            {
                return(null);
            }

            GameObject temp = Instantiate(projectile, transform.position, new Quaternion(), null);

            HitColliderBehaviour collider = (temp.AddComponent <HitColliderBehaviour>());

            HitColliderBehaviour.Copy(hitCollider, collider);

            Rigidbody rigidbody = temp.GetComponent <Rigidbody>();

            if (rigidbody)
            {
                rigidbody.AddForce(force, ForceMode.Impulse);
            }

            return(temp);
        }
Ejemplo n.º 17
0
        protected override void Activate(params object[] args)
        {
            _projectileCollider = new HitColliderBehaviour(abilityData.GetCustomStatValue("Damage"), abilityData.GetCustomStatValue("KnockBackScale"),
                                                           abilityData.GetCustomStatValue("HitAngle"), true, abilityData.GetCustomStatValue("Lifetime"), owner, true, false, true, abilityData.GetCustomStatValue("HitStun"));
            _projectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _projectileCollider.Priority        = abilityData.ColliderPriority;

            CleanProjectileList();

            Vector2 moveDir = owner.transform.forward;

            if (ActiveProjectiles.Count < abilityData.GetCustomStatValue("MaxInstances") || abilityData.GetCustomStatValue("MaxInstances") < 0)
            {
                if (_ownerMoveScript.MoveToPanel(_ownerMoveScript.Position + moveDir))
                {
                    _ownerMoveScript.AddOnMoveEndTempAction(SpawnProjectile);
                }
                else
                {
                    SpawnProjectile();
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Spawns a new capsule collider
        /// </summary>
        /// <param name="position">The world position of this collider</param>
        /// <param name="radius">The length of the radius of this collider</param>
        /// <param name="height">How tall this collider is</param>
        /// <param name="damage">The amount of damage this collider will do to objects</param>
        /// <param name="knockBackScale">How far will objects hit by this collider will travel</param>
        /// <param name="hitAngle">The angle objects hit by this collider are launched</param>
        /// <param name="rotation">The orientation of this collider</param>
        /// <param name="despawnAfterTimeLimit">Whether or not this collider will despawn after a given time</param>
        /// <param name="timeActive">The amount of time this collider is going to be active for</param>
        /// <param name="owner">The game object that owns this collider. Collision with this object will be ignored</param>
        /// <returns></returns>
        public static HitColliderBehaviour SpawnCapsuleCollider(Vector3 position, float radius, float height,
                                                                float damage, float knockBackScale, float hitAngle,
                                                                Quaternion rotation, bool despawnAfterTimeLimit, float timeActive = 0,
                                                                GameObject owner = null)
        {
            GameObject hitObject = new GameObject();

            hitObject.name = owner.name + "CapsuleCollider";
            CapsuleCollider collider = hitObject.AddComponent <CapsuleCollider>();

            hitObject.transform.position = position;
            collider.isTrigger           = true;
            collider.radius = radius;
            collider.height = height;
            hitObject.transform.rotation = rotation;

            HitColliderBehaviour hitScript = hitObject.AddComponent <HitColliderBehaviour>();

            hitScript.Init(damage, knockBackScale, hitAngle, despawnAfterTimeLimit, timeActive,
                           owner, false, false, true);

            return(hitScript);
        }
Ejemplo n.º 19
0
        //Called when ability is used
        protected override void Activate(params object[] args)
        {
            //If no spawn transform has been set, use the default owner transform
            if (!ownerMoveset.ProjectileSpawnTransform)
            {
                spawnTransform = owner.transform;
            }
            else
            {
                spawnTransform = ownerMoveset.ProjectileSpawnTransform;
            }

            //Log if a projectile couldn't be found
            if (!_strongProjectile)
            {
                Debug.LogError("Projectile for " + abilityData.abilityName + " could not be found.");
                return;
            }

            //Initialize stats of strong and weak colliders
            float powerScale = (float)args[0];

            _weakShotDamage           = abilityData.GetCustomStatValue("WeakShotDamage") * powerScale;
            _strongShotDamage         = abilityData.GetCustomStatValue("StrongShotDamage") * powerScale;
            _strongShotKnockBackScale = abilityData.GetCustomStatValue("StrongShotKnockBackScale") * powerScale;
            _strongShotDistance       = (powerScale - 1) / abilityData.GetCustomStatValue("StrongShotForceIncreaseRate");

            _weakProjectileCollider = new HitColliderBehaviour(_weakShotDamage, abilityData.GetCustomStatValue("WeakShotKnockBackScale"),
                                                               abilityData.GetCustomStatValue("WeakShotHitAngle"), true, abilityData.GetCustomStatValue("WeakShotLifeTime"), owner, true, false, true, abilityData.GetCustomStatValue("WeakHitStun"));
            _weakProjectileCollider.IgnoreColliders = abilityData.IgnoreColliders;
            _weakProjectileCollider.Priority        = abilityData.GetCustomStatValue("WeakColliderPriority");

            _strongProjectileCollider = new HitColliderBehaviour(_strongShotDamage, _strongShotKnockBackScale,
                                                                 abilityData.GetCustomStatValue("StrongShotHitAngle"), true, abilityData.GetCustomStatValue("StrongShotLifeTime"), owner, true, false, true, abilityData.GetCustomStatValue("StrongHitStun"));
            _strongProjectileCollider.Priority        = abilityData.ColliderPriority;
            _strongProjectileCollider.IgnoreColliders = abilityData.IgnoreColliders;


            CleanProjectileList();

            //If the maximum amount of lobshot instances has been reached for this owner, don't spawn a new one
            if (_activeProjectiles.Count >= abilityData.GetCustomStatValue("MaxInstances") && abilityData.GetCustomStatValue("MaxInstances") >= 0)
            {
                return;
            }

            //Create object to spawn laser from
            GameObject spawnerObject = new GameObject();

            spawnerObject.transform.parent        = spawnTransform;
            spawnerObject.transform.localPosition = Vector3.zero;
            spawnerObject.transform.position      = new Vector3(spawnerObject.transform.position.x, spawnerObject.transform.position.y, owner.transform.position.z);
            spawnerObject.transform.forward       = owner.transform.forward;

            //Initialize and attach spawn script
            ProjectileSpawnerBehaviour spawnScript = spawnerObject.AddComponent <ProjectileSpawnerBehaviour>();

            spawnScript.projectile = _strongProjectile;

            Vector2 offSet = new Vector2(1, 0) * -owner.transform.forward;

            offSet.x = Mathf.RoundToInt(offSet.x);
            offSet.y = Mathf.RoundToInt(offSet.y);

            _ownerMoveScript.MoveToPanel(_ownerMoveScript.Position + offSet);

            _strongProjectileCollider.onHit += SpawnWeakShots;
            //Fire laser
            _weakSpawnTransform = spawnScript.FireProjectile(CalculateProjectileForce(owner.transform.forward, _strongShotDistance), _strongProjectileCollider).transform;

            _activeProjectiles.Add(_weakSpawnTransform.gameObject);

            MonoBehaviour.Destroy(spawnerObject);

            _weakShotDamage           /= powerScale;
            _strongShotDamage         /= powerScale;
            _strongShotKnockBackScale /= powerScale;
            _strongShotDistance       -= (powerScale - 1) / _strongForceIncreaseRate;
        }