This commit is contained in:
Oscar
2025-05-28 17:15:12 +03:00
parent 37173c8b39
commit 77c1704cd6
35 changed files with 80065 additions and 851 deletions

View File

@@ -1,26 +1,64 @@
@using System.Threading.Tasks
@inherits PanelComponent
@inherits PanelComponent
<root class="interaction-panel">
<div class="label">@InteractionString</div>
<div class="label @(IsPressed ? "pressed" : "")">@InteractionString</div>
@if (IsHoldInteraction)
@if ( IsHoldInteraction )
{
<div class="progress-bar">
<div class="progress-fill" style="width: @(ProgressionHold * 100)%"></div>
<div class="progress-fill" style="width: @( ProgressionHold * 100 )%"></div>
</div>
}
</root>
<style lang="scss">
.interaction-panel {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
transition: all 0.1s ease;
.progress-bar {
width: 100px;
height: 8px;
background-color: #333;
border-radius: 4px;
.progress-fill {
height: 100%;
background-color: limegreen;
border-radius: 4px;
}
}
.label {
padding: 8px;
border-radius: 6px;
color: white;
font-size: 56px;
background-color: rgba(0, 128, 255, 0.2);
transition: all 0.1s ease;
}
.label.pressed {
background-color: rgba(0, 128, 255, 0.6);
transform: scale(1.4);
}
}
</style>
@code {
[Property] public string InteractionString { get; set; } = "Interact";
[Property] public bool IsHoldInteraction { get; set; } = false;
[Property] public float ProgressionHold { get; set; } = 0f;
public async Task TriggerInteractAnimation()
[Property] public bool IsPressed { get; set; } = false;
public void SetPressed(bool value)
{
AddClass("interacted");
await Task.Delay(300);
RemoveClass("interacted");
IsPressed = value;
StateHasChanged(); // << 🔁 вручную обновим UI
}
}

View File

@@ -1,13 +0,0 @@
namespace Sandbox.UI;
public class HoverInfoPanelBase : WorldPanel
{
[Property] public string Label { get; set; } = "Описание";
[Property] public bool Visible { get; set; } = false;
public HoverInfoPanelBase(SceneWorld world) : base(world)
{
PanelBounds = new Rect(-200, -100, 400, 200);
WorldScale = 0.05f;
}
}

View File

@@ -0,0 +1,87 @@
using Sandbox.Diagnostics;
namespace Sandbox.UI;
public abstract class InteractionButton : Component, Component.IPressable
{
[Property] public string Label { get; set; } = "Label";
[Property] public bool RequiresHold { get; set; } = false;
private HoverInfoPanel _uiPanel;
private GameObject _interactionPanelPrefab { get; set; }
protected override void OnStart()
{
base.OnStart();
_interactionPanelPrefab = GameObject.GetPrefab("prefabs/InteractionPanel.prefab");
Log.Info(_interactionPanelPrefab.Name);
Assert.True(_interactionPanelPrefab.IsValid(), $"No InteractionPanel prefab found for {GameObject.Name}!");
}
public virtual void Hover(IPressable.Event e)
{
CreatePanel();
}
public virtual void Blur(IPressable.Event e)
{
DestroyPanel();
}
public virtual void Look(IPressable.Event e)
{
if (_uiPanel != null)
{
_uiPanel.ProgressionHold = 0f;
}
}
public virtual bool CanPress( IPressable.Event e )
{
return true;
}
public virtual bool Press(IPressable.Event e)
{
if (_uiPanel != null)
{
_uiPanel?.SetPressed(true);
}
return true;
}
public virtual void Release(IPressable.Event e)
{
if (_uiPanel != null)
{
_uiPanel?.SetPressed(false);
}
}
protected void CreatePanel()
{
if (_uiPanel != null) return;
var panelGo = _interactionPanelPrefab.Clone();
panelGo.WorldPosition = WorldPosition;
panelGo.Parent = Scene;
_uiPanel = panelGo.Components.Get<HoverInfoPanel>();
if (_uiPanel != null)
{
_uiPanel.InteractionString = Label;
_uiPanel.IsHoldInteraction = RequiresHold;
_uiPanel.ProgressionHold = 0f;
}
}
protected async void DestroyPanel()
{
if (_uiPanel == null) return;
_uiPanel.GameObject.Destroy();
_uiPanel = null;
await Task.DelaySeconds(0.05f);
}
}

View File

@@ -0,0 +1,22 @@
namespace Sandbox.UI;
[Icon("skip_next")]
public sealed class MusicPlayerNextButton : InteractionButton
{
[Property] public MyMusicPlayer MusicPlayer { get; set; }
public override bool Press(IPressable.Event e)
{
base.Press(e);
DoNextRpc(); // вызываем RPC отдельно из за того что в базовом классе абстракт и RPC там не работают
return true;
}
[Rpc.Broadcast]
private void DoNextRpc()
{
Log.Info("PRESSED");
MusicPlayer?.Next();
}
}

View File

@@ -1,24 +0,0 @@
.interaction-panel {
padding: 8px;
background-color: rgba(0,0,0,0.7);
border-radius: 6px;
color: white;
font-size: 16px;
.label {
margin-bottom: 4px;
}
.progress-bar {
width: 100px;
height: 8px;
background-color: #333;
border-radius: 4px;
.progress-fill {
height: 100%;
background-color: limegreen;
border-radius: 4px;
}
}
&.interacted {
background-color: rgba(0, 128, 255, 0.6);
}
}