using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Rendering; [RequireComponent(typeof(CapsuleCollider))] public class LeavesHiding : MonoBehaviour { public Material invisibleMaterial; Dictionary matLists = new Dictionary(); HashSet singleMatLeavesMeshes = new HashSet(); static RPGController player = null; static new Camera camera = null; static int ignoreRaycastLayer = -1; private void Awake() { if (ignoreRaycastLayer == -1) ignoreRaycastLayer = LayerMask.NameToLayer("Ignore Raycast"); } void Start() { foreach (Collider collider in GetComponents()) collider.isTrigger = true; LODGroup lodGroup = GetComponentInChildren(); foreach (MeshRenderer renderer in GetComponentsInChildren(true)) { MeshRenderer newRenderer = Instantiate(renderer.gameObject, renderer.transform.parent, true).GetComponent(); newRenderer.shadowCastingMode = ShadowCastingMode.ShadowsOnly; renderer.shadowCastingMode = ShadowCastingMode.Off; if (!lodGroup) continue; LOD[] lods = lodGroup.GetLODs(); for (int i = 0; i < lods.Length; i++) { if (lods[i].renderers.Any(r => r == renderer)) lods[i].renderers = lods[i].renderers.Append(newRenderer).ToArray(); } lodGroup.SetLODs(lods); } foreach (MeshRenderer renderer in GetComponentsInChildren(true)) { Material[] rendererSharedMats = renderer.sharedMaterials; Material[] leavelessMats = new Material[rendererSharedMats.Length]; if (renderer.shadowCastingMode == ShadowCastingMode.ShadowsOnly) continue; bool didReplace = false; for (int i = 0; i < rendererSharedMats.Length; i++) { if (rendererSharedMats[i].name.Contains("leaves", StringComparison.InvariantCultureIgnoreCase)) { leavelessMats[i] = invisibleMaterial; didReplace = true; } else leavelessMats[i] = rendererSharedMats[i]; } if (!didReplace) continue; matLists.Add(renderer, (rendererSharedMats, leavelessMats)); } } void Update() { if (!player) player = FindAnyObjectByType(); if (!camera) camera = Camera.main; if (!player || !camera) return; if (gameObject.layer != ignoreRaycastLayer) gameObject.layer = ignoreRaycastLayer; Vector3 playerPos = player.transform.position + Vector3.up; Vector3 cameraPos = camera.transform.position; Vector3 rayDir = (playerPos - cameraPos).normalized; RaycastHit[] hits = Physics.RaycastAll(cameraPos, rayDir, float.PositiveInfinity, 1 << gameObject.layer, QueryTriggerInteraction.Collide); for (int i = 0; i < hits.Length; i++) { if (hits[i].collider.gameObject == gameObject) { SetLeavesVisible(false); return; } } SetLeavesVisible(true); } /* void OnTriggerEnter(Collider other) { if (other.GetComponent() || other.GetComponentInParent()) SetLeavesVisible(false); } void OnTriggerExit(Collider other) { if (other.GetComponent() || other.GetComponentInParent()) SetLeavesVisible(true); } */ void SetLeavesVisible(bool visible) { foreach (MeshRenderer renderer in matLists.Keys) renderer.sharedMaterials = visible ? matLists[renderer].Item1 : matLists[renderer].Item2; } }