"bir yazılımcının not defteri.."

18 Temmuz 2017 Salı

yedinci mini uygulama - UMG kullanıcı arabirimi

merhabalar,

şimdi Unreal Motion Graphics (UMG) leri ve onlarla nasıl temel çoklu ekranlı ve button lu menü sistemleri yaratacağımızı anlayacağız,


1. gereklilikleri ayarlayalım:
önce C++ şablonlu yeni bir proje yaratalım adına da HowTo_UMG diyelim:



Unreal Motion Graphics (UMG) için Visual Studio ya birkaç modül dahil etmemiz gerekiyor, bunlar default olarak dahili değillerdir.

ilk olarak editörden File menüsünden Open Visual Studio diyelim.


UMG
birkaç modüle bağımlıdır, dolayısı ile onları HowTo_UMG.Build.cs dosyasına eklememiz gerekir.

BuildCS.png

HowTo_UMG.Build.CS dosyasında listelenen public modüllere UMG yi de ekleyelim ve de Slate ve SlateCore modüllerini de; bunun için HowTo_UMG constructor fonksyonunun ilk satırını değiştirmeliyiz:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

ve aşağıdaki satırın commentini kaldırın:

PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
UMG yi ayarlamak için projemizin özel (custom) Game Mode una kod eklemeliyiz; ki oyun menüleri görünebilsin;

kodun tamamı aşağıdadır:

HowTo_UMG.Build.cs
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}

2. Game Mode umuzu geinşletelim (Extend edelim):
menü yaratmak için User Widgets kullanacağız, bunun için biraz kod yazıp bir fonksyon yaratacağız, oyun başladığında bu fonksyonu çağıracaz ve o da widget i yaratacak.

her bir projemiz özel GameMode class ı ile geldiğinden, projemiz ile birlikte geleni kolayca açabiliriz, ilgili dosya burada HowTo_UMGGameMode.h dir; aşağıda takip eden satırlar ve özellikler eklenmelidir:

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;

kodumuzda User Widgets i kullanmak için ilk olarak ilgili class ı projemize include ile dahil edelim:

#include "Blueprint/UserWidget.h"

şimdi HowTo_UMGGameMode.cpp dosyasına geçelim, tanımlamasını yaptığımız iki fonksyonun gövdelerini doldurmamız gerek, şimdi BeginPlay() fonksyonunu override ederek başlayalım:

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}
parent class dan gelen fonksyonları override ettiğimizde (burada BeginPlay de yaptığımız gibi), bu fonksyonun parent class daki versiyonunu çağırmamız genellikle önemlidir; eğer ki tanımladığımız fonksyon parent deki fonksyon versonunun kodlarının sonuna bir satır ekler nitelikte ise mutlaka önce onu çağırmalıyız: 

Super::BeginPlay bu şekilde ilk satırda parent versiyonunu çağrırız, sonra kendi kodlarımızı yazarız. 

Bir sonraki adımda yine HowTo_UMGGameMode.cpp dosyasında menü değişikliklerini tanımlayacağız, önce viewport daki aktif widget leri kaldıralım, eğer varsa, şimdi yeni bir tane yaratıp viewport a ekleyelim:
void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}
 
bu kod temin edip ekrana ekrana koyduğumuz herhangi bir Widget in instance ini yaratır; aynı zamanda onları kaldırır; böylece tek seferde sadece bir tanesi aktif olabilir; yine de Unreal Engine bir defada çoklu Widget gösterimi yapabilir. 

Bir Widget i doğrudan yoketmemize (destroy) gerek yokur, çünkü onu viewort tan kaldırma ve onu işaret eden tüm değişkenleri (variables) temizlemek / değiştirmek Unreal Engine in garbage collection sistemi tarafından temizlenmesine neden olur.

Nihayetinde Player Controller class ımızdaki input mode ı ayarlamamız lazım; bunu yapmak için, projemize Player Controller a dayalı (based on) yeni bir C++ class ı ekleyeceğiz.

Oyun başladığında, UI elemanlaeri ile etkileşimde olabildiğimize emin olmak için bu sınıfta sadece extra bir fonksyon çağırmamız gerekir,




HowTo_UMGPlayerController.h içinde, aşağıdaki override satırını ekliyoruz:

