Всем привет! Я новичок в программировании и сейчас активно изучаю UMG и столкнулся с некоторыми сложностями.
Я сделал главное меню и при нажатии на кнопку "Новая игра" должен появляется новый виджет с меню выбора персонажа. При сборке проекта клик отрабатывает(выводил в логи), но новый виджет не создается(Пробовал выводить инфу при в лог при создании виджета).
void UMainMenu::OnNewGameClicked() { if( ChangeHeroWidgetClass) { ChangeHeroWidget = CreateWidget<UChangeHeroWidget>( GetGameInstance( ), ChangeHeroWidgetClass); if( ChangeHeroWidget) { ChangeHeroWidget->AddToViewport( ); } } }
При этом если сделать логику на блюпринтах, то все отлично работает.
Трудность явно возникает на моменте создания виджета, искал варианты и нашел только сделать через Pawn-а и PlayerController, но не хотелось бы плодить классы только для вывода главного меню.
Очень прошу у Вас помощи и буду благодарен за любые идеи и предложения.
P.S. возможно кода маловато, но я не хотел бы забивать им пост. Если нужна доп. информация, то напишите, пожалуйста, и я скину в комментариях.
покажи объявления ChangeHeroWidgetClass и ChangeHeroWidget
У тебя строчка
ChangeHeroWidget = CreateWidget<UChangeHeroWidget>(GetGameInstance( ), ChangeHeroWidgetClass);
выполняется, и ты получаешь ChangeHeroWidget == nullptr или как?
Используй отладчик, а не логи - так быстрее проблему найдёшь в разы.
Ryzen
Я пробовал вместо GameInstance изначально использовать GetWorld(), но это тоже не сработало, так что скорее всего тут в другом проблема.
pahaa
UPROPERTY(EditAnywhere) TSubclassOf<UChangeHeroWidget> ChangeHeroWidgetClass; UPROPERTY( ) UChangeHeroWidget* ChangeHeroWidget;
Райдер мне подсказывает что при объявлении TSubclassOf<UChangeHeroWidget> он не понимает о каком виджете идет речь, хотя в unreal-e он создан.
До этого делал по чужим чертежам систему инвентаря, но там райдер понимает о каком виджете идет речь.
Наследование у виджетов корректное, перепроверял,поэтому не совсем понимаю где я и что делаю не так.
Скорее всего мне нужна тут функция инициализации( в ней пока не совсем разобрался, т.к. только вникаю в тему).
Emphatic44
> Райдер мне подсказывает что при объявлении TSubclassOf<UChangeHeroWidget> он не понимает о каком виджете идет речь, хотя в unreal-e он создан.
Смысл фразы не особо понятен. Если бы у тебя не было объявления, то компилятор проект бы просто не собрал.
У тебя в экземпляре UMainMenu в редакторе указан класс ChangeHeroWidgetClass? Ведь у твоего UChangeHeroWidget может быть 100500 подклассов. Если ты ручками не указал в редакторе конкретный, то в этой переменной ничего и не будет. У тебя вон даже в подсказке написано "unchanged in assets".
А ещё попробуй написать так:
ChangeHeroWidget = CreateWidget<UChangeHeroWidget>(GetGameInstance( ), ChangeHeroWidgetClass.Get( ));
Emphatic44
> Я пробовал вместо GameInstance изначально использовать GetWorld()
Это повлияет на время жизни виджета. Если родителем поставишь GameInstance, то виджет сможет путешествовать из одной сцены в другую (как экран загрузки, например). А если поставишь родителем World, то виджет автоматически уничтожится при выгрузке уровня (удобно для игрового HUDа, например).
может глупость скажу, сам то я в блупринтах почти всё делаю, но из вот этого
ChangeHeroWidget = CreateWidget<UChangeHeroWidget>(GetGameInstance(), ChangeHeroWidgetClass);
1)не понятно, а как твой виджет получает ссылку на Player Controller? (см. блупринт из первого поста)
и в качестве второго глупого вопроса:
2) Вот это "WBP ChangeHe..." и UChangeHeroWidget или ChangeHeroWidgetClass это точно как-то связано? Им WBP не мешает?
ЗЫ я б ещё проверил точками останова, заходит ли программа в
{ ChangeHeroWidget->AddToViewport(); }