public IEnumerator SinkPhase() { // rotting or sink phase includes time before unit is destroyed: for example to perform rotting animation or sink object into the ground float timeBeg; float timeEnd; float twaiter; while (true) { timeBeg = Time.realtimeSinceStartup; twaiter = 0.0f; // checking in sinks array, which is already different from main units array for (int i = 0; i < sinks.Count; i++) { GameObject sink = sinks[i]; UnitParsFree sinkPars = sink.GetComponent <UnitParsFree>(); if (sinkPars.isSinking == true) { if (sinkPars.changeMaterial) { sink.GetComponent <Renderer>().material.color = new Color((148.0f / 255.0f), (0.0f / 255.0f), (211.0f / 255.0f), 1.0f); } // moving sinking object down into the ground if (sink.transform.position.y > -1.0f) { sink.transform.Translate(0, -0.1f, 0, Space.World); } // destroy object if it has sinked enough else if (sink.transform.position.y < -1.0f) { sinks.Remove(sink); Destroy(sink.gameObject); } } } // main coroutine wait statement and performance information collection from sink coroutine twaiter = twaiter + 1.0f; yield return(new WaitForSeconds(1.0f)); timeEnd = Time.realtimeSinceStartup; timeloops[6] = timeEnd - timeBeg - twaiter; timeall[6] = timeEnd - timeBeg; performance[6] = (timeEnd - timeBeg - twaiter) * 100.0f / (timeEnd - timeBeg); message6 = ("Sink: " + (sinks.Count).ToString() + "; " + (timeEnd - timeBeg - twaiter).ToString() + "; " + (performance[6]).ToString() + "% "); } }
public IEnumerator BoolChecker() { // additional conditions check to set bool values while (true) { int maxatt = 0; for (int i = 0; i < unitss.Count; i++) { GameObject obj = unitss[i]; UnitParsFree objPars = obj.GetComponent <UnitParsFree>(); // Atackable modifications if (objPars.noAttackers > maxatt) { maxatt = objPars.noAttackers; } if ((objPars.isAttackable == true) && (objPars.noAttackers > objPars.maxAttackers)) { objPars.isAttackable = false; } else if ((objPars.isAttackable == false) && (objPars.noAttackers < objPars.maxAttackers)) { objPars.isAttackable = true; } } // total performance calculation from Battle System timeloops[0] = timeloops[1] + timeloops[2] + timeloops[3] + timeloops[4] + timeloops[5] + timeloops[6]; timeall[0] = timeall[1] + timeall[2] + timeall[3] + timeall[4] + timeall[5] + timeall[6]; performance[0] = (performance[1] + performance[2] + performance[3] + performance[4] + performance[5] + performance[6]) / 6.0f; message = ("BSystem: " + (unitss.Count).ToString() + "; " // + (timeEnd-timeBeg-twaiter).ToString() + "; " + (timeloops[0]).ToString() + "; " + (timeall[0]).ToString() + "; " + (performance[0]).ToString() + "% "); yield return(new WaitForSeconds(0.5f)); } }
public void ResetSearching(GameObject go) { UnitParsFree goPars = go.GetComponent <UnitParsFree>(); goPars.isApproaching = false; goPars.isAttacking = false; goPars.target = null; go.GetComponent <UnityEngine.AI.NavMeshAgent>().SetDestination(go.transform.position); if (goPars.changeMaterial) { go.GetComponent <Renderer>().material.color = Color.yellow; } goPars.isReady = true; }
// Death phase unset all unit activity and prepare to die public IEnumerator DeathPhase() { float timeBegin, timeEnd; while (true) { timeBegin = Time.realtimeSinceStartup; // Getting dying units for (int i = 0; i < deadUnits.Count; i++) { GameObject dead = deadUnits[i]; UnitParsFree deadPars = dead.GetComponent <UnitParsFree>(); // If unit is dead long enough, prepare for rotting (sinking) phase and removing from the aliveUnits list if (deadPars.deathCalls > UnitParsFree.maxDeathCalls) { deadPars.setSinking(); sinkingUnits.Add(dead); deadUnits.RemoveAt(i--); } else { deadPars.deathCalls++; } } timeEnd = Time.realtimeSinceStartup; yield return(new WaitForSeconds(1.0f)); timeloops[5] = timeEnd - timeBegin; timeall[5] = timeloops[5] + 1.0f; performance[5] = timeloops[5] * 100.0f / timeall[5]; message5 = "Dead: " + deadUnits.Count.ToString() + "; " + timeloops[5].ToString() + "; " + performance[5].ToString() + "%"; } }
public IEnumerator MakeBox() { // if(createFakeObject == true){ // for(int i=0;i<2;i=i+1){ // GameObject cubeSpawn = (GameObject)Instantiate(fakeObject, new Vector3(-9999999999999.99f-9999.99f*Random.Range(-1.0f,1.0f),-9999999999999.99f-9999.99f*Random.Range(-1.0f,1.0f),-9999999999999.99f-9999.99f*Random.Range(-1.0f,1.0f)), transform.rotation); // // cubeSpawn.GetComponent<UnitParsFree>().isReady = true; // bs.unitsBuffer.Add(cubeSpawn); // } // } // // for (int i = 0; i < numberOfObjects; i = i + 1) { readynow = false; yield return(new WaitForSeconds(timestep)); Vector3 pos = new Vector3(transform.position.x + Random.Range(-size, size) + 5, transform.position.y, transform.position.z + Random.Range(-size, size)); pos = TerrainVector(pos, ter); GameObject cubeSpawn = (GameObject)Instantiate(box, pos, transform.rotation); UnitParsFree up = cubeSpawn.GetComponent <UnitParsFree>(); if (up != null) { up.isReady = true; } bs.unitsBuffer.Add(cubeSpawn); readynow = true; count = count + 1; } }
// Attacking phase set attackers to attack their targets and cause damage when they already approached their targets public IEnumerator AttackPhase() { float timeBegin, timeEnd; var deadUnitsLocal = new List <GameObject>(); while (true) { timeBegin = Time.realtimeSinceStartup; int attackerCounter = 0; deadUnitsLocal.Clear(); // checking through main aliveUnits array which units are set to approach (isAttacking) for (int i = 0; i < aliveUnits.Count; i++) { GameObject att = aliveUnits[i]; UnitParsFree attPars = att.GetComponent <UnitParsFree>(); if (attPars.mode != Mode.ATTACK) { continue; } attackerCounter++; GameObject targ = attPars.target; UnitParsFree targPars = targ.GetComponent <UnitParsFree>(); if (targPars.mode >= Mode.DEAD) { attPars.setSearch(); continue; } // If attack passes target through target defence, cause damage to target if (Random.value > 0.5) { targPars.health -= 20f * Random.value; if (targPars.health < 0.0f) { targPars.mode = Mode.DEAD; deadUnitsLocal.Add(targ); } } } for (int i = 0; i < deadUnitsLocal.Count; ++i) { deadUnits.Add(deadUnitsLocal[i]); aliveUnits.Remove(deadUnitsLocal[i]); deadUnitsLocal[i].GetComponent <UnitParsFree>().setDead(); } timeEnd = Time.realtimeSinceStartup; yield return(new WaitForSeconds(1.0f)); timeloops[3] = timeEnd - timeBegin; timeall[3] = timeloops[3] + 1.0f; performance[3] = timeloops[3] * 100.0f / timeall[3]; message3 = "Attacker: " + attackerCounter.ToString() + "; " + timeloops[3].ToString() + "; " + timeall[3].ToString() + "%"; } }
// this phase starting attackers to move towards their targets public IEnumerator ApproachTargetPhase() { float timeBegin, timeEnd; while (true) { timeBegin = Time.realtimeSinceStartup; int approachCounter = 0; for (int i = 0; i < aliveUnits.Count; i++) { GameObject appr = aliveUnits[i]; UnitParsFree apprPars = appr.GetComponent <UnitParsFree>(); if (apprPars.mode != Mode.APPROACH) { continue; } approachCounter++; GameObject targ = apprPars.target; if (targ.GetComponent <UnitParsFree>().mode >= Mode.DEAD) { apprPars.setSearch(); continue; } if (appr.GetComponent <NavMeshAgent>().remainingDistance < 0.5f) { apprPars.setSearch(); continue; } // distance between approacher and target var distance = Vector3.Distance(appr.transform.position, targ.transform.position); // counting increased distances (failure to approach) between attacker and target; // if counter failedR becomes bigger than critFailedR, preparing for new target search. if (apprPars.previousTargetDistance < distance) { ++apprPars.failedReachTarget; if (apprPars.failedReachTarget > UnitParsFree.maxFailedReachTarget) { apprPars.setSearch(); continue; } } else { apprPars.failedReachTarget = 0; } // saving previous R apprPars.previousTargetDistance = distance; } // main coroutine wait statement and performance information collection from approach coroutine timeEnd = Time.realtimeSinceStartup; yield return(new WaitForSeconds(1.0f)); timeloops[2] = timeEnd - timeBegin; timeall[2] = timeloops[2] + 1.0f; performance[2] = timeloops[2] * 100.0f / timeall[2]; message2 = "Approacher: " + approachCounter.ToString() + "; " + timeloops[2].ToString() + "; " + performance[2].ToString() + "%"; } }
public IEnumerator DeathPhase() { // Death phase unset all unit activity and prepare to die float timeBeg; float timeEnd; float twaiter; while (true) { timeBeg = Time.realtimeSinceStartup; int noDeads = 0; twaiter = 0.0f; // Getting dying units for (int i = 0; i < unitss.Count; i++) { GameObject dead = unitss[i]; UnitParsFree deadPars = dead.GetComponent <UnitParsFree>(); if (deadPars.isDying == true) { // If unit is dead long enough, prepare for rotting (sinking) phase and removing from the unitss list if (deadPars.deathCalls > deadPars.maxDeathCalls) { deadPars.isDying = false; deadPars.isSinking = true; dead.GetComponent <UnityEngine.AI.NavMeshAgent>().enabled = false; sinks.Add(dead); unitss.Remove(dead); int alliance = deadPars.alliance; runits[alliance].Remove(dead); rfunits[alliance].Remove(dead); } // unsetting unit activity and keep it dying else { deadPars.isMovable = false; deadPars.isReady = false; deadPars.isApproaching = false; deadPars.isAttacking = false; deadPars.isApproachable = false; deadPars.isAttackable = false; deadPars.isHealing = false; deadPars.target = null; // unselecting deads dead.SendMessage("OnUnselected", SendMessageOptions.DontRequireReceiver); dead.transform.gameObject.tag = "Untagged"; // unsetting attackers /* GameObject attTemp; * for(int j=0;j<deadPars.attackers.Count;j++){ * * attTemp = deadPars.attackers[j]; * UnitParsFree attTempPars = attTemp.GetComponent<UnitParsFree>(); * * if((attTempPars.isDying == false)&&(attTempPars.isSinking == false)){ * attTemp.GetComponent<NavMeshAgent>().SetDestination(attTemp.transform.position); * attTempPars.isReady = true; * attTempPars.isApproaching = false; * attTempPars.isAttacking = false; * } * } * deadPars.attackers.Clear(); */ dead.GetComponent <UnityEngine.AI.NavMeshAgent>().SetDestination(dead.transform.position); deadPars.deathCalls = deadPars.deathCalls + 1; if (deadPars.changeMaterial) { dead.GetComponent <Renderer>().material.color = Color.blue; } noDeads = noDeads + 1; } } } // main coroutine wait statement and performance information collection from death coroutine twaiter = twaiter + 1.0f; yield return(new WaitForSeconds(1.0f)); timeEnd = Time.realtimeSinceStartup; timeloops[5] = timeEnd - timeBeg - twaiter; timeall[5] = timeEnd - timeBeg; performance[5] = (timeEnd - timeBeg - twaiter) * 100.0f / (timeEnd - timeBeg); message5 = ("Dead: " + (noDeads).ToString() + "; " + (timeEnd - timeBeg - twaiter).ToString() + "; " + (performance[5]).ToString() + "; "); } }
public IEnumerator SelfHealingPhase() { // Self-Healing phase heals damaged units over time float timeBeg; float timeEnd; float twaiter; while (true) { timeBeg = Time.realtimeSinceStartup; int noSelfHealers = 0; twaiter = 0.0f; // checking which units are damaged for (int i = 0; i < unitss.Count; i++) { GameObject sheal = unitss[i]; UnitParsFree shealPars = sheal.GetComponent <UnitParsFree>(); if (shealPars.health < shealPars.maxHealth) { // if unit has less health than 0, preparing it to die if (shealPars.health < 0.0f) { shealPars.isHealing = false; shealPars.isImmune = true; shealPars.isDying = true; } // healing unit else { shealPars.isHealing = true; shealPars.health = shealPars.health + shealPars.selfHealFactor; noSelfHealers = noSelfHealers + 1; // if unit health reaches maximum, unset self-healing if (shealPars.health >= shealPars.maxHealth) { shealPars.health = shealPars.maxHealth; shealPars.isHealing = false; noSelfHealers = noSelfHealers - 1; } } } } // main coroutine wait statement and performance information collection from self-healing coroutine twaiter = twaiter + 3.0f; yield return(new WaitForSeconds(3.0f)); timeEnd = Time.realtimeSinceStartup; timeloops[4] = timeEnd - timeBeg - twaiter; timeall[4] = timeEnd - timeBeg; performance[4] = (timeEnd - timeBeg - twaiter) * 100.0f / (timeEnd - timeBeg); message4 = ("SelfHealing: " + (noSelfHealers).ToString() + "; " + (timeEnd - timeBeg - twaiter).ToString() + "; " + (performance[4]).ToString() + "% "); } }
public IEnumerator AttackPhase() { // Attacking phase set attackers to attack their targets and cause damage when they already approached their targets float timeBeg; float timeEnd; float twaiter; float ax; float ay; float az; float tx; float ty; float tz; float Rtarget; float stopDist = 2.5f; float stoppDistance; float tempRand = 0.0f; float tempStrength = 1.0f; float tempDefence = 1.0f; while (true) { timeBeg = Time.realtimeSinceStartup; twaiter = 0.0f; int noAttackers = 0; // checking through main unitss array which units are set to approach (isAttacking) for (int i = 0; i < unitss.Count; i++) { GameObject att = unitss[i]; UnitParsFree attPars = att.GetComponent <UnitParsFree>(); if (attPars.isAttacking) { GameObject targ = attPars.target; UnitParsFree targPars = targ.GetComponent <UnitParsFree>(); ax = att.transform.position.x; ay = att.transform.position.y; az = att.transform.position.z; tx = targ.transform.position.x; ty = targ.transform.position.y; tz = targ.transform.position.z; UnityEngine.AI.NavMeshAgent attNav = att.GetComponent <UnityEngine.AI.NavMeshAgent>(); UnityEngine.AI.NavMeshAgent targNav = targ.GetComponent <UnityEngine.AI.NavMeshAgent>(); attNav.stoppingDistance = attNav.radius / (att.transform.localScale.x) + targNav.radius / (targ.transform.localScale.x); // distance between attacker and target Rtarget = Mathf.Sqrt((tx - ax) * (tx - ax) + (ty - ay) * (ty - ay) + (tz - az) * (tz - az)); stoppDistance = (stopDist + att.transform.localScale.x * targ.transform.localScale.x * attNav.stoppingDistance); // if target moves away, resetting back to approach target phase if (Rtarget > stoppDistance) { attPars.isApproaching = true; attPars.isAttacking = false; } // if targets becomes immune, attacker is reset to start searching for new target else if (targPars.isImmune == true) { attPars.isAttacking = false; attPars.isReady = true; targPars.attackers.Remove(att); targPars.noAttackers = targPars.noAttackers - 1; if (attPars.changeMaterial) { att.GetComponent <Renderer>().material.color = Color.yellow; } } // attacker starts attacking their target else { noAttackers = noAttackers + 1; if (attPars.changeMaterial) { att.GetComponent <Renderer>().material.color = Color.red; } tempRand = Random.value; tempStrength = attPars.strength; tempDefence = attPars.defence; // if attack passes target through target defence, cause damage to target if (tempRand > (tempStrength / (tempStrength + tempDefence))) { targPars.health = targPars.health - 2.0f * tempStrength * Random.value; } } } } // main coroutine wait statement and performance information collection from attack coroutine twaiter = twaiter + 1.5f; yield return(new WaitForSeconds(1.5f)); timeEnd = Time.realtimeSinceStartup; timeloops[3] = timeEnd - timeBeg - twaiter; timeall[3] = timeEnd - timeBeg; performance[3] = (timeEnd - timeBeg - twaiter) * 100.0f / (timeEnd - timeBeg); message3 = ("Attacker: " + (noAttackers).ToString() + "; " + (timeEnd - timeBeg - twaiter).ToString() + "; " + (performance[3]).ToString() + "% "); } }
public IEnumerator ApproachTargetPhase() { // this phase starting attackers to move towards their targets float timeBeg; float timeEnd; float t3; float twaiter; float ax; float ay; float az; float tx; float ty; float tz; float Rtarget; float stopDist = 2.0f; float stoppDistance; while (true) { timeBeg = Time.realtimeSinceStartup; int noApproachers = 0; int ii = 0; t3 = Time.realtimeSinceStartup; twaiter = 0.0f; // checking through main unitss array which units are set to approach (isApproaching) for (int i = 0; i < unitss.Count; i++) { GameObject appr = unitss[i]; UnitParsFree apprPars = appr.GetComponent <UnitParsFree>(); ii = ii + 1; if (apprPars.isApproaching) { GameObject targ = apprPars.target; UnityEngine.AI.NavMeshAgent apprNav = appr.GetComponent <UnityEngine.AI.NavMeshAgent>(); UnityEngine.AI.NavMeshAgent targNav = targ.GetComponent <UnityEngine.AI.NavMeshAgent>(); if (targ.GetComponent <UnitParsFree>().isApproachable == true) { ax = appr.transform.position.x; ay = appr.transform.position.y; az = appr.transform.position.z; tx = targ.transform.position.x; ty = targ.transform.position.y; tz = targ.transform.position.z; // stopping condition for NavMesh apprNav.stoppingDistance = apprNav.radius / (appr.transform.localScale.x) + targNav.radius / (targ.transform.localScale.x); // distance between approacher and target Rtarget = Mathf.Sqrt((tx - ax) * (tx - ax) + (ty - ay) * (ty - ay) + (tz - az) * (tz - az)); stoppDistance = (stopDist + appr.transform.localScale.x * targ.transform.localScale.x * apprNav.stoppingDistance); // counting increased distances (failure to approach) between attacker and target; // if counter failedR becomes bigger than critFailedR, preparing for new target search. if (apprPars.prevR < Rtarget) { apprPars.failedR = apprPars.failedR + 1; if (apprPars.failedR > apprPars.critFailedR) { apprPars.isApproaching = false; apprPars.isReady = true; apprPars.failedR = 0; if (apprPars.changeMaterial) { appr.GetComponent <Renderer>().material.color = Color.yellow; } } } else { // if approachers already close to their targets if (Rtarget < stoppDistance) { apprNav.SetDestination(appr.transform.position); // pre-setting for attacking apprPars.isApproaching = false; apprPars.isAttacking = true; } else { if (apprPars.changeMaterial) { appr.GetComponent <Renderer>().material.color = Color.green; } // starting to move if (apprPars.isMovable) { noApproachers = noApproachers + 1; apprNav.SetDestination(targ.transform.position); apprNav.speed = 3.5f; } // performance waiter for long approacher lists if (ii > 1500) { if (Time.realtimeSinceStartup - t3 > 0.005f) { twaiter = twaiter + 0.1f * (Time.realtimeSinceStartup - t3) + 0.05f; yield return(new WaitForSeconds(0.1f * (Time.realtimeSinceStartup - t3) + 0.05f)); t3 = Time.realtimeSinceStartup; ii = 0; } } } } // saving previous R apprPars.prevR = Rtarget; } // condition for non approachable targets else { apprPars.target = null; apprNav.SetDestination(appr.transform.position); apprPars.isApproaching = false; apprPars.isReady = true; if (apprPars.changeMaterial) { appr.GetComponent <Renderer>().material.color = Color.yellow; } } } } // main coroutine wait statement and performance information collection from approach coroutine timeEnd = Time.realtimeSinceStartup; twaiter = twaiter + 1.0f * (timeEnd - timeBeg) + 1.0f; yield return(new WaitForSeconds(1.0f * (timeEnd - timeBeg) + 1.0f)); float curTime = Time.realtimeSinceStartup; timeloops[2] = curTime - timeBeg - twaiter; timeall[2] = curTime - timeBeg; performance[2] = (curTime - timeBeg - twaiter) * 100.0f / (curTime - timeBeg); message2 = ("Approacher: " + (noApproachers).ToString() + "; " + (curTime - timeBeg - twaiter).ToString() + "; " + (performance[2]).ToString() + "% "); } }
// ManualMover controls unit if it is selected and target is defined by player public IEnumerator ManualMover() { float r; float ax; float ay; float az; float tx; float ty; float tz; while (true) { for (int i = 0; i < unitss.Count; i++) { GameObject obj = unitss[i]; ManualControlFree objSel = obj.GetComponent <ManualControlFree>(); UnitParsFree objPars = obj.GetComponent <UnitParsFree>(); if (objSel.isMoving) { ax = obj.transform.position.x; ay = obj.transform.position.y; az = obj.transform.position.z; tx = objSel.manualDestination.x; ty = objSel.manualDestination.y; tz = objSel.manualDestination.z; r = Mathf.Sqrt((tx - ax) * (tx - ax) + (ty - ay) * (ty - ay) + (tz - az) * (tz - az)); if (r >= objSel.prevDist) { objSel.failedDist = objSel.failedDist + 1; if (objSel.failedDist > objSel.critFailedDist) { objSel.failedDist = 0; objSel.isMoving = false; ResetSearching(obj); } } objSel.prevDist = r; } if (objSel.prepareMoving) { if (objPars.isMovable) { UnSetSearching(obj); objSel.prepareMoving = false; objSel.isMoving = true; obj.GetComponent <UnityEngine.AI.NavMeshAgent>().SetDestination(objSel.manualDestination); } } } yield return(new WaitForSeconds(0.5f)); } }