using Godot; using System; public partial class ChatLogContainer : VBoxContainer { public enum ChatState { Hidden, Default, Scrolling } private ChatState _state; public ChatState CurrentState { get => _state; set { _state = value; switch (_state) { case ChatState.Hidden: break; case ChatState.Default: break; case ChatState.Scrolling: break; default: throw new ArgumentOutOfRangeException(); } } } private const float MaxChatLogContainerSize = 200; private Vector2 _initialPosition; // Called when the node enters the scene tree for the first time. public override void _Ready() { _initialPosition = Position; _state = ChatState.Default; } private Vector2 GetBottomPosition() { return _initialPosition + new Vector2(Size.X, MaxChatLogContainerSize) - Size; } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _PhysicsProcess(double delta) { if (CurrentState is ChatState.Default && Size.Y > MaxChatLogContainerSize) { Position = GetBottomPosition(); } } public override void _Input(InputEvent @event) { if (@event.IsActionPressed("ui_down")) { switch (CurrentState) { case ChatState.Hidden: return; case ChatState.Default: CurrentState = ChatState.Scrolling; break; case ChatState.Scrolling: break; default: throw new ArgumentOutOfRangeException(); } Position = (Position + new Vector2(0, -10)).Clamp(GetBottomPosition(), _initialPosition); } if (@event.IsActionPressed("ui_up")) { switch (CurrentState) { case ChatState.Hidden: return; case ChatState.Default: CurrentState = ChatState.Scrolling; break; case ChatState.Scrolling: break; default: throw new ArgumentOutOfRangeException(); } Position = (Position + new Vector2(0, 10)).Clamp(GetBottomPosition(), _initialPosition); } if (CurrentState is ChatState.Default or ChatState.Scrolling) { } } }