using System.Collections.Generic; using UnityEngine; public class HideWall : MonoBehaviour { [SerializeField] private GameObject target; [SerializeField] private GameObject origin; public GameObject prevObject; public Material defaultMaterial; // Material when not hitting "Wall" public Material hitMaterial; // Material when hitting "Wall" public float sphereRadius; float maxSphereRayDistance; public Vector3 maxSphereRayDistanceOffset; private List prevHitObjects = new List(); private void Start() { maxSphereRayDistance = Vector3.Distance(origin.transform.position, target.transform.position) - (sphereRadius * 2 + 1); } void Update() { Vector3 direction = ((target.transform.position + maxSphereRayDistanceOffset) - origin.transform.position).normalized; RaycastHit[] hits = Physics.SphereCastAll(origin.transform.position, sphereRadius, direction, maxSphereRayDistance); List hitObjectsThisFrame = new List(); // Change material of currently hit objects for (int i = 0; i < hits.Length; i++) { if (hits[i].collider.CompareTag("Wall")) { var hitGameObject = hits[i].collider.gameObject; hitObjectsThisFrame.Add(hitGameObject); // Change material only if this object wasn't hit last frame if (!prevHitObjects.Contains(hitGameObject)) { Renderer renderer = hits[i].collider.GetComponent(); if (renderer != null) { renderer.material = hitMaterial; } } } } // Restore the material of objects that are not hit this frame but were hit in the previous frame for (int i = 0; i < prevHitObjects.Count; i++) { if (!hitObjectsThisFrame.Contains(prevHitObjects[i])) { Renderer renderer = prevHitObjects[i].GetComponent(); if (renderer != null) { renderer.material = defaultMaterial; } } } // Update the list of previously hit objects prevHitObjects = hitObjectsThisFrame; } private void OnDrawGizmos() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(origin.transform.position, sphereRadius); } }