Files
UnrealEngineUWP/Engine/Source/Editor/BlueprintGraph/Private/K2Node_GenericCreateObject.cpp
Maciej Mroz ba111a9270 GenericCreateObject node can be called in Construction Script
UGameplayStatics::SpawnObject checks ClassWithin

#codereview Nick.Whiting, Marc.Audy

[CL 2582478 by Maciej Mroz in Main branch]
2015-06-10 07:03:55 -04:00

94 lines
3.4 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "BlueprintGraphPrivatePCH.h"
#include "KismetCompiler.h"
#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
#include "K2Node_GenericCreateObject.h"
#define LOCTEXT_NAMESPACE "K2Node_GenericCreateObject"
void UK2Node_GenericCreateObject::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
UK2Node_CallFunction* CallCreateNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
CallCreateNode->FunctionReference.SetExternalMember(GET_FUNCTION_NAME_CHECKED(UGameplayStatics, SpawnObject), UGameplayStatics::StaticClass());
CallCreateNode->AllocateDefaultPins();
bool bSucceeded = true;
//connect exe
{
auto SpawnExecPin = GetExecPin();
auto CallExecPin = CallCreateNode->GetExecPin();
bSucceeded &= SpawnExecPin && CallExecPin && CompilerContext.MovePinLinksToIntermediate(*SpawnExecPin, *CallExecPin).CanSafeConnect();
}
//connect class
{
auto SpawnClassPin = GetClassPin();
auto CallClassPin = CallCreateNode->FindPin(TEXT("ObjectClass"));
bSucceeded &= SpawnClassPin && CallClassPin && CompilerContext.MovePinLinksToIntermediate(*SpawnClassPin, *CallClassPin).CanSafeConnect();
}
//connect outer
{
auto SpawnOuterPin = GetOuterPin();
auto CallOuterPin = CallCreateNode->FindPin(TEXT("Outer"));
bSucceeded &= SpawnOuterPin && CallOuterPin && CompilerContext.MovePinLinksToIntermediate(*SpawnOuterPin, *CallOuterPin).CanSafeConnect();
}
UEdGraphPin* CallResultPin = nullptr;
//connect result
{
auto SpawnResultPin = GetResultPin();
CallResultPin = CallCreateNode->GetReturnValuePin();
// cast HACK. It should be safe. The only problem is native code generation.
if (SpawnResultPin && CallResultPin)
{
CallResultPin->PinType = SpawnResultPin->PinType;
}
bSucceeded &= SpawnResultPin && CallResultPin && CompilerContext.MovePinLinksToIntermediate(*SpawnResultPin, *CallResultPin).CanSafeConnect();
}
//assign exposed values and connect then
{
auto LastThen = FKismetCompilerUtilities::GenerateAssignmentNodes(CompilerContext, SourceGraph, CallCreateNode, this, CallResultPin, GetClassToSpawn());
auto SpawnNodeThen = GetThenPin();
bSucceeded &= SpawnNodeThen && LastThen && CompilerContext.MovePinLinksToIntermediate(*SpawnNodeThen, *LastThen).CanSafeConnect();
}
BreakAllNodeLinks();
if (!bSucceeded)
{
CompilerContext.MessageLog.Error(*LOCTEXT("GenericCreateObject_Error", "ICE: GenericCreateObject error @@").ToString(), this);
}
}
void UK2Node_GenericCreateObject::ValidateNodeDuringCompilation(class FCompilerResultsLog& MessageLog) const
{
Super::ValidateNodeDuringCompilation(MessageLog);
}
void UK2Node_GenericCreateObject::EarlyValidation(class FCompilerResultsLog& MessageLog) const
{
Super::EarlyValidation(MessageLog);
auto ClassToSpawn = GetClassToSpawn();
if (!UGameplayStatics::CanSpawnObjectOfClass(ClassToSpawn))
{
MessageLog.Error(*FString::Printf(*LOCTEXT("GenericCreateObject_WrongClass", "Wrong class to spawn '%s' in @@").ToString(), *GetPathNameSafe(ClassToSpawn)), this);
}
auto OuterPin = GetOuterPin();
if (!OuterPin || (!OuterPin->DefaultObject && !OuterPin->LinkedTo.Num()))
{
MessageLog.Error(*LOCTEXT("GenericCreateObject_NoOuter", "Outer object is required in @@").ToString(), this);
}
}
bool UK2Node_GenericCreateObject::IsCompatibleWithGraph(const UEdGraph* TargetGraph) const
{
return UK2Node::IsCompatibleWithGraph(TargetGraph);
}
#undef LOCTEXT_NAMESPACE