Rama's Extra Blueprint Nodes for UE5, No C++ Required!

SwitchByte will take less memory than SwitchInt
(SwitchWildcard This is already a show off)

this function should be in Ue4

// Переназначить поведение навигации получив виджет для курсора
UFUNCTION(Category="IVS|Set", BlueprintCallable, BlueprintCosmetic, Meta=(DefaultToSelf="Widget")) static void EscapeNavigation(UWidget* Widget, EUINavigation Direction, UWidget*& R);


void UILbr::EscapeNavigation(UWidget * Widget, EUINavigation Direction, UWidget * & R) {
  FVector2D Position = Widget -> GetCachedWidget() -> GetPaintSpaceGeometry().GetAbsolutePosition(), NewPosition, OldPosition;
  FVector2D Size = Widget -> GetCachedWidget() -> GetPaintSpaceGeometry().GetAbsoluteSize(), NewSize, OldSize;
  TSharedPtr < SWidget > C;
  UWorld *
    const World = GEngine -> GetWorldFromContextObject(Widget, EGetWorldErrorMode::ReturnNull);
  if (!World) {
    return;
  }
  bool expr = false;
  auto F {
    [](UWidget * R, float NewP, float OldP, float New, float Old, float Pos, bool & expr) {
      if (expr && IsValid(R)) {
        expr = NewP > OldP || (NewP == OldP && abs(New - Pos) < abs(Old - Pos));
      }
    }
  };
  for (TObjectIterator < UWidget > Itr; Itr; ++Itr) {
    if (Itr -> GetWorld() != World || * Itr == Widget) {
      continue;
    }
    // GetCachedWidget() получить ссылку. TakeWidget() получить ссылку, при неудаче создает SWidget
    C = Itr -> GetCachedWidget();
    if (C.IsValid() && C -> GetVisibility().IsVisible() && C -> SupportsKeyboardFocus()) {
      NewPosition = C -> GetPaintSpaceGeometry().GetAbsolutePosition();
      NewSize = C -> GetPaintSpaceGeometry().GetAbsoluteSize();
      //X длина. Y Высота. Отсчёт сверху слева. Элементы могут перекрываться так что Size не используем)IsInteractable
      switch (Direction) {
      case EUINavigation::Left:
        expr = NewPosition.X + NewSize.X <= Position.X;
        F(R, NewPosition.X + NewSize.X, OldPosition.X + OldSize.X, NewPosition.Y, OldPosition.Y, Position.Y, expr);
        break;
      case EUINavigation::Right:
        expr = NewPosition.X >= Position.X + Size.X;
        F(R, OldPosition.X + OldSize.X, NewPosition.X + NewSize.X, NewPosition.Y, OldPosition.Y, Position.Y, expr);
        break;
      case EUINavigation::Up:
        expr = NewPosition.Y + NewSize.Y <= Position.Y;
        F(R, NewPosition.Y + NewSize.Y, OldPosition.Y + OldSize.Y, NewPosition.X, OldPosition.X, Position.X, expr);
        break;
      case EUINavigation::Down:
        expr = NewPosition.Y >= Position.Y + Size.Y;
        F(R, OldPosition.Y + OldSize.Y, NewPosition.Y + NewSize.Y, NewPosition.X, OldPosition.X, Position.X, expr);
      }
      if (expr) {
        R = * Itr;
        OldPosition = NewPosition;
        OldSize = NewSize;
      }
    }
  }
}
2 Likes