public:
    virtual void BeginPlay() override;

ve HowTo_UMGPlayerController.cpp içinde de aşağıdaki overridden function satırını ekliyoruz:
void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}
menüleri yaratmak için kodu built edin; şimdi editöre dönüp menü asset lerini tasarlama zamanı.

kodun tamamının şöyle olması gerekiyor bu arada:

HowTo_UMG.Build.cs
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}
HowTo_UMGGameMode.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameFramework/GameModeBase.h"
#include "HowTo_UMGGameMode.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;
};
HowTo_UMGGameMode.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGGameMode.h"

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}

void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}

HowTo_UMGPlayerController.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/PlayerController.h"
#include "HowTo_UMGPlayerController.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;
};

HowTo_UMGPlayerController.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGPlayerController.h"

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}


3. Menu Widget Blueprint ini yaraalım:
Unreal Editor içinden Compile button u a basın ve derleyin, 



şimdi Game Mode umuzun menü olarak kullanacağı User Widgets i yaratıcaz; bu Content Browser içindeki Add New buttonu ile yapılır.

Widget Blueprint class ı User Interface kategorisi altında bulunur. Bunlardan iki tane yaratmamız lazım; ilkinin adı MainMenu diğerinin adı da NewGameMenu olsun. Oyunumuz Main Menü de başlayacak, ve New Game Menu de devam etmek için bir opsiyona sahip olacak.


az önce yarattığımız Main Menü Widget ine çift tıkladığımızda BluePrint design ekranına gider, burada menü müzü düzenleyebiliriz.
Şimdi Common kısmından bi button ve bir Text sütükleyip bırakın. Bu button eninde sonunda New Game Menü yü açmak için kullanılacak.



iyi bir düzen için ilk adım button un yerini (location) ve büyüklüğünü (size) ayarlamaktır; aşağıdaki değişiklikleri yapalım:

size: 200x200.
position:  (200, 100).

adını da NewGameButton yapın, ki daha sonra fonksyonalitede adından daha anlaşılır olacaktır.


bu button için özel bir imaj seti çizmediğimizden dolayı onu Text Blok içine sürükleyerek etiketleyebiliriz (Label) , sonra aşağıdaki değişiklikleri yapın:

text: New Game.
Visibility:  Hit Test Invisible. 

Bu, Metin Bloğunun altındaki Button için planlanan mouse tıklamalarını kesmesini önleyecektir.

ismini NewGameText olarak ayarlayın, şart olmasa da iyi bir alışkanlıktır.



sonraki aşamada bir de Quit button yapalım; ve de Text bloğu ayarlayalım; bunları da yukarıdaki ile aynı yolla yapıyoruz;  sonra aşağıdaki değişiklikleri de yapalım aynı şekilde:

button adı: QuitButton
button positionu: 600, 100
Text Block adı QuitText

ardından, buttonlarımıza Event ler ekleyelim, ki onlara tıklandığında belli bazı kodlar koşsun.

bu, details panel içindeki ilgili event in yanındaki + buttonuna basarak yapılır; bu vakamızda OnClicked kullanmak istediğimiz event tir; bu event i NewGameButton ve QuitButton widgets lerin her ikisi için de yaratalım.


burada tasarımcılar Blueprint script ile fonksyonalite yaratabilir, veya C++ programcıları ortaya konan fonksyonları çağıran bu node lara bağlanabilir; OnClicked (NewGameButton) adı verilen olay için isteyeceğiz ki: daha önceden GameMode umuza eklediğimiz fonksyonumuzu kullanmak için ChangeMenuWidget noduna bağlanın.

ChangeMenuWidget nodundaki New Widget Class alanını (field) NewGameMenu asset olarak ayarlayın; 

OnClicked (QuitButton) Event i için, Quit Game noduna bağlamak isteyeceğiz.


ana menümüz oluşturulmuşken level başlangıcında hemen onu yükleyecek olan GameMode asset imizi ayarlayabiliriz;

kodun son hali şöyle:

HowTo_UMG.Build.cs
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}

HowTo_UMGGameMode.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameFramework/GameModeBase.h"
#include "HowTo_UMGGameMode.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;
};

