I am trying to learn unity. This is something I would use in Javascript so I was hoping to find a way to do this in C#, where you take the collision variable and use the reference to have another function clean up the variables after you are finished.
private void OnTriggerEnter(Collider collision) {
if(collision.gameObject.CompareTag("Enemy")) {
collision.gameObject.GetComponent<enemy>().powerup = 1;
StartCoroutine(removePower(collision.gameObject.GetComponent<enemy>()));
Destroy(gameObject);
}
if (collision.gameObject.CompareTag("Player")) {
collision.gameObject.GetComponent<player>().powerup = 1;
StartCoroutine(removePower(collision.gameObject.GetComponent<player>()));
Destroy(gameObject);
}
}
IEnumerator removePower(GameObject target) {
yield return new WaitForSeconds(5);
target.powerup = 0;
}
Note: Coroutines are also stopped when the MonoBehaviour is destroyed or if the GameObject the MonoBehaviour is attached to is disabled.
You should destroy the gameobject when the coroutine finishes.
StartCoroutine(removePower(collision.gameObject.GetComponent<enemy>()));
//Destroy(gameObject);
IEnumerator removePower(GameObject target) {
yield return new WaitForSeconds(5);
target.powerup = 0;
Destroy(gameObject);
}
Or run the coroutine on another gameobject
var enemy = collision.gameObject.GetComponent<enemy>();
enemy.StartCoroutine(removePower(enemy));
First if all there is a general flaw in your approach: When you
Destroy(gameObject);
this object this component is attached to then also all Coroutines are immediately canceled.
I would therefore start the coroutine rather on the target itself.
And then your classes should have a common interface or base class like for example
public abstract class Character : MonoBehaviour
{
public float powerup;
// And other common members
}
And then you inherit
public class Player : Character
{
// Additional player specific stuff
}
and
public class Enemy : Character
{
// Additional enemy specific stuff
}
OR if you rather want to go for an interface
public interface ICharacter
{
float powerup { get; set; }
}
And then both your classes have to implement that
public class Player : MonoBehaviour, ICharacter
{
public float powerup { get; set; }
// Additional player specific stuff
}
and
public class Enemy : MonoBehaviour, ICharacter
{
public float powerup { get; set; }
// Additional player specific stuff
}
And then your collision code could simply be
private void OnTriggerEnter(Collider collision)
{
// TryGetComponent now finds anything inherited from Character
// you don't even need to check the tags
if(collision.TryGetComponent<Character>(out var character))
// Or if using the interface
//if(collision.TryGetComponent<ICharacter>(out var character)
{
// Let the character run this coroutine without even having to know what it does
character.StartCoroutine(PowerUpRoutine(character));
Destroy(gameObject);
}
}
IEnumerator PowerUpRoutine(Character target)
{
target.powerup = 1;
yield return new WaitForSeconds(5);
target.powerup = 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.