I’m trying my hand at making a card game. But the images I don’t want to add the image files to the game unless the player wants to get the card and download the image (using scryfall).
Questions
- How would I turn a uint8 TArray into an image?
- How do I turn that Image into a Dynamic Material?
- How do I then set the my StaticMesh’s material to the new dynamic material to change it on game start?
Currently, my FBX class has two images associated with it and UVWrapped to the top and bottom face. I’m using
“Material” as the bottom face and “Material_001” as the top face (I know original names). When I have two different top face images, it’s as easy as dragging the image onto the card and it sets the top face (without interfering with the bottom face as I wanted).
MTGCard.cpp
#include "MTGCard.h"
// Sets default values
AMTGCard::AMTGCard()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Begin to try and get the JSON
HttpCard = &FHttpModule::Get();
// Creates mesh object based on file location of OBJ/FBX file.
static ConstructorHelpers::FObjectFinder<UStaticMesh>MeshAsset(TEXT("StaticMesh'/Game/Objects/Test/CardTest.CardTest'"));
if (MeshAsset.Succeeded())
{
// Create a new instance of the mesh from MeshAsset.Object
UStaticMesh* Asset = MeshAsset.Object;
// Set the default subobject with a dummy text
CardMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CardMesh"));
// Set the static mesh
CardMesh->SetStaticMesh(Asset);
CardMesh->CreateAndSetMaterialInstanceDynamic(0);
// Make the object by setting it's root component
RootComponent = CardMesh;
}
}
// Called when the game starts or when spawned
void AMTGCard::BeginPlay()
{
HttpCall();
Super::BeginPlay();
}
void AMTGCard::HttpCall()
{
TSharedRef<IHttpRequest> Request = HttpCard->CreateRequest();
Request->OnProcessRequestComplete().BindUObject(this, &AMTGCard::OnResponseReceived);
// Url
Request->SetURL("https://api.scryfall.com/cards/named?fuzzy=Vorapede");
Request->SetVerb("GET");
Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent");
Request->SetHeader("Content-Type", TEXT("application/json"));
Request->ProcessRequest();
}
void AMTGCard::PngCall(const FString& url)
{
TSharedRef<IHttpRequest> Request = HttpCard->CreateRequest();
Request->OnProcessRequestComplete().BindUObject(this, &AMTGCard::OnPngReceived);
// Url
Request->SetURL(url);
Request->SetVerb("GET");
Request->ProcessRequest();
}
void AMTGCard::OnPngReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
if (bWasSuccessful && Response.IsValid())
{
TArray<uint8> ImageData = Response->GetContent();
}
}
void AMTGCard::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
if (bWasSuccessful && Response.IsValid())
{
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
FString name = JsonObject->GetStringField("name");
TSharedPtr<FJsonObject> InnerJson = JsonObject->GetObjectField("image_uris");
GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, name);
GEngine->AddOnScreenDebugMessage(2, 2.0f, FColor::Green, InnerJson->GetStringField("png"));
// This was a test to try to use Download Image Node using the object's StaticMesh and the images url. Didn't work
//this->downloadCardImage(InnerJson->GetStringField("png"), CardMesh);
}
}
}
// Called every frame
void AMTGCard::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
The url passed will always be right and the image that it gets will always be a png. Any suggestions to what I should look at to make this work? I’ve been looking around trying to find anything I can. But not much as been working.