Add a new way to hide trees, with dither fade around the player character

This commit is contained in:
Lucien
2026-08-03 13:53:40 +02:00
parent c7a34c56f5
commit a01e19e5fe
16 changed files with 8408 additions and 0 deletions
@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Toria.Game
{
[RequireComponent(typeof(CapsuleCollider))]
public class LeavesHidingDither : MonoBehaviour
{
[NonSerialized]
List<Material> treeMaterials;
static RPGController player = null;
static new Camera camera = null;
[NonSerialized]
bool shouldHide = false;
void Start()
{
treeMaterials = new List<Material>();
foreach (Renderer renderer in GetComponentsInChildren<Renderer>())
{
MakeShadowClone(renderer);
Material mat = Instantiate(renderer.sharedMaterial);
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
renderer.sharedMaterial = mat;
treeMaterials.Add(mat);
}
}
void MakeShadowClone(Renderer renderer)
{
GameObject shadowClone = Instantiate(renderer.gameObject);
for (int i = shadowClone.transform.childCount - 1; i >= 0; i--)
Destroy(shadowClone.transform.GetChild(i).gameObject);
shadowClone.name = "Shadow clone";
shadowClone.transform.SetParent(renderer.transform);
shadowClone.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
shadowClone.transform.localScale = Vector3.one;
foreach (Component comp in shadowClone.GetComponents<Component>())
{
if (comp is not MeshRenderer && comp is not MeshFilter && comp is not Transform)
Destroy(comp);
}
shadowClone.GetComponent<Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
}
void Update()
{
if (!player)
player = FindAnyObjectByType<RPGController>();
if (shouldHide)
{
Vector2 viewPortPoint = camera.WorldToViewportPoint(player.transform.position);
foreach (Material mat in treeMaterials)
mat.SetVector("_PlayerPosition", viewPortPoint);
}
if (!camera)
camera = Camera.main;
if (!player || !camera)
return;
Vector3 playerPos = player.transform.position + Vector3.up;
Vector3 cameraPos = camera.transform.position;
Vector3 rayDir = (playerPos - cameraPos).normalized;
//move back the origin point so the raycast doesn't start from within a tree collider
RaycastHit[] hits = Physics.RaycastAll(cameraPos + rayDir * -100f, rayDir, float.PositiveInfinity, 1 << gameObject.layer, QueryTriggerInteraction.Collide);
for (int i = 0; i < hits.Length; i++)
{
if (hits[i].collider.gameObject == gameObject)
{
SetCutoutEnabled(true);
return;
}
}
SetCutoutEnabled(false);
}
void SetCutoutEnabled(bool enabled)
{
if (shouldHide == enabled)
return;
shouldHide = enabled;
foreach (Material mat in treeMaterials)
mat.SetFloat("_ShouldHide", enabled ? 1 : 0);
}
}
}