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(); } } }
//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); }
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"))); }
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; }
//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); }
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; }
//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); }
/// <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); }
//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); }
/// <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); }
//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)); }
/// <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); } }
/// <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); }
/// <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); }
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(); } } }
/// <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); }
//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; }