- Home /
Problem with Collision (3D)
I have an magma pool in my game and i want that the player getting damage while standing inside it. The problem is the collision detection doesn't work. The while loop never get called. My Player has a sphere collider and is named "Player". Thank you for ur help :) Here is my code thats on my "magma", it has a box collider on "Is Trigger" and a rigidbody:
public class CollisionDamage : MonoBehaviour
{
public bool colWithObject;
void Update()
{
StartCoroutine(TouchDamage());
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "Player")
{
colWithObject = true;
}
}
private void OnCollisionExit(Collision collision)
{
colWithObject = false;
}
IEnumerator TouchDamage()
{
while (colWithObject == true)
{
Debug.Log("Damage");
yield return new WaitForSeconds(1);
}
}
}
Answer by KoenigX3 · Jun 02, 2020 at 07:59 AM
Starting coroutines on Update is a bad idea. At 60 FPS, you are going to start 60 coroutines per second. However, it's not the cause of your main problem.
Your while loop won't stay there forever. If the condition is false, your coroutine ends.
You can solve your problem in two ways. If your magma pool is solid, and your character needs to collide with it, and be damaged when touches it, you simply need to uncheck IsTrigger and start your coroutine from OnCollisionEnter.
public class CollisionDamage : MonoBehaviour
{
Coroutine damageCoroutine;
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "Player") damageCoroutine = StartCoroutine(TouchDamage());
}
private void OnCollisionExit(Collision collision)
{
StopCoroutine(damageCoroutine);
}
IEnumerator TouchDamage()
{
while(true)
{
Debug.Log("Damage");
yield return new WaitForSeconds(1);
}
}
}
If your character can submerge in the magma pool, you probably need to set your collider to Trigger, and use OnTriggerEnter and OnTriggerExit instead of OnCollisionEnter and OnCollisionExit. Keep in mind that those callbacks return different parameters, you can check them at UnityDocs. The rest of the code remains the same.
Answer by Artik2442 · Jun 02, 2020 at 08:02 AM
I think this might be because your StartCoroutine(TouchDamage()) is in the Update method. There is nothing that can stop it. You are doing a while loop into an Update method.
Its better to use:
public class CollisionDamage : MonoBehaviour
{
public bool colWithObject;
public bool canDamage;
void Update()
{
if (colWithObject && canDamage) // If there is a collision and you can Damage you can start damaging
{
StartCoroutine(TouchDamage());
}
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "Player")
{
colWithObject = true;
}
}
private void OnCollisionExit(Collision collision)
{
colWithObject = false;
}
IEnumerator TouchDamage() // Now, you have to wait 1 seconds before recalling this function
{
canDamage = false;
Debug.Log("Damage");
yield return new WaitForSeconds(1);
canDamage = true;
}
}
It is maybe a OnTriggerEnter and OnTriggerExit you should use if your magma pool collider is trigger.