HowTo_UMGGameMode.cpp
/ Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGGameMode.h"

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}

void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}

HowTo_UMGPlayerController.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/PlayerController.h"
#include "HowTo_UMGPlayerController.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;
};
HowTo_UMGPlayerController.cpp
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGPlayerController.h"

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}



4. Game Mode umuzu Configure edelim:
Content Browser içinde projemizin GameMode umuza bağlı olan Blueprint Class ımızı ekleyeceğiz; bu, her iki class daki açıklanan değişkenlere istediğimiz değerleri set edebilmemizi mümkün kılar.

bunu yapmak için : 

Content Browser dan Add buttonuna basın



HowTo_UMGGameMode ı parent class olarak seçin; All Classes kısmında bu listelenecektir.



elde edilen Blueprint asset ini MenuGameMode olarak isimlendirin.

oyunda mouse cursor ünü görmek istiyorsanız, GameMode umuzda yaptığımız gibi PlayerController in Blueprint ini yaratmalıyız.

Content Browser dan yine Add buttonuna tıkalyın,
Common Classes kısmından Player Controller seçin;
onu MenuPlayerController olarak isimlendirin;
sonra MenuPlayerController i editleyin;
Show Mouse Cursor box tikini işaretleyin;



MenuGameMode i şimdi editleyelim;

oyun başladığında menüyü getirmesi için Starting Widget Class MainMenu asset e ayarlanmalıdır.

Default Pawn Class, DefaultPawn yerine Pawn a set edilmeli, ayarlanmalı, böylece oyuncu (player) menüde gezinemez.

Player Controller Class yarattığımız MenuPlayerController e ayarlanmalıdır ki böylece mouse cursor oyun içinde görünecektir.



Blueprint in kullanılabilmesi için Level Editor penceresine dönmeliyiz ve World Settings i Level imiz için değiştirmeliyiz.



Project Settings menüsünde Maps and Modes section unda default GameModunu ayarlamak da mümkündür; eğer bu şekilde yaparsanız tüm level lerimiz default olarak seçtiğimiz GameModunda olacaktır; (bireysel olarak overrride etmedikçe).  Kullanacağınız metod projenizi nasıl ayarlayacağınıza bağlı olarak değişir.

World Settings Panel ini açın, şimdi GameMode u değiştirmeliyiz, burada bizim MenuGameMode asset ini ayarlayın.



bizim özel GameMode asset imiz şimdi level imizde aktif olacak, ve Main Menu yü yüklemek üzere configure edecek ve cursor ün gösteren Player Controller imizi kullanacak. Eğer oyunu şimdi Run edersek beklendiği gibi Quit button çalışacak ve New Game button bizi boş menü ekranına götürecektir. Bir sonraki aşamada New Game Menü yü ayarlayalım.

kodun tamamı şu şekildedir:

HowTo_UMG.Build.cs
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}

HowTo_UMGGameMode.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameFramework/GameModeBase.h"
#include "HowTo_UMGGameMode.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;
};

HowTo_UMGGameMode.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGGameMode.h"

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}

void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}

HowTo_UMGPlayerController.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/PlayerController.h"
#include "HowTo_UMGPlayerController.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;
};

HowTo_UMGPlayerController.cpp
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGPlayerController.h"

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}


5. ikinci menüyü ayarlayalım:
Content Browser içinde, yarattığımız NewGameMenu yü bulun. Bu menü isim girişi içerecek, yani Tect Box olacak, ve bir isim girilmeden basılamayacak bir Button oyunu Play edecek / başlatacak, ve bir Button da Main Menu ye geri döndürecek olsun.

şimdi bir Text box sürükleyin;



Text Box ı aşağıdaki şekilde configure edin:
ismi: NameTextEntry;
pozisyonu: (325, 200); 
Bu, Text Box ın soluna yerleştirilen bir Metin Bloğu için yer bırakır.
byüklüğü (size): 250x40;
Font Size: 20;

şimdi Text Box label ile Play Game Button u yaratabiliriz.
Button un adını PlayGameButton olarak değiştirim. Pozisyonunu da : 200, 300, Size to 200, 100  olarak belirleyelim.

