138 lines
3.6 KiB
C#
138 lines
3.6 KiB
C#
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<Rigidbody> _affectedBodies = new List<Rigidbody>();
|
|
private Dictionary<Rigidbody, ObjectAirProperties> _objectProperties = new Dictionary<Rigidbody, ObjectAirProperties>();
|
|
|
|
private void Start()
|
|
{
|
|
if (windZone == null) windZone = GetComponent<WindZone>();
|
|
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<ObjectAirProperties>();
|
|
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);
|
|
}
|
|
}
|