using UnityEngine; /// /// Токсичная лужа ядовитой слизи босса, оставшаяся после попадания плевка. /// Наносит периодический урон игроку при нахождении в зоне поражения и шипит. /// 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 visualSplatterPieces = new System.Collections.Generic.List(); 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(); pool.lifetime = poolLifetime; pool.radius = poolRadius; return pool; } private void Start() { // Сферический триггер для обнаружения игрока SphereCollider sc = gameObject.AddComponent(); 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()); mainPuddle.GetComponent().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()); splash.GetComponent().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(); 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() != null) { playerInPool = other.GetComponentInParent(); } } private void OnTriggerExit(Collider other) { if (other.CompareTag("Player") || other.GetComponentInParent() != null) { if (playerInPool == other.GetComponentInParent()) { playerInPool = null; } } } }