//apply effect to all hostile unit surrounding the player void ApplyEffectAOE(Collider playerCollider) { float aoeRadius = aStats.aoeRadius; if (aoeRadius > 0) { Collider[] cols = Physics.OverlapSphere(transform.position, aoeRadius); //get all the collider in range for (int i = 0; i < cols.Length; i++) { if (cols[i] == playerCollider) { continue; } //clone the attack stats so that the original value wont get modified when making further calculation AttackInstance aInstance = new AttackInstance(null, aStats); aInstance.isAOE = true; aInstance.aoeDistance = Vector3.Distance(transform.position, cols[i].transform.position); Unit unitInstance = cols[i].gameObject.GetComponent <Unit>(); if (unitInstance != null) { unitInstance.ApplyAttack(aInstance); } } } //since this is aoe effect, explosion force applies TDSPhysics.ApplyExplosionForce(transform.position, aStats, true); }
//launch the ability, at the position given public void Activate(Vector3 pos = default(Vector3), bool useCostNCD = true) { if (useCostNCD) { currentCD = GetCooldown(); //set the cooldown GameControl.GetPlayer().energy -= GetCost(); //deduct player energy by the ability cost } AudioManager.PlaySound(launchSFX); //instantiate the launch object, if there's any if (launchObj != null) { GameObject obj = (GameObject)MonoBehaviour.Instantiate(launchObj, pos, Quaternion.identity); if (autoDestroyLaunchObj) { MonoBehaviour.Destroy(obj, launchObjActiveDuration); } } //for aoe ability if (type == _AbilityType.AOE || type == _AbilityType.AOESelf) { //get all the collider in range Collider[] cols = Physics.OverlapSphere(pos, GetAOERadius()); for (int i = 0; i < cols.Length; i++) { Unit unitInstance = cols[i].gameObject.GetComponent <Unit>(); //only continue if the collider is a unit and is not player if (unitInstance != null && unitInstance != GameControl.GetPlayer()) { //create an AttackInstance and mark it as AOE attack AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); aInstance.isAOE = true; aInstance.aoeDistance = Vector3.Distance(pos, cols[i].transform.position); //apply the AttackInstance unitInstance.ApplyAttack(aInstance); } } //apply explosion force TDSPhysics.ApplyExplosionForce(pos, aStats); } //for ability that affects all hostile unit in game else if (type == _AbilityType.All) { //get all hostile unit for unit tracker List <Unit> unitList = new List <Unit>(UnitTracker.GetAllUnitList()); //loop through all unit, create an AttackInstance and apply the attack for (int i = 0; i < unitList.Count; i++) { AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); unitList[i].ApplyAttack(aInstance); } } //for ability that meant to be cast on player unit else if (type == _AbilityType.Self) { //apply the attack on player AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); GameControl.GetPlayer().ApplyAttack(aInstance); } //for ability that fires a shoot object else if (type == _AbilityType.Shoot) { //get the position and rotation to fire the shoot object from Transform srcT = GetShootObjectSrcTransform(); Vector3 shootPos = srcT.TransformPoint(shootPosOffset); pos.y = shootPos.y; Quaternion shootRot = Quaternion.LookRotation(pos - shootPos); //create the AttackInstance AttackInstance aInstance = new AttackInstance(GameControl.GetPlayer(), GetRuntimeAttackStats()); //Instantiate the shoot-object and fires it GameObject soObj = (GameObject)MonoBehaviour.Instantiate(shootObject, shootPos, shootRot); ShootObject soInstance = soObj.GetComponent <ShootObject>(); soInstance.Shoot(GameControl.GetPlayer().thisObj.layer, GetRange(), srcT, aInstance); } else if (type == _AbilityType.Movement) { if (moveType == _MoveType.Blink) { GameControl.GetPlayer().thisT.position += GameControl.GetPlayer().thisT.TransformVector(Vector3.forward * range); } else if (moveType == _MoveType.Dash) { //GameControl.GetPlayer().thisT.position+=GameControl.GetPlayer().thisT.TransformPoint(Vector3.z)*range; GameControl.GetPlayer().Dash(range, duration); } else if (moveType == _MoveType.Teleport) { Transform playerT = GameControl.GetPlayer().thisT; Vector3 tgtPos = new Vector3(pos.x, playerT.position.y, pos.z); if (Vector3.Distance(playerT.position, tgtPos) > range) { tgtPos = playerT.position + (tgtPos - playerT.position).normalized * range; } playerT.position = tgtPos; } } }
//called when shootobject hit something void OnTriggerEnter(Collider col) { if (state == _State.Hit) { return; //if the shootobject has hit something before this, return } //if the shootobject hits another shootobject from friendly unit if (!GameControl.SOHitFriendly() && col != null) { if (srcLayer == col.gameObject.layer) { return; } } //register the state of the shootobject as hit state = _State.Hit; TDS.CameraShake(impactCamShake); //when hit a shootObject if (col != null && col.gameObject.layer == TDS.GetLayerShootObject()) { //if this is a beam shootobject, inform the other shootobject that it has been hit (beam doesnt use a collider) if (type == _SOType.Beam) { col.gameObject.GetComponent <ShootObject>().Hit(); } } //when hit a collectible, destroy the collectible if (col != null && col.gameObject.layer == TDS.GetLayerCollectible()) { ObjectPoolManager.Unspawn(col.gameObject); return; } //if there's a attack instance (means the shootobject has a valid attacking stats and all) if (attInstance != null) { float aoeRadius = attInstance.aStats.aoeRadius; //for area of effect hit if (aoeRadius > 0) { Unit unitInstance = null; //get all the potental target in range Collider[] cols = Physics.OverlapSphere(thisT.position, aoeRadius); for (int i = 0; i < cols.Length; i++) { //if the collider in question is the collider the shootobject hit in the first place, apply the full attack instance if (cols[i] == col) { unitInstance = col.gameObject.GetComponent <Unit>(); if (unitInstance != null) { unitInstance.ApplyAttack(attInstance.Clone()); } continue; } //no friendly fire, then skip if the target is a friendly unit if (!GameControl.SOHitFriendly()) { if (cols[i].gameObject.layer == srcLayer) { continue; } } unitInstance = cols[i].gameObject.GetComponent <Unit>(); //create a new attack instance and mark it as aoe attack, so diminishing aoe can be applied if enabled AttackInstance aInstance = attInstance.Clone(); aInstance.isAOE = true; aInstance.aoeDistance = Vector3.Distance(thisT.position, cols[i].transform.position); //apply the attack if (unitInstance != null) { unitInstance.ApplyAttack(aInstance); } } } else { if (col != null) { //get the unit and apply the attack Unit unitInstance = col.gameObject.GetComponent <Unit>(); if (unitInstance != null) { unitInstance.ApplyAttack(attInstance); } } } if (col != null) { //apply impact force to the hit object Vector3 impactDir = Quaternion.Euler(0, thisT.eulerAngles.y, 0) * Vector3.forward; TDSPhysics.ApplyAttackForce(thisT.position, impactDir, col.gameObject, attInstance.aStats); } } //add collider to the condition so the shootobject wont split if the shootObject didnt hit anything (it could have just reach the range limit) if (splitUponHit && col != null) { Split(col); } Hit(); }