Kursach_StealthAction/Assets/Scripts/AcidPool.cs
2026-10-23 15:44:09 +03:00

140 lines
5.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
/// <summary>
/// Токсичная лужа ядовитой слизи босса, оставшаяся после попадания плевка.
/// Наносит периодический урон игроку при нахождении в зоне поражения и шипит.
/// </summary>
public class AcidPool : MonoBehaviour
{
public float damagePerSecond = 5f;
public float lifetime = 4.5f;
public float radius = 0.85f;
private float timer = 0f;
private PlayerHealth playerInPool = null;
private Light poolLight;
private System.Collections.Generic.List<Transform> visualSplatterPieces = new System.Collections.Generic.List<Transform>();
public static AcidPool Create(Vector3 position, float poolLifetime = 4.5f, float poolRadius = 0.85f)
{
GameObject go = new GameObject("Acid_Saliva_Splatter");
go.transform.position = position;
AcidPool pool = go.AddComponent<AcidPool>();
pool.lifetime = poolLifetime;
pool.radius = poolRadius;
return pool;
}
private void Start()
{
// Сферический триггер для обнаружения игрока
SphereCollider sc = gameObject.AddComponent<SphereCollider>();
sc.isTrigger = true;
sc.radius = radius;
// Кислотно-зеленый токсичный материал слюны: влажный, глянцевый
Material salivaMat = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"));
salivaMat.color = new Color(0.28f, 0.9f, 0.18f, 0.75f);
salivaMat.EnableKeyword("_EMISSION");
salivaMat.SetColor("_EmissionColor", new Color(0.15f, 0.7f, 0.1f) * 1.1f);
if (salivaMat.HasProperty("_Smoothness")) salivaMat.SetFloat("_Smoothness", 0.95f);
// 1. Центральное влажное пятно слюны (ультратонкое, как реальный след жидкости)
GameObject mainPuddle = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
mainPuddle.name = "Saliva_Center";
mainPuddle.transform.SetParent(transform, false);
mainPuddle.transform.localPosition = new Vector3(0f, 0.005f, 0f);
mainPuddle.transform.localScale = new Vector3(radius * 0.9f, 0.002f, radius * 0.9f);
Destroy(mainPuddle.GetComponent<Collider>());
mainPuddle.GetComponent<Renderer>().material = salivaMat;
visualSplatterPieces.Add(mainPuddle.transform);
// 2. Мелкие органические капли-брызги вокруг центра (клякса превращается в естественный всплеск слюны)
Vector2[] splashOffsets = new Vector2[]
{
new Vector2(0.42f, 0.25f),
new Vector2(-0.38f, 0.32f),
new Vector2(0.15f, -0.45f),
new Vector2(-0.42f, -0.22f),
new Vector2(0.50f, -0.18f)
};
for (int i = 0; i < splashOffsets.Length; i++)
{
GameObject splash = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
splash.name = $"Saliva_Droplet_{i + 1}";
splash.transform.SetParent(transform, false);
splash.transform.localPosition = new Vector3(splashOffsets[i].x * radius, 0.005f, splashOffsets[i].y * radius);
float dropScale = Random.Range(0.14f, 0.24f) * radius;
splash.transform.localScale = new Vector3(dropScale, 0.002f, dropScale * Random.Range(0.85f, 1.35f));
Destroy(splash.GetComponent<Collider>());
splash.GetComponent<Renderer>().material = salivaMat;
visualSplatterPieces.Add(splash.transform);
}
// 3. Мягкий биолюминесцентный свет пятна
GameObject lightObj = new GameObject("AcidLight");
lightObj.transform.SetParent(transform, false);
lightObj.transform.localPosition = new Vector3(0f, 0.15f, 0f);
poolLight = lightObj.AddComponent<Light>();
poolLight.type = LightType.Point;
poolLight.color = new Color(0.3f, 1.0f, 0.2f);
poolLight.intensity = 0.75f;
poolLight.range = 1.8f;
// Звук шипения кислоты
GameAudioSynthesizer.PlayAcidHiss();
}
private void Update()
{
timer += Time.deltaTime;
// Нанесение периодического урона игроку в луже
if (playerInPool != null)
{
playerInPool.TakeDamage(damagePerSecond * Time.deltaTime);
}
// Плавное испарение слюны в конце жизни
float remaining = lifetime - timer;
if (remaining <= 1.0f)
{
float scaleRatio = Mathf.Clamp01(remaining);
foreach (var piece in visualSplatterPieces)
{
if (piece != null)
{
piece.localScale = new Vector3(piece.localScale.x * scaleRatio, 0.002f, piece.localScale.z * scaleRatio);
}
}
if (poolLight != null) poolLight.intensity = 0.75f * scaleRatio;
}
if (timer >= lifetime)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player") || other.GetComponentInParent<PlayerMovement>() != null)
{
playerInPool = other.GetComponentInParent<PlayerHealth>();
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player") || other.GetComponentInParent<PlayerMovement>() != null)
{
if (playerInPool == other.GetComponentInParent<PlayerHealth>())
{
playerInPool = null;
}
}
}
}