using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class NewScaleZone : MonoBehaviour { [Header("Scale Parts")] [SerializeField] private Transform _chainsOriginLeft; [SerializeField] private Transform _chainsOriginRight; [SerializeField] private Transform _beam; [Header("Zones")] [SerializeField] private Collider _leftZoneCollider; [SerializeField] private Collider _rightZoneCollider; [Header("Button")] [SerializeField] private Button _startButton; [SerializeField] private Sprite _spriteStart; [SerializeField] private Sprite _spriteInProgress; [Header("UI")] [SerializeField] private TMPro.TextMeshProUGUI _attemptText; [Header("Settings")] [SerializeField] private float _tiltSpeed = 1f; [SerializeField] private float _maxTiltAngle = 15f; [SerializeField] private float _maxChainOffset = 0.2f; [SerializeField] private float _showResultTime = 1.5f; private int _attempt = 1; private Vector3 _beamStartRot; private Vector3 _leftChainStartPos; private Vector3 _rightChainStartPos; private bool _isWeighing = false; public int Attempt => _attempt; private void Start() { _beamStartRot = _beam.localEulerAngles; _leftChainStartPos = _chainsOriginLeft.localPosition; _rightChainStartPos = _chainsOriginRight.localPosition; _startButton.onClick.AddListener(OnStartPressed); UpdateAttemptText(); } private float GetMassInZone(Collider zone) { Collider[] colliders = Physics.OverlapBox( zone.bounds.center, zone.bounds.extents, Quaternion.identity ); float total = 0f; foreach (var col in colliders) { if (col.gameObject == zone.gameObject) continue; Rigidbody rb = col.GetComponent(); if (rb != null) total += rb.mass; } return total; } private void OnStartPressed() { if (_isWeighing) return; StartCoroutine(WeighRoutine()); } private IEnumerator WeighRoutine() { _isWeighing = true; _startButton.image.sprite = _spriteInProgress; float leftMass = GetMassInZone(_leftZoneCollider); float rightMass = GetMassInZone(_rightZoneCollider); float diff = rightMass - leftMass; float normalized = Mathf.Clamp(diff / 2f, -1f, 1f); float targetAngle = -normalized * _maxTiltAngle; float elapsed = 0f; float duration = 1.5f; while (elapsed < duration) { elapsed += Time.deltaTime * _tiltSpeed; float t = Mathf.Clamp01(elapsed / duration); float angle = Mathf.Lerp(0f, targetAngle, t); _beam.localEulerAngles = new Vector3( _beamStartRot.x, _beamStartRot.y, _beamStartRot.z + angle); float offset = normalized * _maxChainOffset * t; _chainsOriginLeft.localPosition = new Vector3( _leftChainStartPos.x, _leftChainStartPos.y - offset, _leftChainStartPos.z); _chainsOriginRight.localPosition = new Vector3( _rightChainStartPos.x, _rightChainStartPos.y + offset, _rightChainStartPos.z); yield return null; } yield return new WaitForSeconds(_showResultTime); elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime * _tiltSpeed; float t = Mathf.Clamp01(elapsed / duration); float angle = Mathf.Lerp(targetAngle, 0f, t); _beam.localEulerAngles = new Vector3( _beamStartRot.x, _beamStartRot.y, _beamStartRot.z + angle); float offset = normalized * _maxChainOffset * (1f - t); _chainsOriginLeft.localPosition = new Vector3( _leftChainStartPos.x, _leftChainStartPos.y - offset, _leftChainStartPos.z); _chainsOriginRight.localPosition = new Vector3( _rightChainStartPos.x, _rightChainStartPos.y + offset, _rightChainStartPos.z); yield return null; } _beam.localEulerAngles = _beamStartRot; _chainsOriginLeft.localPosition = _leftChainStartPos; _chainsOriginRight.localPosition = _rightChainStartPos; WeighingManager manager = FindObjectOfType(); if (manager != null) manager.ResetAllBalls(); _attempt++; UpdateAttemptText(); _startButton.image.sprite = _spriteStart; _isWeighing = false; } private void UpdateAttemptText() { if (_attemptText != null) _attemptText.text = "Спроба " + _attempt; } public void ShowSuccess() { int count = _attempt <= 1 ? 1 : _attempt - 1; if (_attemptText != null) _attemptText.text = "Пройдено з " + count + " спроб!"; } public void RegisterAttempt() { if (_isWeighing) return; _attempt++; UpdateAttemptText(); } public void RestartAttempts() { _attempt = 1; UpdateAttemptText(); } }