//for when the unit is destroy by game mechanic public void Destroyed(UnitPlayer player = null) { if (destroyed) { return; } //if(player==null) Debug.LogWarning("unit destroyed by not source player has been detected", null); destroyed = true; //spawn a unit if spawnUponDestroy is assigned if (spawnUponDestroy != null) { //loop as many as required for (int i = 0; i < spawnUponDestroyCount; i++) { //instantiate the unit //GameObject unitObj=(GameObject)Instantiate(spawnUponDestroy.gameObject, thisT.position, thisT.rotation); GameObject unitObj = ObjectPoolManager.Spawn(spawnUponDestroy.gameObject, thisT.position, thisT.rotation); unitObj.layer = thisObj.layer; //pass on the wave info Unit unitInstance = unitObj.GetComponent <Unit>(); if (waveID >= 0) { unitInstance.SetWaveID(spawner, waveID); spawner.AddUnitToWave(unitInstance); } else if (spawner != null) { spawner.AddUnit(unitInstance); } } } //check if the unit is going to drop any collectible if (useDropManager) //if useDropManager is enabled, inform CollectibleDropManager { CollectibleDropManager.UnitDestroyed(thisT.position); } else { //check chance and spawn the item if (dropObject != null && Random.value < dropChance) { ObjectPoolManager.Spawn(dropObject.gameObject, thisT.position, Quaternion.identity); } } if (player != null) { //applies the bonus value for when the unit is destroyed. //if(valueCredits>0) GameControl.GainCredits(valueCredits); if (valueScore > 0) { GameControl.GainScore(valueScore); } if (valuePerkC > 0) { player.GainPerkCurrency(valuePerkC); } if (valueExp > 0) { player.GainExp(valueExp); } if (valueHitPoint > 0) { player.GainHitPoint(valueHitPoint); } if (valueEnergy > 0) { player.GainEnergy(valueEnergy); } } //if(isPlayer) GetUnitPlayer().DeleteSave(); //shake camera TDS.CameraShake(destroyCamShake); float delay = uAnimation != null?uAnimation.Destroyed() : 0; ClearUnit(true, delay); }
IEnumerator ShootRoutine(ShootObject.AimInfo aimInfo = null) { if (uAnimation != null) { uAnimation.AttackRange(); } AttackStats aStats = ModifyAttackStatsToLevel(weaponList[weaponID].GetRuntimeAttackStats()); aStats = ModifyAttackStatsToExistingEffect(aStats); //aStats=ModifyAttackStatsToExistingEffect(weaponList[weaponID].GetRuntimeAttackStats()); AttackInstance aInstance = new AttackInstance(this, aStats); int weapID = weaponID; //to prevent weapon switch and state change while delay and firing multiple so int spread = weaponList[weapID].spread; if (spread > 1) { aInstance.aStats.damageMin /= spread; aInstance.aStats.damageMax /= spread; } float startAngle = spread > 1 ? -weaponList[weapID].spreadAngle / 2f : 0; float angleDelta = spread > 1 ? weaponList[weapID].spreadAngle / (spread - 1) : 0; List <Collider> soColliderList = new List <Collider>(); //colliders of all the so fired, used to tell each so to ignore each other for (int i = 0; i < weaponList[weapID].shootPointList.Count; i++) { Transform shootPoint = weaponList[weapID].shootPointList[i]; float recoilSign = (Random.value < recoilSignTH ? -1 : 1); recoilSignTH = Mathf.Clamp(recoilSignTH + (recoilSign > 0 ? 0.25f : -0.25f), 0, 1); float recoilValue = recoilSign * Random.Range(0.1f, 1f) * GetRecoil(); Quaternion baseShootRot = shootPoint.rotation * Quaternion.Euler(0, recoilValue, 0); for (int m = 0; m < Mathf.Max(1, spread); m++) { Vector3 shootPos = shootPoint.position; if (spread > 1) { shootPos = shootPoint.TransformPoint(new Vector3(0, 0, Random.Range(-1.5f, 1.5f))); } Quaternion shootRot = baseShootRot * Quaternion.Euler(0, startAngle + (m * angleDelta), 0); //GameObject soObj=(GameObject)Instantiate(weaponList[weapID].shootObject, shootPos, shootRot); GameObject soObj = ObjectPoolManager.Spawn(weaponList[weapID].shootObject, shootPos, shootRot); ShootObject soInstance = soObj.GetComponent <ShootObject>(); soInstance.IgnoreCollider(GetCollider()); for (int n = 0; n < soColliderList.Count; n++) { soInstance.IgnoreCollider(soColliderList[n]); } if (soInstance.GetCollider() != null) { soColliderList.Add(soInstance.GetCollider()); } soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), aimInfo); //soInstance.Shoot(thisObj.layer, GetRange(), shootPoint, aInstance.Clone(), hit); } TDS.CameraShake(weaponList[weapID].recoilCamShake); if (weaponList[weapID].shootPointDelay > 0) { yield return(new WaitForSeconds(weaponList[weapID].shootPointDelay)); } if (weapID >= weaponList.Count) { break; } } }
//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(); }