コード例 #1
0
    private void FixedUpdate()
    {
        PortalOcclusionVolume currentOcclusionVolume = null;

        foreach (var occlusionVolume in occlusionVolumes)
        {
            if (occlusionVolume.collider.bounds.Contains(transform.position))
            {
                currentOcclusionVolume = occlusionVolume;
                break;
            }
        }

        var bestApparentPosition = FindBestApparentPosition(
            transform.position,
            target.position,
            "Player Visibility Checker",
            layerMask,
            currentOcclusionVolume,
            maxRecursions,
            maxApparentPositions
            );

        if (bestApparentPosition != null)
        {
            transform.LookAt(bestApparentPosition.ApparentPosition);
        }
    }
コード例 #2
0
    private void OnPreRender()
    {
        PortalOcclusionVolume currentVolume = null;

        foreach (PortalOcclusionVolume portalOcclusionVolume in portalOcclusionVolumes)
        {
            if (portalOcclusionVolume.collider.bounds.Contains(transform.position))
            {
                currentVolume = portalOcclusionVolume;
                break;
            }
        }

        Portal[] portalsToRender = currentVolume ? currentVolume.visiblePortals : defaultRenderAllPortals ? allPortals : null;
        debugDirectPortalCount = 0;
        if (portalsToRender != null)
        {
            foreach (Portal portal in portalsToRender)
            {
                // Frustum cull; do not render portal view through texture if not visible
                if (portal.viewThroughToRenderer.isVisible)
                {
                    Portal.RenderViewThroughRecursive(
                        portal,
                        GameManager.instance.mainCamera.transform.position,
                        GameManager.instance.mainCamera.transform.rotation,
                        out PortalRenderTexturePoolItem _,
                        out Texture _,
                        out int renderCount);
                    debugDirectPortalCount++;
                    debugTotalPortalCount = renderCount;
                }
            }
        }
    }
コード例 #3
0
    private void OnPreRender()
    {
        debugTotalRenderCount = 0;

        PortalOcclusionVolume currentOcclusionVolume = null;

        foreach (var occlusionVolume in occlusionVolumes)
        {
            if (occlusionVolume.collider.bounds.Contains(mainCamera.transform.position))
            {
                currentOcclusionVolume = occlusionVolume;
                break;
            }
        }

        if (currentOcclusionVolume != null)
        {
            var cameraPlanes = GeometryUtility.CalculateFrustumPlanes(mainCamera);

            foreach (var portal in currentOcclusionVolume.portals)
            {
                if (!portal.ShouldRender(cameraPlanes))
                {
                    continue;
                }

                portal.RenderViewthroughRecursive(
                    mainCamera.transform.position,
                    mainCamera.transform.rotation,
                    out _,
                    out _,
                    out var renderCount,
                    portalCamera,
                    0,
                    maxRecursions,
                    noCloneMask,
                    renderCloneMask,
                    PortalableObjectClone.LocalInstance.ClosestTouchingPortal);

                debugTotalRenderCount += renderCount;
            }
        }
    }
コード例 #4
0
    private void OnPreRender()
    {
        DebugTotalRenderCount = 0;

        PortalOcclusionVolume currentOcclusionVolume = null;

        foreach (var occlusionVolume in occlusionVolumes)
        {
            if (occlusionVolume.Collider.bounds.Contains(mainCamera.transform.position))
            {
                currentOcclusionVolume = occlusionVolume;
                break;
            }
        }

        if (currentOcclusionVolume != null)
        {
            var cameraPlanes = GeometryUtility.CalculateFrustumPlanes(mainCamera);

            foreach (var portal in currentOcclusionVolume.Portals)
            {
                if (!portal.ShouldRender(cameraPlanes))
                {
                    continue;
                }

                if (portal.TargetPortal[portal.TargetPortalIndex] != null)
                {
                    portal.RenderViewthroughRecursive(
                        mainCamera.transform.position,
                        mainCamera.transform.rotation,
                        out _,
                        out _,
                        out var renderCount,
                        PortalCamera,
                        0,
                        MaxRecursions);

                    DebugTotalRenderCount += renderCount;
                }
            }
        }
    }
コード例 #5
0
    public static TargetApparentPosition FindBestApparentPosition(
        Vector3 origin,
        Vector3 target,
        string targetTag,
        LayerMask layerMask,
        PortalOcclusionVolume occlusionVolume,
        int maxRecursions,
        int maxApparentPositions)
    {
        AimingPortalChainQueue.Clear();
        AimingTargetApparentPositions.Clear();

        // Breadth first search

        AimingPortalChainQueue.Enqueue(new List <Portal>());
        while (AimingPortalChainQueue.Count > 0)
        {
            var currentChain = AimingPortalChainQueue.Dequeue();

            // Calculate apparent location

            var targetApparentPosition = target;
            foreach (var portal in currentChain)
            {
                targetApparentPosition = Portal.TransformPositionBetweenPortals(portal.targetPortal, portal,
                                                                                targetApparentPosition);
            }

            var aimDirection = targetApparentPosition - origin;
            aimDirection.Normalize();

            // Calculate visibility
            // If visible, add to target apparent positions

            if (Portal.RaycastRecursive(
                    origin,
                    aimDirection,
                    currentChain.Count,
                    null,
                    (x, y) => layerMask,
                    out var hitInfo))
            {
                if (hitInfo.collider.CompareTag(targetTag))
                {
                    AimingTargetApparentPositions.Add(new TargetApparentPosition
                    {
                        ApparentPosition = targetApparentPosition,
                        AimDirection     = aimDirection
                    });
                }
            }

            // Return if enough for an accurate heuristic

            if (maxApparentPositions > 0)
            {
                if (AimingTargetApparentPositions.Count >= maxApparentPositions)
                {
                    break;
                }
            }

            // Continue search; add to queue

            if (currentChain.Count >= maxRecursions)
            {
                continue;
            }
            foreach (var visiblePortal in currentChain.Count > 0 ? currentChain[currentChain.Count - 1].visiblePortals : occlusionVolume == null ? new Portal[0] : occlusionVolume.portals)
            {
                AimingPortalChainQueue.Enqueue(new List <Portal>(currentChain)
                {
                    visiblePortal
                });
            }
        }

        // Use heuristic (closest apparent) to find which of the apparent positions should the AI shoot at

        TargetApparentPosition bestApparentPosition = null;
        var minDistance = Mathf.Infinity;

        foreach (var aimingTargetApparentPosition in AimingTargetApparentPositions)
        {
            var distance = Vector3.Distance(aimingTargetApparentPosition.ApparentPosition, origin);
            if (distance >= minDistance)
            {
                continue;
            }
            minDistance          = distance;
            bestApparentPosition = aimingTargetApparentPosition;
        }

        return(bestApparentPosition);
    }