Text Bloğu için ise; adını PlayGameText yapın ve Visibility özelliğini Hit Test Visible olarak değiştirin ve de PlayGameButton un üzerine sürükleyin.

Play Game Button u özel bir özelliğe sahip olacak, o sadece text box a isim girildiğinde enabled edilecek, yani text box boş olmadığında.

Unreal Motion Graphics' (UMG) özellik bağlama yı Enabled / Disabled alanı adına yeni bir fonksyon yaratmak için kullanabiliriz. (under the Behavior section).
oyunumuzda geçerli oyuncu ismi olduğunu ayırt etmemiz yani valiasyon gerekiyor ise veya bu ismi bir C++ değişkenine kaydetmemiz gerekiyor ise, GameMode umuzda UFUNCTION kullanabilir, veya projede bir yerde bir static fonksyon da kullanılabilir. Her ne kadar biz sadece metin kutusunun boş olup olmadığını umursuyor olsak bile bu widget için script yaratabiliriz.

Button un yalnızca Metin Kutusu boş değilse etkinleştirildiğinden emin olmak için, Text Box daki değeri string e çevirmeliyiz ve onun büyüklüğünü kontrol etmeliyiz, sıfır mı yoksa daha büyük mü ? bu mantığın nasıl görüneceğine dair şema şöyle :



Bir düğme daha ekleyelim, böylece geri çekebilir ve buradan Ana Menü'ye gidebiliriz. bu tıpkı Main Menü müzdeki Play Game Button u gibi olacak, fakat pozisyonu sağ alt köşeye göre relative olacak. Bunu ypmak için Details Panel de bu button için Anchors dropdownuna tıklayın, ve pop up menü içinden uygun grafik temsilciyi bulun; 

ismini MainMenuButton olarak değiştirin,
pozisyonunu  -400, -200
büyüklüğünü (size):  200x100



anchor ümüzü sağ alt köşeye konumlamak büyüklük ve pozisyon değerlerinin (values) çalışmasını değiştirmez; yani pozisyon değerlerimizi ekran üzerinde olması için negatif yapmamız lazım; size değeri (value) pozitif kalacak (remain).

şimdi yeni buttonlarımıza bir kez daha OnClicked event i ekleyerek script ekleyeceğiz. Play Game button u ChangeMenuWidget fonksyonuna yapılan çağrıda yeni bir widget almadan menümüzü tamamen deaktif edecek iken Main Menu button u basitçe Main Menu Widget i reload edecek.

bu Select Class ifadesi ile görterilir, sınıf veya asset adı yerine.



menüyü Play Game Button u ile deactivate ettikten sonra oyunda daha fazla birşey yapamaz hale geleceğiz. Bu, normalde ilk level i yüklediğimiz, bir giriş sahne animasyonu (introductory cutscene) oynattığımız, veya spawn ya da bie Pawn ı possess yaptığımız noktaydı.

şimdi aşağı yukarı şu iki ekrana sahip olmalıyız:





kodun tamamı isde şöyledir: 

HowTo_UMG.Build.cs
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}


HowTo_UMGGameMode.h
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameFramework/GameModeBase.h"
#include "HowTo_UMGGameMode.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;
};

HowTo_UMGGameMode.cpp
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGGameMode.h"

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}

void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}


HowTo_UMGPlayerController.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/PlayerController.h"
#include "HowTo_UMGPlayerController.generated.h"

/**
 * 
 */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;
};

HowTo_UMGPlayerController.cpp
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGPlayerController.h"

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}


6. ev ödevi:
öğrendiklerimizle aşağıdakileri yapmaya çalışalım:
  • aynı anda bir den fazla menü açmaya çalışın. 
  • Widgets ları ekranda karartın (fade) ve ekranda kaydırın onları sadece gösterip kaldırmak yerine. 
  • Widget ların desteklediği farklı renk ve özellikler deneyin. 
  • GameMode unuza farklı değişkenler ayarlayın (set edin) örneğin zorluk seviyesi (difficulty level), character class ı gibi; ve bunu menülerin içinden yapın. 
  • oyun için menüler yapın, oyuncu bir tuşa bastığında popup olarak çıksın ve oyunu durdursun, ve kapandığında gameplay devam etsin. 

Hiç yorum yok: