initial commit
This commit is contained in:
444
Assets/Scripts/SlidingObject.cs
Normal file
444
Assets/Scripts/SlidingObject.cs
Normal file
@@ -0,0 +1,444 @@
|
||||
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<string, Dictionary<string, (float stat, float slide, float roll)>> _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<Rigidbody>();
|
||||
_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<ObjectName>();
|
||||
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<ObjectName>();
|
||||
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<ObjectName>();
|
||||
if (objName == null)
|
||||
objName = obj.GetComponentInParent<ObjectName>();
|
||||
if (objName != null)
|
||||
return objName.description;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user