using System.Collections; using System.Collections.Generic; using UnityEngine; public class SlidingObject : MonoBehaviour { [SerializeField] private ObjectInfoDisplay _display; private Rigidbody _rb; private string _currentSurface = ""; private bool _isMoving = false; private bool _shownStatic = false; private bool _wasOnShelf = false; private bool _didSlide = false; private string _lastShownName = ""; private float _lastMu = 0f; private FrictionType _lastFrictionType; private static readonly Dictionary> _mu = new() { { "Мармур", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.40f, 0.28f, -1) }, { "Крижана поверхня", (0.10f, 0.06f, -1) }, { "Гумова поверхня", (0.80f, 0.60f, -1) } } }, { "Ядро", new() { { "Дерев'яна поверхня", (0.49f, 0.32f, 0.10f) }, { "Металева поверхня", (0.23f, 0.15f, 0.08f) }, { "Крижана поверхня", (0.05f, 0.03f, 0.02f) }, { "Гумова поверхня", (0.65f, 0.50f, 0.15f) } } }, { "Колесо гармати", new() { { "Дерев'яна поверхня", (0.49f, 0.32f, 0.05f) }, { "Металева поверхня", (0.23f, 0.15f, 0.04f) }, { "Крижана поверхня", (0.08f, 0.05f, 0.01f) }, { "Гумова поверхня", (0.75f, 0.58f, 0.08f) } } }, { "Надутий футбольний м'яч", new() { { "Дерев'яна поверхня", (0.65f, 0.50f, 0.04f) }, { "Металева поверхня", (0.50f, 0.38f, 0.03f) }, { "Крижана поверхня", (0.10f, 0.07f, 0.015f) }, { "Гумова поверхня", (0.90f, 0.75f, 0.07f) } } }, { "Здутий футбольний м'яч", new() { { "Дерев'яна поверхня", (0.80f, 0.65f, 0.09f) }, { "Металева поверхня", (0.65f, 0.50f, 0.07f) }, { "Крижана поверхня", (0.18f, 0.13f, 0.04f) }, { "Гумова поверхня", (1.05f, 0.88f, 0.12f) } } }, { "Гумова качечка", new() { { "Дерев'яна поверхня", (0.90f, 0.70f, -1) }, { "Металева поверхня", (0.70f, 0.55f, -1) }, { "Крижана поверхня", (0.20f, 0.15f, -1) }, { "Гумова поверхня", (1.10f, 0.90f, -1) } } }, { "Енциклопедія", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.35f, 0.25f, -1) }, { "Крижана поверхня", (0.08f, 0.05f, -1) }, { "Гумова поверхня", (0.80f, 0.65f, -1) } } }, { "Авокадо", new() { { "Дерев'яна поверхня", (0.55f, 0.40f, -1) }, { "Металева поверхня", (0.40f, 0.30f, -1) }, { "Крижана поверхня", (0.10f, 0.07f, -1) }, { "Гумова поверхня", (0.85f, 0.68f, -1) } } }, { "Баскетбольний м'яч", new() { { "Дерев'яна поверхня", (0.70f, 0.55f, 0.05f) }, { "Металева поверхня", (0.55f, 0.40f, 0.04f) }, { "Крижана поверхня", (0.15f, 0.10f, 0.02f) }, { "Гумова поверхня", (1.00f, 0.85f, 0.08f) } } }, { "Стара шина", new() { { "Дерев'яна поверхня", (0.90f, 0.70f, 0.08f) }, { "Металева поверхня", (0.70f, 0.55f, 0.06f) }, { "Крижана поверхня", (0.18f, 0.12f, 0.02f) }, { "Гумова поверхня", (1.10f, 0.90f, 0.10f) } } }, { "Дерев'яна дошка", new() { { "Дерев'яна поверхня", (0.62f, 0.48f, -1) }, { "Металева поверхня", (0.50f, 0.35f, -1) }, { "Крижана поверхня", (0.08f, 0.05f, -1) }, { "Гумова поверхня", (0.75f, 0.60f, -1) } } }, { "Пластикова дошка", new() { { "Дерев'яна поверхня", (0.40f, 0.28f, -1) }, { "Металева поверхня", (0.35f, 0.25f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.68f, 0.52f, -1) } } }, { "Сніжок", new() { { "Дерев'яна поверхня", (0.15f, 0.10f, -1) }, { "Металева поверхня", (0.10f, 0.07f, -1) }, { "Крижана поверхня", (0.05f, 0.03f, -1) }, { "Гумова поверхня", (0.35f, 0.25f, -1) } } }, { "Лід", new() { { "Дерев'яна поверхня", (0.08f, 0.05f, -1) }, { "Металева поверхня", (0.06f, 0.04f, -1) }, { "Крижана поверхня", (0.03f, 0.02f, -1) }, { "Гумова поверхня", (0.25f, 0.18f, -1) } } }, { "Скло", new() { { "Дерев'яна поверхня", (0.35f, 0.25f, -1) }, { "Металева поверхня", (0.56f, 0.40f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.70f, 0.55f, -1) } } }, { "Монета", new() { { "Дерев'яна поверхня", (0.44f, 0.30f, 0.05f) }, { "Металева поверхня", (0.57f, 0.44f, 0.04f) }, { "Крижана поверхня", (0.05f, 0.03f, 0.01f) }, { "Гумова поверхня", (0.65f, 0.50f, 0.08f) } } }, { "Сталь", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.74f, 0.57f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.65f, 0.50f, -1) } } }, { "Мідь", new() { { "Дерев'яна поверхня", (0.50f, 0.36f, -1) }, { "Металева поверхня", (0.53f, 0.36f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.70f, 0.55f, -1) } } }, { "Алюміній", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.61f, 0.47f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.65f, 0.50f, -1) } } }, { "Чавун", new() { { "Дерев'яна поверхня", (0.49f, 0.35f, -1) }, { "Металева поверхня", (0.23f, 0.15f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.70f, 0.55f, -1) } } }, { "Ножиці", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.74f, 0.57f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.65f, 0.50f, -1) } } }, { "Скальпель", new() { { "Дерев'яна поверхня", (0.40f, 0.28f, -1) }, { "Металева поверхня", (0.74f, 0.57f, -1) }, { "Крижана поверхня", (0.05f, 0.03f, -1) }, { "Гумова поверхня", (0.60f, 0.45f, -1) } } }, { "Лічі", new() { { "Дерев'яна поверхня", (0.55f, 0.40f, -1) }, { "Металева поверхня", (0.40f, 0.30f, -1) }, { "Крижана поверхня", (0.08f, 0.06f, -1) }, { "Гумова поверхня", (0.80f, 0.65f, -1) } } }, { "Гумовий м'яч", new() { { "Дерев'яна поверхня", (0.90f, 0.70f, 0.05f) }, { "Металева поверхня", (0.70f, 0.55f, 0.04f) }, { "Крижана поверхня", (0.18f, 0.12f, 0.02f) }, { "Гумова поверхня", (1.10f, 0.90f, 0.08f) } } }, { "Асфальт", new() { { "Дерев'яна поверхня", (0.62f, 0.48f, -1) }, { "Металева поверхня", (0.50f, 0.35f, -1) }, { "Крижана поверхня", (0.15f, 0.10f, -1) }, { "Гумова поверхня", (0.90f, 0.75f, -1) } } }, { "Каміння з мохом", new() { { "Дерев'яна поверхня", (0.55f, 0.40f, -1) }, { "Металева поверхня", (0.45f, 0.33f, -1) }, { "Крижана поверхня", (0.12f, 0.08f, -1) }, { "Гумова поверхня", (0.80f, 0.65f, -1) } } }, { "Цегла", new() { { "Дерев'яна поверхня", (0.62f, 0.48f, -1) }, { "Металева поверхня", (0.50f, 0.36f, -1) }, { "Крижана поверхня", (0.12f, 0.08f, -1) }, { "Гумова поверхня", (0.85f, 0.70f, -1) } } }, { "Скляна банка", new() { { "Дерев'яна поверхня", (0.35f, 0.25f, -1) }, { "Металева поверхня", (0.56f, 0.40f, -1) }, { "Крижана поверхня", (0.06f, 0.04f, -1) }, { "Гумова поверхня", (0.68f, 0.52f, -1) } } }, { "Лоток", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.74f, 0.57f, -1) }, { "Крижана поверхня", (0.05f, 0.03f, -1) }, { "Гумова поверхня", (0.60f, 0.45f, -1) } } }, { "Блокнот", new() { { "Дерев'яна поверхня", (0.50f, 0.35f, -1) }, { "Металева поверхня", (0.35f, 0.25f, -1) }, { "Крижана поверхня", (0.08f, 0.05f, -1) }, { "Гумова поверхня", (0.75f, 0.58f, -1) } } }, { "Хірургічна пилка", new() { { "Дерев'яна поверхня", (0.40f, 0.28f, -1) }, { "Металева поверхня", (0.74f, 0.57f, -1) }, { "Крижана поверхня", (0.05f, 0.03f, -1) }, { "Гумова поверхня", (0.60f, 0.45f, -1) } } }, }; private void Awake() { _rb = GetComponent(); _didSlide = false; } private void OnCollisionEnter(Collision collision) { string surface = GetSurfaceName(collision.gameObject); if (surface != "") { _wasOnShelf = true; _currentSurface = surface; _isMoving = false; _shownStatic = false; return; } if (collision.gameObject.CompareTag("Floor") && _wasOnShelf && _didSlide) { _wasOnShelf = false; _didSlide = false; float speed = _rb.velocity.magnitude; ObjectName objName = GetComponent(); string name = objName != null ? objName.ukrainianName : gameObject.name; StartCoroutine(ShowFallAfterSlide(name, speed)); _currentSurface = ""; } else if (collision.gameObject.CompareTag("Floor")) { _wasOnShelf = false; _didSlide = false; } } private void OnCollisionExit(Collision collision) { string surface = GetSurfaceName(collision.gameObject); if (surface == "") return; _currentSurface = ""; _isMoving = false; _shownStatic = false; } private void Update() { if (_currentSurface == "" || _display == null || _rb == null) return; ObjectName objName = GetComponent(); if (objName == null) return; string rawName = objName.ukrainianName; string name = _mu.ContainsKey(rawName) ? rawName : rawName.Contains("Енциклопедія") ? "Енциклопедія" : rawName; if (!_mu.TryGetValue(name, out var surfaces)) return; if (!surfaces.TryGetValue(_currentSurface, out var mu)) return; bool movingNow = _rb.velocity.magnitude > 0.05f; if (!movingNow && !_shownStatic) { _shownStatic = true; _isMoving = false; _lastShownName = name; _lastMu = mu.stat; _lastFrictionType = FrictionType.Статичне; _display.ShowSlide(name, _currentSurface, mu.stat, FrictionType.Статичне); } else if (movingNow && !_isMoving) { _isMoving = true; _shownStatic = false; StartCoroutine(ShowAfterDelay(name, mu)); } } private IEnumerator ShowAfterDelay(string name, (float stat, float slide, float roll) mu) { yield return new WaitForSeconds(0.3f); if (_rb == null || _currentSurface == "") yield break; float linearSpeed = _rb.velocity.magnitude; float angularSpeed = _rb.angularVelocity.magnitude; bool isRolling = angularSpeed > 0.5f && linearSpeed > 0.05f; float shownMu; FrictionType shownType; if (isRolling && mu.roll >= 0f) { shownMu = mu.roll; shownType = FrictionType.Кочення; } else if (isRolling && mu.roll < 0f) { shownMu = mu.slide; shownType = FrictionType.Кочення; } else { shownMu = mu.slide; shownType = FrictionType.Ковзання; } if (_lastFrictionType == shownType && _lastMu == shownMu) yield break; _lastShownName = name; _lastMu = shownMu; _lastFrictionType = shownType; _didSlide = true; _display.ShowSlide(name, _currentSurface, shownMu, shownType); GameData.AddFriction(name, _currentSurface, shownMu, shownType); } private IEnumerator ShowFallAfterSlide(string name, float speed) { yield return new WaitForSeconds(_display.displayTime + _display.fadeTime); _display.ShowFall(name, speed); } private string GetSurfaceName(GameObject obj) { ObjectName objName = obj.GetComponent(); if (objName == null) objName = obj.GetComponentInParent(); if (objName != null) return objName.description; return ""; } }