I'm having an issue with my light system in my game made with unity, where I'm trying to stop the enemy when he touches the light emitted by the player, but when he touches the light, the enterTrigger and exitTrigger functions are called many times simultaneously. I think that maybe it's caused by the way I'm handling the light in the update method.
Player script
public class Player : MonoBehaviour
{
#region Light
[Header("Light Settings")]
private bool lightOn;
public GameObject lightUp;
public GameObject lightDown;
public GameObject lightLeft;
public GameObject lightRight;
#endregion
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
batterySystem.UpdateBatteryUI();
if (canMove)
{
HandleMovement();
HandleLantern();
batterySystem.HandleBatteryUsage(lightOn);
if (Input.GetKey(KeyCode.Q))
{
batterySystem.HandleBatteryRecharge();
}
if (Input.GetKeyUp(KeyCode.Q))
{
batterySystem.CancelRecharge();
}
}
}
#region Light Methods
public void HandleLantern()
{
if (Input.GetKeyDown(KeyCode.R) && batterySystem.batteryCount > 0)
{
lightOn = !lightOn;
anim.SetBool("Light", lightOn);
if (lightOn)
{
UpdateLightDirection(lastMove);
}
else
{
DisableAllLights();
}
}
}
private void UpdateLightDirection(Vector2 direction)
{
DisableAllLights();
if (Mathf.Abs(direction.x) > Mathf.Abs(direction.y))
{
if (direction.x > 0)
{
lightRight.SetActive(true);
}
else if (direction.x < 0)
{
lightLeft.SetActive(true);
}
}
else
{
if (direction.y > 0)
{
lightUp.SetActive(true);
}
else if (direction.y < 0)
{
lightDown.SetActive(true);
}
}
}
private void DisableAllLights()
{
lightUp.SetActive(false);
lightDown.SetActive(false);
lightLeft.SetActive(false);
lightRight.SetActive(false);
}
public void TurnOffLight()
{
lightOn = false;
anim.SetBool("Light", false);
DisableAllLights();
}
#endregion
}
Enemy Script
public class FollowEnemy : MonoBehaviour
{
public float speed;
public float defaultSpeed;
private float distance;
public float minimumDistance;
public float attackDistance;
public bool canMove = true;
void Start()
{
defaultSpeed = speed;
}
void Update()
{
Walk();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Light"))
{
canMove = false;
speed = 0f;
Debug.Log("Entered Light Trigger");
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Light"))
{
canMove = true;
speed = defaultSpeed;
Debug.Log("Exited Light Trigger");
}
}
private void Walk()
{
if (canMove)
{
distance = Vector2.Distance(transform.position, GameObject.FindGameObjectWithTag("Player").transform.position);
Vector2 direction = GameObject.FindGameObjectWithTag("Player").transform.position - transform.position;
direction.Normalize();
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (distance < minimumDistance)
{
transform.position = Vector2.MoveTowards(this.transform.position, GameObject.FindGameObjectWithTag("Player").transform.position, speed * Time.deltaTime);
transform.rotation = Quaternion.Euler(Vector3.forward * angle);
}
if (distance < attackDistance)
{
speed = 0;
}
}
}
}
I tried to disable the the triggers too, but it didn't work, the EnterTrigger2D and the ExitTrigger2d keep being called many times.
If the lights collider is inside of the trigger when you disable the light gameobject, OnTriggerExit will be called.
This is because the collider is no longer inside of the trigger collider.
When exit gets called you allow the enemy to move again.
You would need to change how this interaction works in your game to fix the issue.
One way would be to toggle the light component instead of the entire object. This would require a check to see if the light is on or off when implementing the other logic.