Home > Software engineering >  How to detect if the player has entered the drawn circle radius area in the Update each time once?
How to detect if the player has entered the drawn circle radius area in the Update each time once?

Time:05-13

This part either in edit mode or runtime keep displaying in the console the debug.log nonstop.

private void Update()
        {
            if (Physics.CheckSphere(transform.position, xRadius, targetLayers))
            {
                Debug.Log("player detected");
            }
            else
            {
                Debug.Log("player NOT detected");
            }
        }

I want that if the player detected display the "player detected" once then of the player has exited and not detected display the other text once until the player will enter again and will be detected and then display the detected once again.

Each time to display it once and not nonstop. THe problem is that it's in the Update.

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

[ExecuteAlways]
[RequireComponent(typeof(UnityEngine.LineRenderer))]
public class DrawCircle : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 500)] public float xRadius = 5;
    [Range(1, 500)] public float yRadius = 5;
    [Range(0.1f, 5)] public float width = 0.1f;
    [Range(0, 100)] public float height = 0;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LayerMask targetLayers;
    [SerializeField] private LineRenderer line;

    private void Start()
    {
        if (!line) line = GetComponent<LineRenderer>();

        if (draw)
            CreatePoints();
    }

    private void Update()
    {
        if (Physics.CheckSphere(transform.position, xRadius, targetLayers))
        {
            Debug.Log("player detected");
        }
        else
        {
            Debug.Log("player NOT detected");
        }
    }

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments   1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments   1];

        for (int i = 0; i < segments   1; i  )
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, height, y);

            angle  = (380f / segments);
        }

        // it's way more efficient to do this in one go!
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;
    private float prevHeight;

    private void OnValidate()
    {
        // Can't set up our line if the user hasn't connected it yet.
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            // instead simply disable the component
            line.enabled = false;
        }
        else
        {
            // Otherwise re-enable the component
            // This will simply re-use the previously created points
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth || height != prevHeight)
            {
                CreatePoints();

                // Cache our most recently used values.
                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
                prevHeight = height;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;

                CreatePoints();
            }
        }
    }
#endif
}

CodePudding user response:

In this case I would use a sort of mini state machine (easy to extend in the future and looks nice). Though you really just need a member variable to keep track of state.


private enum states {
    inSphere,
    outSphere
}

states state = states.outSphere;

private void Update() {
        
    switch(state) {
        case states.outSphere:
            if (Physics.CheckSphere(transform.position, xRadius, targetLayers)) {
                Debug.Log("player detected");
                state = states.inSphere;
            }
            break;
        case states.inSphere:
            if (!Physics.CheckSphere(transform.position, xRadius, targetLayers)) {
                Debug.Log("player NOT detected");
                state = states.outSphere;
            }
            break;
    }
}
  • Related