- Home /
Substracting Lives every n seconds on TriggerEnter
I want to create a script for my player that would substract lives every 3 seconds when enemy is in close distance, for example, distance <= 2 (enemy at this moment would play animation like he's hitting my player with stick or hammer). Given script is based on collision, but I will replace it with distance function, just haven't got that example on this PC... This example is continuously substracting lives and setting "hit" to false after 1 second...
using UnityEngine; using System.Collections;
public class NewPlayerLives : MonoBehaviour { //Fields public int lives = 10;//lives public bool hit = false;//state of being attacked //Trigger Function void OnTriggerEnter(Collider col) { if (col.tag == "enemy") { // Debug.Log("Collision with enemy detected"); hit = true; } else { hit = false; } if (DidEnemyDie()) Destroy(gameObject); //Application.LoadLevel(2);
//Destroy(gameObject);
} //Function return true if life < 0 bool DidEnemyDie() { return lives <= 0 ? true : false; } void Awake() { if(hit = true){ StartCoroutine(MyFunctionName()); } } IEnumerator MyFunctionName() { //if(hit =true) //if enemy is in close range while(true) { //if(hit =true){ lives-=1; yield return new WaitForSeconds(1); //StopCoroutine(MyFunctionName()); hit = false; //} } } }
Answer by Valdemars Magone · Mar 31, 2011 at 08:15 AM
Trying to make that OnTriggerStay work but Update is substracting lives each frame and doDamage is switching from true to false after each 2 seconds, but enemy is not even colliding with Player...
using UnityEngine; using System.Collections;
public class PlayerLivesCollisions : MonoBehaviour { //Fields public int keyStatus = 0; public int lives = 5; public Texture2D h4; public Texture2D h3; public Texture2D h2; public Texture2D h1; public Texture2D h0; public Texture2D k1; public Texture2D k2; public bool doDamage = false;
//InvokeRepeating ("DoDamage", 0,3);
void Update(){
if(doDamage = true) StartCoroutine ("Substracting");
}
IEnumerator Substracting(){ lives-=1; yield return new WaitForSeconds (2); doDamage = false; } void OnGUI() { if(lives > 8){ GUI.Label (new Rect (750,0,300,300),h4); } else if(lives > 6){ GUI.Label (new Rect (750,0,300,300),h3); } else if(lives > 4){ GUI.Label (new Rect (750,0,300,300),h2); } else if(lives > 2){ GUI.Label (new Rect (750,0,300,300),h1); } else if(lives > 0){ GUI.Label (new Rect (750,0,300,300),h0); } if(keyStatus > 0){ GUI.Label (new Rect (700,25,64,64),k1); } if(keyStatus > 1){ GUI.Label (new Rect (700,25,64,64),k2); }
}
void OnTriggerStay(Collider other){ if (other.tag == "Enemy"){ doDamage = true;
//lives-=1; //yield return new WaitForSeconds(2); }
}
//Trigger Function
void OnTriggerEnter(Collider col)
{
if (col.tag == "Enemy")
{
Debug.Log("Collision with Enemy detected");
doDamage = true;
//Decrease Life and destroy bullet
//lives -= 1;
//Destroy(col.gameObject);
}
else if (col.tag == "medKit") { Debug.Log("Mmm, extasy...");
//Decrease Life and destroy bullet
lives += 5;
Destroy(col.gameObject);
}
if (col.tag == "key1") { Debug.Log("man ir pirmaa atsleega"); gameObject.AddComponent("openStorageRoomScene1");
//Decrease Life and destroy bullet
keyStatus += 1;
Destroy(col.gameObject);
}
else if (col.tag == "key2") { Debug.Log("man ir otraa atsleega"); gameObject.AddComponent("openExitScene1");
//Decrease Life and destroy bullet
keyStatus += 1;
Destroy(col.gameObject);
}
//Check if we destroy our enemy
if (DidEnemyDie())
Application.LoadLevel(2);
//Destroy(gameObject);
}
//Function return true if life < 0
bool DidEnemyDie()
{
return lives <= 0 ? true : false;
}
//Should declare the DoDamage function here I suppose...
}
I'd say do a little reading on Coroutines and see some more examples of how they can be used. They can run faster, but are tricky. I'm surprised if(doDamage = true)
runs (single equals.) As easy trick is something this in your triggerStay: timeNear++; if(timeNear>120) { lives--; timeNear=0; }
You can then get rid of all the coroutines and doDamage
vars.
10000 Thanks, Owen!!! This is so simple and works perfect for me!!!!
Answer by Owen-Reynolds · Mar 31, 2011 at 06:21 AM
Some comments: Awake is like Start. Runs total of one time, right away (it is used for timing, for things you need to happen before someone else's Start.)
OnTriggerEnter is called once, on entering. If the enemy manages to stay on you, OnTriggerEnter won't be called again. You could try OnTriggerStay. Maybe add 1 to "ticksInRange" and take a life every 180?
I like a trick like this:
bool canAttack=true; // global
// Update/FixedUpdate or some AI function running X times/sec: if(canAttack && (player.position - transform.position).magnitude < AttackRange) { player.GetComponent<playerScript>().getHit(1); canAttack=false; StartCoroutine(AttackDelay); }
// set canAttack back to true after a while IEnumerator AttackDelay() { yield return new WaitForSeconds(3.0f); canAttack=true; }
Your answer
![](https://koobas.hobune.stream/wayback/20220613115844im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Coroutoutine doesnt work properly. 3 Answers
Pause the coroutine inside a loop 1 Answer
Last item not being moved (yield problem) 0 Answers
Instantiating many objects during update lags 1 Answer
Im a bit confused on a simple script 1 Answer