[Add] Dice return script
This commit is contained in:
+29
-1
@@ -311,13 +311,15 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier: Assembly-CSharp::DiceRoller
|
m_EditorClassIdentifier: Assembly-CSharp::DiceRoller
|
||||||
dice: {fileID: 3052556563113756475}
|
dice: {fileID: 3052556563113756475}
|
||||||
rb: {fileID: 1768444232422188122}
|
rb: {fileID: 1768444232422188122}
|
||||||
|
diceCollider: {fileID: 0}
|
||||||
<Definition>k__BackingField: {fileID: 11400000, guid: b4fd0877395ff654b83ec79e811d356c, type: 2}
|
<Definition>k__BackingField: {fileID: 11400000, guid: b4fd0877395ff654b83ec79e811d356c, type: 2}
|
||||||
throwUpForce: 2
|
throwUpForce: 2
|
||||||
throwScatter: 1.5
|
throwScatter: 1.5
|
||||||
torqueMin: 15
|
torqueMin: 15
|
||||||
torqueMax: 30
|
torqueMax: 80
|
||||||
settleSpeed: 0.05
|
settleSpeed: 0.05
|
||||||
settleDelay: 0.3
|
settleDelay: 0.3
|
||||||
|
maxRollDuration: 3
|
||||||
snapDuration: 0.35
|
snapDuration: 0.35
|
||||||
snapCurve:
|
snapCurve:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -343,6 +345,32 @@ MonoBehaviour:
|
|||||||
m_PreInfinity: 2
|
m_PreInfinity: 2
|
||||||
m_PostInfinity: 2
|
m_PostInfinity: 2
|
||||||
m_RotationOrder: 4
|
m_RotationOrder: 4
|
||||||
|
returnDuration: 0.4
|
||||||
|
returnArcHeight: 0.6
|
||||||
|
returnCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0
|
||||||
|
outWeight: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 1
|
||||||
|
value: 1
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0
|
||||||
|
outWeight: 0
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
--- !u!1 &6346438093409117343
|
--- !u!1 &6346438093409117343
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
+19
-19
@@ -543,11 +543,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: -2
|
value: -2.01
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -762,7 +762,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 678730622}
|
m_GameObject: {fileID: 678730622}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 3.39505, y: 8.67578, z: 0}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children:
|
m_Children:
|
||||||
@@ -1173,9 +1173,9 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1284869687}
|
m_GameObject: {fileID: 1284869687}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0.38268343, z: 0, w: 0.92387956}
|
m_LocalRotation: {x: -0, y: 0.38268343, z: -0, w: 0.92387956}
|
||||||
m_LocalPosition: {x: 0, y: -1.35, z: 0}
|
m_LocalPosition: {x: 0, y: 1, z: 0}
|
||||||
m_LocalScale: {x: 0.82, y: 0.82, z: 0.82}
|
m_LocalScale: {x: 0.8200002, y: 0.82, z: 0.8200002}
|
||||||
m_ConstrainProportionsScale: 1
|
m_ConstrainProportionsScale: 1
|
||||||
m_Children:
|
m_Children:
|
||||||
- {fileID: 819220931}
|
- {fileID: 819220931}
|
||||||
@@ -1272,7 +1272,7 @@ Transform:
|
|||||||
m_GameObject: {fileID: 1375693286}
|
m_GameObject: {fileID: 1375693286}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0.46193978, y: 0.33141357, z: -0.19134171, w: 0.8001032}
|
m_LocalRotation: {x: 0.46193978, y: 0.33141357, z: -0.19134171, w: 0.8001032}
|
||||||
m_LocalPosition: {x: -5, y: 25, z: -6}
|
m_LocalPosition: {x: -10, y: 22, z: -8}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -1352,11 +1352,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: -1
|
value: -1.01
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -1409,11 +1409,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 1
|
value: 0.99
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -1535,11 +1535,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 0
|
value: -0.01
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -1592,11 +1592,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 1
|
value: 0.99
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -1662,8 +1662,8 @@ Transform:
|
|||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 1715952346}
|
m_GameObject: {fileID: 1715952346}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: -2.2, z: 0}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 5, y: 5, z: 5}
|
m_LocalScale: {x: 5, y: 5, z: 5}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
@@ -1778,11 +1778,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 2
|
value: 1.99
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0
|
value: 0.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
- target: {fileID: 6590077607741954368, guid: b59e9f48ded300a44bdf1f3f3a43e1ae, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
|
|||||||
@@ -7,13 +7,16 @@ namespace YachtDice.Dice
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Красиво подбрасывает и раскручивает кубик, ждёт пока он остановится,
|
/// Красиво подбрасывает и раскручивает кубик, ждёт пока он остановится,
|
||||||
/// плавно доворачивает до ровного положения и сообщает результат.
|
/// плавно доворачивает до ровного положения, возвращает на старт и сообщает результат.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DiceRoller : MonoBehaviour
|
public class DiceRoller : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private static DiceRoller _activeReturnRoller;
|
||||||
|
|
||||||
[Header("References")]
|
[Header("References")]
|
||||||
[SerializeField] private Dice dice;
|
[SerializeField] private Dice dice;
|
||||||
[SerializeField] private Rigidbody rb;
|
[SerializeField] private Rigidbody rb;
|
||||||
|
[SerializeField] private Collider diceCollider;
|
||||||
|
|
||||||
[Tooltip("Определение типа дайса")]
|
[Tooltip("Определение типа дайса")]
|
||||||
[field: SerializeField] public DiceDefinition Definition { get; private set; }
|
[field: SerializeField] public DiceDefinition Definition { get; private set; }
|
||||||
@@ -38,6 +41,9 @@ namespace YachtDice.Dice
|
|||||||
[Tooltip("Сколько секунд кубик должен быть неподвижен, чтобы засчитать остановку")]
|
[Tooltip("Сколько секунд кубик должен быть неподвижен, чтобы засчитать остановку")]
|
||||||
[SerializeField] private float settleDelay = 0.3f;
|
[SerializeField] private float settleDelay = 0.3f;
|
||||||
|
|
||||||
|
[Tooltip("Максимальная длительность броска до принудительного завершения")]
|
||||||
|
[SerializeField] private float maxRollDuration = 3f;
|
||||||
|
|
||||||
[Header("Snap Alignment")]
|
[Header("Snap Alignment")]
|
||||||
[Tooltip("Длительность плавного доворота к ровному положению")]
|
[Tooltip("Длительность плавного доворота к ровному положению")]
|
||||||
[SerializeField] private float snapDuration = 0.35f;
|
[SerializeField] private float snapDuration = 0.35f;
|
||||||
@@ -45,6 +51,16 @@ namespace YachtDice.Dice
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private AnimationCurve snapCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
private AnimationCurve snapCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
||||||
|
|
||||||
|
[Header("Return To Start")]
|
||||||
|
[Tooltip("Длительность возврата в стартовую позицию")]
|
||||||
|
[SerializeField] private float returnDuration = 0.4f;
|
||||||
|
|
||||||
|
[Tooltip("Высота дуги при возврате в стартовую позицию")]
|
||||||
|
[SerializeField] private float returnArcHeight = 0.6f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private AnimationCurve returnCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Вызывается когда кубик полностью остановился. Аргумент — выпавшее значение.
|
/// Вызывается когда кубик полностью остановился. Аргумент — выпавшее значение.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -56,11 +72,36 @@ namespace YachtDice.Dice
|
|||||||
public bool IsRolling { get; private set; }
|
public bool IsRolling { get; private set; }
|
||||||
|
|
||||||
private Coroutine _rollRoutine;
|
private Coroutine _rollRoutine;
|
||||||
|
private Vector3 _startLocalPosition;
|
||||||
|
private bool _startPoseCaptured;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (dice == null)
|
||||||
|
dice = GetComponent<Dice>();
|
||||||
|
|
||||||
|
if (rb == null)
|
||||||
|
rb = GetComponent<Rigidbody>();
|
||||||
|
|
||||||
|
if (diceCollider == null)
|
||||||
|
diceCollider = GetComponent<Collider>();
|
||||||
|
|
||||||
|
CaptureStartPose();
|
||||||
|
}
|
||||||
|
|
||||||
private void Reset()
|
private void Reset()
|
||||||
{
|
{
|
||||||
dice = GetComponent<Dice>();
|
dice = GetComponent<Dice>();
|
||||||
rb = GetComponent<Rigidbody>();
|
rb = GetComponent<Rigidbody>();
|
||||||
|
diceCollider = GetComponent<Collider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CaptureStartPose()
|
||||||
|
{
|
||||||
|
if (_startPoseCaptured) return;
|
||||||
|
|
||||||
|
_startLocalPosition = transform.localPosition;
|
||||||
|
_startPoseCaptured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +112,12 @@ namespace YachtDice.Dice
|
|||||||
{
|
{
|
||||||
if (IsRolling) return;
|
if (IsRolling) return;
|
||||||
|
|
||||||
|
if (dice == null || rb == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("DiceRoller: отсутствуют обязательные компоненты Dice/Rigidbody.", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_rollRoutine != null)
|
if (_rollRoutine != null)
|
||||||
StopCoroutine(_rollRoutine);
|
StopCoroutine(_rollRoutine);
|
||||||
|
|
||||||
@@ -80,12 +127,17 @@ namespace YachtDice.Dice
|
|||||||
private IEnumerator RollSequence()
|
private IEnumerator RollSequence()
|
||||||
{
|
{
|
||||||
IsRolling = true;
|
IsRolling = true;
|
||||||
|
CaptureStartPose();
|
||||||
|
|
||||||
// ── 1. Подготовка ────────────────────────────────────────────
|
// ── 1. Подготовка ────────────────────────────────────────────
|
||||||
|
if (diceCollider != null)
|
||||||
|
diceCollider.enabled = true;
|
||||||
|
|
||||||
rb.isKinematic = false;
|
rb.isKinematic = false;
|
||||||
rb.useGravity = true;
|
rb.useGravity = true;
|
||||||
rb.linearVelocity = Vector3.zero;
|
rb.linearVelocity = Vector3.zero;
|
||||||
rb.angularVelocity = Vector3.zero;
|
rb.angularVelocity = Vector3.zero;
|
||||||
|
var rollStartedAt = Time.time;
|
||||||
|
|
||||||
// ── 2. Импульс: подбросить вверх с лёгким разбросом ─────────
|
// ── 2. Импульс: подбросить вверх с лёгким разбросом ─────────
|
||||||
Vector3 force = new Vector3(
|
Vector3 force = new Vector3(
|
||||||
@@ -105,9 +157,17 @@ namespace YachtDice.Dice
|
|||||||
// ── 4. Ждём пока кубик успокоится ───────────────────────────
|
// ── 4. Ждём пока кубик успокоится ───────────────────────────
|
||||||
var stillTimer = 0f;
|
var stillTimer = 0f;
|
||||||
var sqrThreshold = settleSpeed * settleSpeed;
|
var sqrThreshold = settleSpeed * settleSpeed;
|
||||||
|
var didTimeout = false;
|
||||||
|
var maxDuration = Mathf.Max(0.1f, maxRollDuration);
|
||||||
|
|
||||||
while (stillTimer < settleDelay)
|
while (stillTimer < settleDelay)
|
||||||
{
|
{
|
||||||
|
if (Time.time - rollStartedAt >= maxDuration)
|
||||||
|
{
|
||||||
|
didTimeout = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
yield return new WaitForFixedUpdate();
|
yield return new WaitForFixedUpdate();
|
||||||
|
|
||||||
bool isSlow = rb.linearVelocity.sqrMagnitude < sqrThreshold
|
bool isSlow = rb.linearVelocity.sqrMagnitude < sqrThreshold
|
||||||
@@ -116,6 +176,9 @@ namespace YachtDice.Dice
|
|||||||
stillTimer = isSlow ? stillTimer + Time.fixedDeltaTime : 0f;
|
stillTimer = isSlow ? stillTimer + Time.fixedDeltaTime : 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (didTimeout)
|
||||||
|
Debug.LogWarning($"DiceRoller: бросок принудительно завершён по таймауту ({maxDuration:0.##} c).", this);
|
||||||
|
|
||||||
// ── 5. Замораживаем физику и читаем верхнюю грань ───────────
|
// ── 5. Замораживаем физику и читаем верхнюю грань ───────────
|
||||||
rb.linearVelocity = Vector3.zero;
|
rb.linearVelocity = Vector3.zero;
|
||||||
rb.angularVelocity = Vector3.zero;
|
rb.angularVelocity = Vector3.zero;
|
||||||
@@ -124,8 +187,7 @@ namespace YachtDice.Dice
|
|||||||
if (!dice.TryGetTopValue(out int topValue))
|
if (!dice.TryGetTopValue(out int topValue))
|
||||||
{
|
{
|
||||||
Debug.LogWarning("DiceRoller: не удалось определить верхнюю грань.");
|
Debug.LogWarning("DiceRoller: не удалось определить верхнюю грань.");
|
||||||
IsRolling = false;
|
topValue = 1;
|
||||||
yield break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 6. Плавный доворот до ровного положения ─────────────────
|
// ── 6. Плавный доворот до ровного положения ─────────────────
|
||||||
@@ -139,20 +201,73 @@ namespace YachtDice.Dice
|
|||||||
transform.rotation = startRot;
|
transform.rotation = startRot;
|
||||||
|
|
||||||
var elapsed = 0f;
|
var elapsed = 0f;
|
||||||
while (elapsed < snapDuration)
|
var snapTime = Mathf.Max(0.01f, snapDuration);
|
||||||
|
var snapCurveToUse = snapCurve ?? AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||||
|
while (elapsed < snapTime)
|
||||||
{
|
{
|
||||||
elapsed += Time.deltaTime;
|
elapsed += Time.deltaTime;
|
||||||
float t = snapCurve.Evaluate(Mathf.Clamp01(elapsed / snapDuration));
|
float t = snapCurveToUse.Evaluate(Mathf.Clamp01(elapsed / snapTime));
|
||||||
transform.rotation = Quaternion.Slerp(startRot, targetRot, t);
|
transform.rotation = Quaternion.Slerp(startRot, targetRot, t);
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
transform.rotation = targetRot;
|
transform.rotation = targetRot;
|
||||||
|
|
||||||
// ── 7. Готово ───────────────────────────────────────────────
|
// ── 7. Возвращаемся в стартовую позицию без коллизий ───────
|
||||||
|
if (diceCollider != null)
|
||||||
|
diceCollider.enabled = false;
|
||||||
|
|
||||||
|
yield return ReturnToStartPosition();
|
||||||
|
|
||||||
|
if (diceCollider != null)
|
||||||
|
diceCollider.enabled = true;
|
||||||
|
|
||||||
|
// ── 8. Готово ───────────────────────────────────────────────
|
||||||
IsRolling = false;
|
IsRolling = false;
|
||||||
OnRollFinished?.Invoke(topValue);
|
OnRollFinished?.Invoke(topValue);
|
||||||
|
|
||||||
// Debug.Log($"{gameObject.name} | Выпало: <b>{topValue}</b>");
|
// Debug.Log($"{gameObject.name} | Выпало: <b>{topValue}</b>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerator ReturnToStartPosition()
|
||||||
|
{
|
||||||
|
var startPos = transform.localPosition;
|
||||||
|
var duration = Mathf.Max(0.01f, returnDuration);
|
||||||
|
|
||||||
|
yield return WaitForReturnTurn();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var elapsed = 0f;
|
||||||
|
var returnCurveToUse = returnCurve ?? AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||||
|
while (elapsed < duration)
|
||||||
|
{
|
||||||
|
elapsed += Time.deltaTime;
|
||||||
|
|
||||||
|
float normalized = Mathf.Clamp01(elapsed / duration);
|
||||||
|
float curved = returnCurveToUse.Evaluate(normalized);
|
||||||
|
|
||||||
|
var pos = Vector3.Lerp(startPos, _startLocalPosition, curved);
|
||||||
|
pos.y += Mathf.Sin(normalized * Mathf.PI) * returnArcHeight;
|
||||||
|
|
||||||
|
transform.localPosition = pos;
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
transform.localPosition = _startLocalPosition;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_activeReturnRoller == this)
|
||||||
|
_activeReturnRoller = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator WaitForReturnTurn()
|
||||||
|
{
|
||||||
|
while (_activeReturnRoller != null && _activeReturnRoller != this)
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
_activeReturnRoller = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user