每次Update中如何检测玩家是否进入绘制的圆半径区域一次?

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

这部分无论是在编辑模式下还是运行时都在控制台中不停的显示debug.log。

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

我希望如果检测到玩家显示一次“检测到玩家”然后玩家退出并且未检测到显示其他文本一次直到玩家再次进入并被检测到然后再次显示检测到.

每次显示一次,不间断。问题是它在更新中。

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
}

在这种情况下,我会使用一种迷你状态机(将来易于扩展并且看起来不错)。虽然你真的只需要一个成员变量来跟踪状态。


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