void UK2Node_CallArrayFunction::GetArrayPins(TArray< FArrayPropertyPinCombo >& OutArrayPinInfo ) const { OutArrayPinInfo.Empty(); UFunction* TargetFunction = GetTargetFunction(); check(TargetFunction); FString ArrayPointerMetaData = TargetFunction->GetMetaData(FBlueprintMetadata::MD_ArrayParam); TArray<FString> ArrayPinComboNames; ArrayPointerMetaData.ParseIntoArray(ArrayPinComboNames, TEXT(","), true); for(auto Iter = ArrayPinComboNames.CreateConstIterator(); Iter; ++Iter) { TArray<FString> ArrayPinNames; Iter->ParseIntoArray(ArrayPinNames, TEXT("|"), true); FArrayPropertyPinCombo ArrayInfo; ArrayInfo.ArrayPin = FindPin(ArrayPinNames[0]); if(ArrayPinNames.Num() > 1) { ArrayInfo.ArrayPropPin = FindPin(ArrayPinNames[1]); } if(ArrayInfo.ArrayPin) { OutArrayPinInfo.Add(ArrayInfo); } } }
void UK2Node_CallArrayFunction::GetArrayTypeDependentPins(TArray<UEdGraphPin*>& OutPins) const { OutPins.Empty(); UFunction* TargetFunction = GetTargetFunction(); check(TargetFunction); const FString DependentPinMetaData = TargetFunction->GetMetaData(FBlueprintMetadata::MD_ArrayDependentParam); TArray<FString> TypeDependentPinNames; DependentPinMetaData.ParseIntoArray(TypeDependentPinNames, TEXT(","), true); for(TArray<UEdGraphPin*>::TConstIterator it(Pins); it; ++it) { UEdGraphPin* CurrentPin = *it; int32 ItemIndex = 0; if( CurrentPin && TypeDependentPinNames.Find(CurrentPin->PinName, ItemIndex) ) { OutPins.Add(CurrentPin); } } }
void SGameplayTagGraphPin::ParseDefaultValueData() { FString TagString = GraphPinObj->GetDefaultAsString(); UK2Node_CallFunction* CallFuncNode = Cast<UK2Node_CallFunction>(GraphPinObj->GetOuter()); FilterString.Empty(); if (CallFuncNode) { UFunction* ThisFunction = CallFuncNode->GetTargetFunction(); if (ThisFunction) { if (ThisFunction->HasMetaData(TEXT("GameplayTagFilter"))) { FilterString = ThisFunction->GetMetaData(TEXT("GameplayTagFilter")); } } } if (TagString.StartsWith(TEXT("(")) && TagString.EndsWith(TEXT(")"))) { TagString = TagString.LeftChop(1); TagString = TagString.RightChop(1); TagString.Split("=", NULL, &TagString); if (TagString.StartsWith(TEXT("\"")) && TagString.EndsWith(TEXT("\""))) { TagString = TagString.LeftChop(1); TagString = TagString.RightChop(1); } } if (!TagString.IsEmpty()) { FGameplayTag Tag = IGameplayTagsModule::Get().GetGameplayTagsManager().RequestGameplayTag(FName(*TagString)); TagContainer->AddTag(Tag); } }
void UK2Node_LatentAbilityCall::CreatePinsForClass(UClass* InClass) { check(InClass != NULL); const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); const UObject* const ClassDefaultObject = InClass->GetDefaultObject(false); SpawnParmPins.Empty(); // Tasks can hide spawn parameters by doing meta = (HideSpawnParms="PropertyA,PropertyB") // (For example, hide Instigator in situations where instigator is not relevant to your task) TArray<FString> IgnorePropertyList; { UFunction* ProxyFunction = ProxyFactoryClass->FindFunctionByName(ProxyFactoryFunctionName); FString IgnorePropertyListStr = ProxyFunction->GetMetaData(FName(TEXT("HideSpawnParms"))); if (!IgnorePropertyListStr.IsEmpty()) { IgnorePropertyListStr.ParseIntoArray(IgnorePropertyList, TEXT(","), true); } } for (TFieldIterator<UProperty> PropertyIt(InClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt) { UProperty* Property = *PropertyIt; UClass* PropertyClass = CastChecked<UClass>(Property->GetOuter()); const bool bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass()); const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property); const bool bIsSettableExternally = !Property->HasAnyPropertyFlags(CPF_DisableEditOnInstance); if (bIsExposedToSpawn && !Property->HasAnyPropertyFlags(CPF_Parm) && bIsSettableExternally && Property->HasAllPropertyFlags(CPF_BlueprintVisible) && !bIsDelegate && !IgnorePropertyList.Contains(Property->GetName()) && (FindPin(Property->GetName()) == nullptr) ) { UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName()); const bool bPinGood = (Pin != NULL) && K2Schema->ConvertPropertyToPinType(Property, /*out*/ Pin->PinType); SpawnParmPins.Add(Pin); if (ClassDefaultObject && Pin && K2Schema->PinDefaultValueIsEditable(*Pin)) { FString DefaultValueAsString; const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString); check(bDefaultValueSet); K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString); } // Copy tooltip from the property. if (Pin != nullptr) { K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip); } } } }
// Context used to aid debugging displays for nodes FKismetNodeInfoContext::FKismetNodeInfoContext(UEdGraph* SourceGraph) : ActiveObjectBeingDebugged(NULL) { // Only show pending latent actions in PIE/SIE mode SourceBlueprint = FBlueprintEditorUtils::FindBlueprintForGraph(SourceGraph); if (SourceBlueprint != NULL) { ActiveObjectBeingDebugged = SourceBlueprint->GetObjectBeingDebugged(); // Run thru debugged objects to see if any are objects with pending latent actions if (ActiveObjectBeingDebugged != NULL) { UBlueprintGeneratedClass* Class = CastChecked<UBlueprintGeneratedClass>((UObject*)(ActiveObjectBeingDebugged->GetClass())); FBlueprintDebugData const& ClassDebugData = Class->GetDebugData(); TSet<UObject*> LatentContextObjects; TArray<UK2Node_CallFunction*> FunctionNodes; SourceGraph->GetNodesOfClass<UK2Node_CallFunction>(FunctionNodes); // collect all the world context objects for all of the graph's latent nodes for (UK2Node_CallFunction const* FunctionNode : FunctionNodes) { UFunction* Function = FunctionNode->GetTargetFunction(); if ((Function == NULL) || !Function->HasMetaData(FBlueprintMetadata::MD_Latent)) { continue; } UObject* NodeWorldContext = ActiveObjectBeingDebugged; // if the node has a specific "world context" pin, attempt to get the value set for that first if (Function->HasMetaData(FBlueprintMetadata::MD_WorldContext)) { FString const WorldContextPinName = Function->GetMetaData(FBlueprintMetadata::MD_WorldContext); if (UEdGraphPin* ContextPin = FunctionNode->FindPin(WorldContextPinName)) { if (UObjectPropertyBase* ContextProperty = Cast<UObjectPropertyBase>(ClassDebugData.FindClassPropertyForPin(ContextPin))) { UObject* PropertyValue = ContextProperty->GetObjectPropertyValue_InContainer(ActiveObjectBeingDebugged); if (PropertyValue != NULL) { NodeWorldContext = PropertyValue; } } } } LatentContextObjects.Add(NodeWorldContext); } for (UObject* ContextObject : LatentContextObjects) { if (UWorld* World = GEngine->GetWorldFromContextObject(ContextObject, /*bChecked =*/false)) { FLatentActionManager& Manager = World->GetLatentActionManager(); TSet<int32> UUIDSet; Manager.GetActiveUUIDs(ActiveObjectBeingDebugged, /*out*/ UUIDSet); for (TSet<int32>::TConstIterator IterUUID(UUIDSet); IterUUID; ++IterUUID) { const int32 UUID = *IterUUID; if (UEdGraphNode* ParentNode = ClassDebugData.FindNodeFromUUID(UUID)) { TArray<FObjectUUIDPair>& Pairs = NodesWithActiveLatentActions.FindOrAdd(ParentNode); new (Pairs) FObjectUUIDPair(ContextObject, UUID); } } } } } // Covert the watched pin array into a set for (auto WatchedPinIt = SourceBlueprint->PinWatches.CreateConstIterator(); WatchedPinIt; ++WatchedPinIt) { UEdGraphPin* WatchedPin = *WatchedPinIt; UEdGraphNode* OwningNode = Cast<UEdGraphNode>(WatchedPin->GetOuter()); if (!ensure(OwningNode != NULL)) // shouldn't happen, but just in case a dead pin was added to the PinWatches array { continue; } check(OwningNode == WatchedPin->GetOwningNode()); WatchedPinSet.Add(WatchedPin); WatchedNodeSet.Add(OwningNode); } } }