chip-gameV3/Assets/Scripts/Settings/SettingsScreen.cs

149 lines
4.6 KiB
C#

using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SettingsScreen : MonoBehaviour, IControlable
{
[SerializeField] private MenuSettingsTransit _menuSettingsTransit;
[Header("Ссылки")]
[SerializeField] private SettingGroup GroupPrefab;
private int activeSettingIndex;
private List<BaseSettingView> settings;
[SerializeField] RectTransform _testPointer;
[SerializeField] CanvasGroup _pointerCG;
[SerializeField] ScrollRect scrollRect;
[SerializeField] TextMeshProUGUI _description;
[Header("Управление")]
[SerializeField] private Axis switchAxis = Axis.Vertical;
[SerializeField] private Axis interactAxis = Axis.Horizontal;
[SerializeField] private PlayerAction intractButton = PlayerAction.action;
[SerializeField] private RectTransform _rootRect;
[SerializeField] private RectTransform Content;
[SerializeField] RectTransform _scrollBar;
private BaseSettingView SelectedSetting => settings[activeSettingIndex];
private HoldTimer _exitTimer;
public bool ControlsEnabled { get; set; } = false;
private bool controlsBlocked = false;
private void Start()
{
print("Start settings");
Generate();
UpdatePointer();
}
private void OnDisable()
{
_exitTimer.Reset();
}
public void UpdateControls()
{
if(controlsBlocked && In.GetButtonAnyPlayer(PlayerAction.action) == false)
controlsBlocked = false;
if (controlsBlocked)
return;
int switchDirection = -In.GetAxis(switchAxis, JoystickSide.Both);
if (switchDirection != 0)
SwitchSetting(switchDirection);
int interactDirection = In.GetAxis(interactAxis, JoystickSide.Both, InteractMode.Continious);
bool action = In.GetButtonAnyPlayer(PlayerAction.action);
SelectedSetting.TakeInput(interactDirection, action);
if(_exitTimer.Update(In.GetButton(InSignal.secret)))
{
_menuSettingsTransit.GotoMenu();
}
}
public void Generate()
{
ClearContent();
settings = new List<BaseSettingView>();
foreach (var group in SettingsManager.currentSchemeDTO.groups)
settings.AddRange(GenerateGroup(group).settings);
_exitTimer = new HoldTimer(1);
ControlsEnabled = true;
}
public void BlockControls() => controlsBlocked = true;
private void SwitchSetting(int switchDirection)
{
SelectedSetting.Deselect();
activeSettingIndex = (activeSettingIndex + switchDirection + settings.Count) % settings.Count;
SelectedSetting.Select();
_description.text = SelectedSetting.CachedSetting.Description;
UpdatePointer();
}
private void UpdatePointer()
{
var activePivot = SelectedSetting.pivotPoint;
ScrollToElementVertical(activePivot);
_testPointer.position = activePivot.position;
_pointerCG.alpha = SelectedSetting is SignalView ? 0 : 1;
_scrollBar.anchoredPosition = new Vector2(0, -460f * activeSettingIndex / (settings.Count-1));
}
private SettingGroup GenerateGroup(SettingsGroupDTO groupData)
{
var group = Instantiate(GroupPrefab, Content);
group.Configure(groupData);
return group;
}
private void ClearContent()
{
for (int i = Content.childCount - 1; i >= 0; i--)
Destroy(Content.GetChild(i).gameObject);
}
private void ScrollToElementVertical(RectTransform targetRect)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(scrollRect.content);
RectTransform viewport = scrollRect.viewport;
RectTransform content = scrollRect.content;
Vector2 targetLocalPos = content.InverseTransformPoint(targetRect.position);
Vector2 viewportLocalPos = content.InverseTransformPoint(viewport.position);
float targetHeight = targetRect.rect.height;
float viewportHeight = viewport.rect.height;
float contentHeight = content.rect.height;
if (contentHeight <= viewportHeight)
{
scrollRect.verticalNormalizedPosition = 1f;
return;
}
float offsetY = (targetLocalPos.y - viewportLocalPos.y) * -1f;
float targetCenterY = offsetY + targetHeight * 0.5f;
float viewportCenterY = viewportHeight * 0.5f;
float deltaY = (targetCenterY - viewportCenterY) / (contentHeight - viewportHeight);
float newPosition = Mathf.Clamp01(scrollRect.verticalNormalizedPosition - deltaY);
scrollRect.verticalNormalizedPosition = newPosition;
}
}