Home > Net >  How to switch between the OnTriggerExit/Enter logic depending on the situation?
How to switch between the OnTriggerExit/Enter logic depending on the situation?

Time:06-07

The script is attached to two gameobjects.

One it's colliding area the collider is big enough so when the game start the player is already inside the collider area and then when he exit the area everything is working fine.

The problem is when I attached the object to another gameobject with collider but this time the collider s smaller and he is inside the bigger collider so now the player is entering the smaller collider and not first time exiting. but I want in both case to make the same effect.

If the player exit the collider he slow down wait then turn around and move inside back. The same I want to make when the player getting closer to the fire flames slow down wait turn around and move back in it's just with the flames the player entering the collider area and then exit while in the bigger collider he first exit then enter.

Screenshot of the two colliders areas. The small one on the left is the one the player entering first and not exiting. The game start when the player is in the bigger collider area.

Colliders areas

And the script :

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;

public class DistanceCheck : MonoBehaviour
{
    public Transform targetToRotateTowards;
    public Transform colliderArea;
    public float lerpDuration;
    public float rotationSpeed;
    [TextArea(1, 2)]
    public string textToShow;
    public GameObject descriptionTextImage;
    public TextMeshProUGUI text;
    public ThirdPersonUserControl thirdPersonUserControl;

    private Animator anim;
    private float timeElapsed = 0;
    private float startValue = 1;
    private float endValue = 0;
    private float valueToLerp = 0;
    private bool startRotating = false;
    private bool slowOnBack = true;
    private bool exited = false;
    private Vector3 exitPosition;
    private float distance;

    void Start()
    {
        anim = transform.GetComponent<Animator>();
    }

    private void FixedUpdate()
    {
        if (startRotating)
        {
            transform.rotation = Quaternion.RotateTowards(transform.rotation,
    Quaternion.LookRotation(targetToRotateTowards.position - transform.position),
    rotationSpeed * Time.deltaTime);
        }

        if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
        {
            distance = Vector3.Distance(transform.position, exitPosition);
        }

        if (distance > 5 && slowOnBack)
        {
            slowOnBack = false;
            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.name == colliderArea.name)
        {
            exited = true;
            slowOnBack = true;
            exitPosition = transform.position;
            thirdPersonUserControl.enabled = false;
            descriptionTextImage.SetActive(true);
            text.text = textToShow;
            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.name == colliderArea.name)
        {
            exited = false;
            startRotating = false;
            text.text = "";
            descriptionTextImage.SetActive(false);
        }
    }

    IEnumerator SlowDown()
    {
        timeElapsed = 0;

        while (timeElapsed < lerpDuration)
        {
            valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed  = Time.deltaTime;

            yield return null;
        }

        if (exited)
        {
            yield return new WaitForSeconds(3f);

            startRotating = true;
            StartCoroutine(SpeedUp());
        }

        if (slowOnBack == false)
        {
            thirdPersonUserControl.enabled = true;
        }
    }

    IEnumerator SpeedUp()
    {
        timeElapsed = 0;

        while (timeElapsed < lerpDuration)
        {
            valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
            anim.SetFloat("Forward", valueToLerp);
            timeElapsed  = Time.deltaTime;

            yield return null;
        }
    }
}

Two problems I'm facing right now :

  • The smaller collider the player enter it then exit and the bigger collider the player exit it then enter so I need to change somehow the OnTriggerExit/Enter behavior logic in the script. but how to make the logic ?

  • Maybe it's better to make the script to be on the player object only and make it some how generic so I can drag to it many colliders and to make the effect in each one of the colliders the problem is how to make a text field for each collider area ? Now because I attach the script to each collider object I have one colliderArea variable but if I want to make the script only attached to the player I need to change the colliderArea variable to a List<Transform> collidersAreas and then how to create a text field/area to each collider area in the List ?

CodePudding user response:

I think I would do this by creating two tags, NoExit and NoEntry. Once the tags are created you can set the tag on the GameObjects that hold your colliders. Then you can check for tags in the OnTriggerEnter and OnTriggerExit and act accordingly.

I can't tell for sure which functionality you've got written is for which case, or if it's both - everything looks muddled. Ultimately what you should be going for is a function like RepositionPlayer, that moves them back to before they're violating the no entry or no exit rules, and then some kind of OnPlayerRepositioned event that restores their control.

I'll leave it up to you to split out your functionality, but in general I'd look to do something like the following:

private void OnTriggerExit(Collider other)
{
    if (other.tag == "NoExit")
    {
        RepositionPlayer();
    }
    else if(other.tag == "NoEntry")
    {
        OnPlayerRepositioned();
    }
}

private void OnTriggerEnter(Collider other)
{
    if (other.tag == "NoExit")
    {
        OnPlayerRepositioned();
    }
    else if(other.tag == "NoEntry")
    {
        RepositionPlayer();
    }
}

And again here it's not clear to me what you're trying to do to reposition the player, but it looks like it's something like:

private void RepositionPlayer()
{
    // Stuff that needs to happen to reposition the player
    exited = true;
    slowOnBack = true;
    exitPosition = transform.position;
    thirdPersonUserControl.enabled = false;
    descriptionTextImage.SetActive(true);
    text.text = textToShow;
    StartCoroutine(SlowDown());
}

private void OnPlayerRepositioned()
{
    // stuff you need to do to clear the "repositioning" status
    exited = false;
    startRotating = false;
    text.text = "";
    descriptionTextImage.SetActive(false);
}

Splitting up the logic like this makes it easier to both read and maintain.

  • Related