using System.Collections; using System.Collections.Generic; using UnityEngine; public class Wind : MonoBehaviour { [Header("Налаштування вітру")] [SerializeField] private WindZone windZone; [Header("Режим середовища")] [Space(5)] [Header("Без вітру. Предмет падає як у вакуумі")] [SerializeField] private bool noWind = false; [Header("Слабкий вітер. Є опір повітря + слабкий вітер вбік")] [SerializeField] private bool weakWind = true; [Header("Сильний вітер. Є опір повітря + сильний вітер вбік")] [SerializeField] private bool strongWind = false; [Header("Налаштування опору повітря")] [SerializeField] private float airDensity = 1.225f; [Header("Сила вітру вбік")] [SerializeField] private float weakWindForce = 0.5f; [SerializeField] private float strongWindForce = 2f; private List _affectedBodies = new List(); private Dictionary _objectProperties = new Dictionary(); private void Start() { if (windZone == null) windZone = GetComponent(); UpdateWindZone(); } private void OnValidate() { UpdateWindZone(); } private void UpdateWindZone() { if (windZone == null) return; if (noWind) { windZone.windMain = 0f; } else if (weakWind) { windZone.windMain = 2f; windZone.windTurbulence = 0.1f; } else if (strongWind) { windZone.windMain = 8f; windZone.windTurbulence = 0.5f; } } private void OnTriggerEnter(Collider other) { Rigidbody rb = other.attachedRigidbody; if (rb != null && !_affectedBodies.Contains(rb)) { _affectedBodies.Add(rb); ObjectAirProperties props = rb.GetComponent(); if (props != null) { _objectProperties[rb] = props; } } } private void OnTriggerExit(Collider other) { Rigidbody rb = other.attachedRigidbody; if (rb != null) { _affectedBodies.Remove(rb); _objectProperties.Remove(rb); } } private void FixedUpdate() { foreach (Rigidbody rb in _affectedBodies) { if (rb == null) continue; if (!noWind) { ApplyAirResistance(rb); if (weakWind || strongWind) { ApplyWindForce(rb); } } } } private void ApplyAirResistance(Rigidbody rb) { if (rb.velocity.magnitude < 0.01f) return; float crossSectionArea = 0.05f; float dragCoefficient = 0.47f; if (_objectProperties.ContainsKey(rb)) { crossSectionArea = _objectProperties[rb].crossSectionArea; dragCoefficient = _objectProperties[rb].dragCoefficient; } float speed = rb.velocity.magnitude; float dragMagnitude = 0.5f * airDensity * speed * speed * dragCoefficient * crossSectionArea; Vector3 dragForce = -rb.velocity.normalized * dragMagnitude; rb.AddForce(dragForce, ForceMode.Force); } private void ApplyWindForce(Rigidbody rb) { float force = 0f; if (weakWind) force = weakWindForce; else if (strongWind) force = strongWindForce; else return; Vector3 windDirection = transform.forward; rb.AddForce(windDirection * force, ForceMode.Force); } }