有什么方法可以在运行时为对撞机轮廓着色?

Is there any way to color a collider outlines at runtime?

我有一个带有盒子对撞机的空游戏对象。当我 select 空游戏对象时,它在编辑器场景视图中显示对撞机 window。但是有什么方法可以在 editor/runtime 中对碰撞器尺寸线进行着色或标记而不 select 游戏对象吗?

我想以某种方式查看并知道玩家何时 leaving/entering 碰撞区域。 问题是你在运行时看不到它。

我有两个事件,ontriggerenter 和 ontriggerexit,但我想要一些视觉效果来查看玩家何时在 leaving/entering 该区域。

private void OnTriggerExit(Collider other)
    {
        if (other.name == "Colliding Area")
        {
            GameObject go = Instantiate(positionMarkerPrefab);
            Renderer rend = go.GetComponent<Renderer>();
            rend.material.color = Color.red;

            StartCoroutine(SlowDown());
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.name == "Colliding Area")
        {
            GameObject go = Instantiate(positionMarkerPrefab);
            Renderer rend = go.GetComponent<Renderer>();
            rend.material.color = Color.black;

            if (increaseSpeed == false)
            {
                enteredPositionBack = transform.position;
            }
        }
    }

您可以使用OnDrawGizmos在运行时绘制盒子碰撞器的边界。但是这些线条只会在编辑器场景视图中可见。这是一个例子:

private BoxCollider boxCollider = null;
    
private void Start()
{
    boxCollider = GetComponent<BoxCollider>();
}

private void OnDrawGizmos()
{
    if (boxCollider)
    {
        Matrix4x4 rotationMatrix = Matrix4x4.TRS(boxCollider.transform.position, boxCollider.transform.rotation, boxCollider.transform.lossyScale);
        Gizmos.matrix = rotationMatrix;
        Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);
    }
}

不过,您可以使用线渲染器在游戏视图中可视化盒子碰撞器的边界。这是一个例子,它不是很漂亮,但它完成了工作:

private List<LineRenderer> lines = new List<LineRenderer>();

private void Start()
{
    BoxCollider boxCollider = GetComponent<BoxCollider>();
    if (boxCollider != null)
    {
        Material material = new Material(Shader.Find("Unlit/Color"));
        Color color = Color.green;
        material.color = color;
        float width = 0.01f;
        Vector3 rightDir = boxCollider.transform.right.normalized;
        Vector3 forwardDir = boxCollider.transform.forward.normalized;
        Vector3 upDir = boxCollider.transform.up.normalized;
        Vector3 center = boxCollider.transform.position + boxCollider.center;
        Vector3 size = boxCollider.size;
        size.x *= boxCollider.transform.lossyScale.x;
        size.y *= boxCollider.transform.lossyScale.y;
        size.z *= boxCollider.transform.lossyScale.z;
        DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color, material, width);
        DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
        DrawLine(center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color, material, width);
    }
}

private void DrawLine(Vector3 start, Vector3 end, Color color, Material material, float width = 0.01f)
{
    LineRenderer line = new GameObject("Line_" + start.ToString() + "_" + end.ToString()).AddComponent<LineRenderer>();
    line.material = material;
    line.startColor = color;
    line.endColor = color;
    line.startWidth = width;
    line.endWidth = width;
    line.positionCount = 2;
    line.useWorldSpace = true;
    line.SetPosition(0, start);
    line.SetPosition(1, end);
    line.transform.SetParent(transform);
    lines.Add(line);
}

public void SetLinesColor(Color color)
{
    for (int i = 0; i < lines.Count; i++)
    {
        lines[i].material.color = color;
        lines[i].startColor = color;
        lines[i].endColor = color;
    }
}