using Fragilem17.MirrorsAndPortals; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Fragilem17.MirrorsAndPortals { [ExecuteInEditMode] public class RayCastingExample : MonoBehaviour { public Transform ForwardGO; public LayerMask layerMask; public float maxDistance = 10; public LineRenderer LineRendererPrefab; private List LineRenderInstances; public int maxRecursions = 10; public bool ChangeColorOfPortalOnHit = false; public Color ColorToChangePortalTo = Color.white; private void OnEnable() { if (LineRendererPrefab) { LineRenderInstances = new List(); LineRenderInstances.Add(LineRendererPrefab); } } private void OnDisable() { if (LineRenderInstances != null) { foreach (LineRenderer lr in LineRenderInstances) { if (lr != LineRendererPrefab) { #if UNITY_EDITOR DestroyImmediate(lr.gameObject); #else Destroy(lr.gameObject); #endif } } LineRenderInstances = null; } } void Update() { if (!LineRendererPrefab || !ForwardGO || LineRenderInstances == null || LineRenderInstances.Count == 0) { return; } HideLines(); RayCast(ForwardGO.position, ForwardGO.forward, 0); } private void HideLines() { foreach (LineRenderer lr in LineRenderInstances) { if (lr) { lr.gameObject.SetActive(false); } } } private void RayCast(Vector3 startPosition, Vector3 direction, int iteration) { if (iteration < maxRecursions) { Vector3 endPosition; Ray ray = new Ray(startPosition, direction); iteration = iteration + 1; if (Physics.Raycast(ray, out RaycastHit hit, maxDistance, layerMask)) { endPosition = hit.point; Portal portal = hit.collider.gameObject.GetComponent(); if (portal) { // where the ray hits the portal we set the rays new original to be the hitPoint ray.origin = endPosition; // Then we portal the ray portal.PortalRay(ref ray); if (ChangeColorOfPortalOnHit) { portal.PortalSurface.MyMaterialInstance.SetColor("_Tint", ColorToChangePortalTo); } // The ray is now pointing outwards of the other portal // we recurse in this function so we can try and find another portal RayCast(ray.origin, ray.direction, iteration); } } else { // we didn't hit anything so we just add the endPos to be a meter from our startPos endPosition = startPosition + (direction * 1f); } DrawLineRenderer(startPosition, endPosition, iteration); //Debug.DrawLine(startPosition, endPosition, Color.blue); } } private void DrawLineRenderer(Vector3 startPosition, Vector3 endPosition, int iteration) { iteration = iteration - 1; LineRenderer lineRenderer; if (LineRenderInstances.Count > iteration) { lineRenderer = LineRenderInstances[iteration]; } else { lineRenderer = Instantiate(LineRendererPrefab, ForwardGO); lineRenderer.gameObject.hideFlags = HideFlags.DontSave; LineRenderInstances.Add(lineRenderer); } if (lineRenderer != null) { Vector3[] positions = new Vector3[] { startPosition, endPosition }; lineRenderer.gameObject.SetActive(true); lineRenderer.SetPositions(positions); } } } }