Home > Mobile >  How to make TextArea attribute field to be created for each collider when the events OnTriggerEnter
How to make TextArea attribute field to be created for each collider when the events OnTriggerEnter

Time:06-08

The script have two states NoEntry and NoExit.

The first problem is the TextToShow. When the player entered/exited a collider it was showing in the text the same text. So i changed the textToShow variable to be array type :

public string[] textToShow;

Then according to the state NoEntry/NoExit i used the TextToShow[0] and TextToShowText

What i want to do is to create for each collider for example the player entered or exited a collider, could be i have 10 colliders in the game for that case so if the player hit a collider to identify the collider and add to it some properties in the inspector.

or maybe another way but the idea is to create a TextArea for each collider so i can enter a text and to see in the inspector to what collider or when the text will show.

Same concept for example to the variable : targetToRotateTowards Now when the player exit/enter he will walk backwards and rotate facing the object in the variable targetToRotateTowards instead i want that in each collider that the player will do something else for example if the collider the state is NoExit move backward face some object but if a collider state is NoEntry so the player should move backwards facing 180 degrees back and not a specific object.

And in the general to extend the script to be more generic for more situations.

Maybe using enum with many cases ? For example if the player enter the small collider he will crash falling dead but if he exit the big collider the player will go backward rotating facing an object.

Colliders

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 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;

    public string[] TextToShow { get => textToShow; set => textToShow = value; }

    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.tag == "NoExit")
        {
            descriptionTextImage.SetActive(true);
            text.text = TextToShow[0];
            RepositionPlayer();
        }
        else if (other.tag == "NoEntry")
        {
            OnPlayerRepositioned();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "NoExit")
        {
            OnPlayerRepositioned();
        }
        else if (other.tag == "NoEntry")
        {
            descriptionTextImage.SetActive(true);
            text.text = TextToShow[1];
            RepositionPlayer();
        }
    }

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

    private void OnPlayerRepositioned()
    {
        // stuff you need to do to clear the "repositioning" status
        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;
        }
    }
}

After creating the ColliderInfo class i added to the class two properties the second one is :

public Transform rotateTowards;

The class :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColliderInfo : MonoBehaviour
{
    [TextArea] public string onEnterText, onExitText;
    public Transform rotateTowards;
}

Then in the DistanceCheck script i removed deleted the variable targetToRotateTowards and added a private ColliderInfo variable :

private ColliderInfo colliderInfo;

Then created instance in the Start :

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

And using it in the FixedUpdate :

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

The problem is that rotateTowrads is type Transform but if i want the transform to rotate by degrees and not facing the rotateTowards transform ?

The complete DistanceCheck script after changes :

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

public class DistanceCheck : MonoBehaviour
{
    public float lerpDuration;
    public float rotationSpeed;
    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;
    private ColliderInfo colliderInfo;

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

    private void FixedUpdate()
    {
        if (startRotating)
        {
            transform.rotation = Quaternion.RotateTowards(transform.rotation,
    Quaternion.LookRotation(colliderInfo.rotateTowards.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.tag == "NoExit")
        {
            descriptionTextImage.SetActive(true);
            if (other.TryGetComponent(out ColliderInfo info))
            {
                text.text = info.onExitText;
            }
            RepositionPlayer();
        }
        else if (other.tag == "NoEntry")
        {
            OnPlayerRepositioned();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "NoExit")
        {
            OnPlayerRepositioned();
        }
        else if (other.tag == "NoEntry")
        {
            descriptionTextImage.SetActive(true);
            if (other.TryGetComponent(out ColliderInfo info))
            {
                text.text = info.onEnterText;
            }
            RepositionPlayer();
        }
    }

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

    private void OnPlayerRepositioned()
    {
        // stuff you need to do to clear the "repositioning" status
        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;
        }
    }
}

CodePudding user response:

Although there are other ways to solve this problem, centralized methods such as giving all the information to the player script by expanding the project also make it more difficult to control. The best way I can suggest you is to give the colliders information themselves, so create a ColliderInfo script like the one below and place it on the target areas.

public class ColliderInfo : MonoBehaviour
{
    [TextArea] public string onEnterText, onExitText;
}

enter image description here

Once this is done, it is enough to call the information of each collider by going to that area, just as easily and with the same efficiency! The following code is written in the player and solves the problem. Keep in mind to create similar colliders just prefab them.

private void OnTriggerEnter(Collider other)
{
   if (other.TryGetComponent(out ColliderInfo info))
   {
      Debug.Log(info.onEnterText);
   }
}
private void OnTriggerExit(Collider other)
{
   if (other.TryGetComponent(out ColliderInfo info))
   {
      Debug.Log(info.onExitText);
   }
}

Extent of methods

The attribution method is not limited to text, for example you can define an enum of a general collider type to allow the player to react differently to different locations, or even to define the temperature in general.

public enum Type
{
    None,
    Hot,
    Cold,
}
public Type type = Type.Hot;

Below is an example of such a structure that instead of defining a name and tag, how can you define everything related to properties, consider never entering player rotation codes in collider info, below from an object-oriented programming perspective this property belongs To the player.

if (other.TryGetComponent(out ColliderInfo info))
{
    Debug.Log(info.onEnterText);
    switch (info.type)
    {
        case ColliderInfo.Type.Hot:
            Reposition();
            inHotArea = true; // deal damage until staying in hot area
            MeshRenderer.material.color = Color.red;
            break;
        case ColliderInfo.Type.Cold:
            inColdArea = true; // slow effect like decreasing movement speed 
            MeshRenderer.material.color = Color.cyan;
            break;
    }
}
  • Related