void UK2Node_InputAxisEvent::Serialize(FArchive& Ar) { Super::Serialize(Ar); if(Ar.IsLoading()) { if(Ar.UE4Ver() < VER_UE4_K2NODE_EVENT_MEMBER_REFERENCE && EventSignatureName_DEPRECATED.IsNone() && EventSignatureClass_DEPRECATED == nullptr) { EventReference.SetExternalDelegateMember(TEXT("InputAxisHandlerDynamicSignature__DelegateSignature")); } } }
void Serialize(FArchive& Ar, UObject* Owner, int32 Idx) { const uint8 AdjacencyDataStripFlag = 1; FStripDataFlags StripFlags( Ar, Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::Tessellation) ? AdjacencyDataStripFlag : 0 ); UStaticMesh* StaticMesh = Cast<UStaticMesh>( Owner ); bool bNeedsCPUAccess = true; if( !StripFlags.IsEditorDataStripped() ) { RawTriangles.Serialize( Ar, Owner ); } Ar << Elements; if( !StripFlags.IsDataStrippedForServer() ) { PositionVertexBuffer.Serialize( Ar, bNeedsCPUAccess ); VertexBuffer.Serialize( Ar, bNeedsCPUAccess ); ColorVertexBuffer.Serialize( Ar, bNeedsCPUAccess ); Ar << NumVertices; IndexBuffer.Serialize( Ar, bNeedsCPUAccess ); if (Ar.UE4Ver() >= VER_UE4_SHADOW_ONLY_INDEX_BUFFERS) { ShadowIndexBuffer.Serialize(Ar, bNeedsCPUAccess); } if( !StripFlags.IsEditorDataStripped() ) { Ar << WireframeIndexBuffer; } if ( !StripFlags.IsClassDataStripped( AdjacencyDataStripFlag ) ) { AdjacencyIndexBuffer.Serialize( Ar, bNeedsCPUAccess ); } } if (Ar.IsLoading()) { if (PositionVertexBuffer.GetNumVertices() != NumVertices) { PositionVertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices); } if (VertexBuffer.GetNumVertices() != NumVertices) { VertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices); } if (VertexBuffer.GetNumVertices() != NumVertices) { ColorVertexBuffer.RemoveLegacyShadowVolumeVertices(NumVertices); } } }
void UK2Node_FunctionEntry::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (Ar.IsLoading()) { if (Ar.UE4Ver() < VER_UE4_BLUEPRINT_ENFORCE_CONST_IN_FUNCTION_OVERRIDES) { // Allow legacy implementations to violate const-correctness bEnforceConstCorrectness = false; } } }
void USoundNodeEnveloper::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (Ar.IsLoading()) { if (Ar.UE4Ver() < VER_UE4_MOVE_DISTRIBUITONS_TO_POSTINITPROPS) { if (VolumeInterpCurve_DEPRECATED != NULL && VolumeInterpCurve_DEPRECATED->ConstantCurve.Points.Num() == 0) { VolumeCurve.EditorCurveData.AddKey(0.0f, 1.0f); } if (PitchInterpCurve_DEPRECATED != NULL && PitchInterpCurve_DEPRECATED->ConstantCurve.Points.Num() == 0) { PitchCurve.EditorCurveData.AddKey(0.0f, 1.0f); } } else if (Ar.UE4Ver() < VER_UE4_SOUND_NODE_ENVELOPER_CURVE_CHANGE) { if (VolumeInterpCurve_DEPRECATED) { VolumeCurve.EditorCurveData.Reset(); for (int32 Index = 0; Index < VolumeInterpCurve_DEPRECATED->ConstantCurve.Points.Num(); ++Index) { FInterpCurvePoint<float>& Point = VolumeInterpCurve_DEPRECATED->ConstantCurve.Points[Index]; VolumeCurve.EditorCurveData.AddKey(Point.InVal, Point.OutVal); } } if (PitchInterpCurve_DEPRECATED) { PitchCurve.EditorCurveData.Reset(); for (int32 Index = 0; Index < PitchInterpCurve_DEPRECATED->ConstantCurve.Points.Num(); ++Index) { FInterpCurvePoint<float>& Point = PitchInterpCurve_DEPRECATED->ConstantCurve.Points[Index]; PitchCurve.EditorCurveData.AddKey(Point.InVal, Point.OutVal); } } } } }
void AWorldSettings::Serialize( FArchive& Ar ) { Super::Serialize(Ar); if (Ar.UE4Ver() < VER_UE4_ADD_OVERRIDE_GRAVITY_FLAG) { //before we had override flag we would use GlobalGravityZ != 0 if(GlobalGravityZ != 0.0f) { bGlobalGravitySet = true; } } }
void USoundNodeModulatorContinuous::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (Ar.IsLoading()) { if (Ar.UE4Ver() < VER_UE4_MOVE_DISTRIBUITONS_TO_POSTINITPROPS) { FDistributionHelpers::RestoreDefaultUniform(PitchModulation_DEPRECATED.Distribution, TEXT("DistributionPitch"), 0.95f, 1.05f); FDistributionHelpers::RestoreDefaultUniform(VolumeModulation_DEPRECATED.Distribution, TEXT("DistributionVolume"), 0.95f, 1.05f); } if (Ar.UE4Ver() < VER_UE4_MODULATOR_CONTINUOUS_NO_DISTRIBUTION) { // If it is a float sound parameter we convert, otherwise it will become a default 1.0 multiplier that has no effect UDEPRECATED_DistributionFloatSoundParameter* Distribution = Cast<UDEPRECATED_DistributionFloatSoundParameter>(PitchModulation_DEPRECATED.Distribution); if (Distribution) { PitchModulationParams.ParameterName = Distribution->ParameterName; PitchModulationParams.Default = Distribution->Constant; PitchModulationParams.MinInput = Distribution->MinInput; PitchModulationParams.MaxInput = Distribution->MaxInput; PitchModulationParams.MinOutput = Distribution->MinOutput; PitchModulationParams.MaxOutput = Distribution->MaxOutput; PitchModulationParams.ParamMode = (ModulationParamMode)(int32)Distribution->ParamMode; } Distribution = Cast<UDEPRECATED_DistributionFloatSoundParameter>(VolumeModulation_DEPRECATED.Distribution); if (Distribution) { VolumeModulationParams.ParameterName = Distribution->ParameterName; VolumeModulationParams.Default = Distribution->Constant; VolumeModulationParams.MinInput = Distribution->MinInput; VolumeModulationParams.MaxInput = Distribution->MaxInput; VolumeModulationParams.MinOutput = Distribution->MinOutput; VolumeModulationParams.MaxOutput = Distribution->MaxOutput; VolumeModulationParams.ParamMode = (ModulationParamMode)(int32)Distribution->ParamMode; } } } }
void FLinker::Serialize( FArchive& Ar ) { if( Ar.IsCountingMemory() ) { // Can't use CountBytes as ExportMap is array of structs of arrays. Ar << ImportMap; Ar << ExportMap; Ar << DependsMap; if (Ar.IsSaving() || Ar.UE4Ver() >= VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP) { Ar << StringAssetReferencesMap; } } if (Ar.IsSaving() || Ar.UE4Ver() >= VER_UE4_SERIALIZE_TEXT_IN_PACKAGES) { Ar << GatherableTextDataMap; } // Prevent garbage collecting of linker's names and package. Ar << NameMap << LinkerRoot; { for (auto& E : ExportMap) { Ar << E.ObjectName; } } { for (auto& I : ImportMap) { UObject* LegacyLinkerObject = nullptr; Ar << LegacyLinkerObject; Ar << I.ClassPackage << I.ClassName; } } }
void FRawCurveTracks::Serialize(FArchive& Ar) { // @TODO: If we're about to serialize vector curve, add here if(Ar.UE4Ver() >= VER_UE4_SKELETON_ADD_SMARTNAMES) { for(FFloatCurve& Curve : FloatCurves) { Curve.Serialize(Ar); } } #if WITH_EDITORONLY_DATA if( !Ar.IsCooking() ) { if( Ar.UE4Ver() >= VER_UE4_ANIMATION_ADD_TRACKCURVES ) { for( FTransformCurve& Curve : TransformCurves ) { Curve.Serialize( Ar ); } } } #endif // WITH_EDITORONLY_DATA }
void FGraphReference::PostSerialize(const FArchive& Ar) { #if WITH_EDITORONLY_DATA if (Ar.UE4Ver() >= VER_UE4_K2NODE_REFERENCEGUIDS) { // Because the macro instance could have been saved with a GUID that was allocated // but the macro graph never actually saved with that value we are forced to make // sure to refresh the GUID and make sure it is up to date if (MacroGraph) { GraphGuid = MacroGraph->GraphGuid; } } #endif }
void FConstraintInstance::PostSerialize(const FArchive& Ar) { if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_FIXUP_STIFFNESS_AND_DAMPING_SCALE) { LinearLimitStiffness /= CVarConstraintStiffnessScale.GetValueOnGameThread(); SwingLimitStiffness /= CVarConstraintStiffnessScale.GetValueOnGameThread(); TwistLimitStiffness /= CVarConstraintStiffnessScale.GetValueOnGameThread(); LinearLimitDamping /= CVarConstraintDampingScale.GetValueOnGameThread(); SwingLimitDamping /= CVarConstraintDampingScale.GetValueOnGameThread(); TwistLimitDamping /= CVarConstraintDampingScale.GetValueOnGameThread(); } if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_FIXUP_MOTOR_UNITS) { AngularVelocityTarget *= 1.f / (2.f * PI); //we want to use revolutions per second - old system was using radians directly } if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_CONSTRAINT_INSTANCE_MOTOR_FLAGS) { bLinearXVelocityDrive = LinearVelocityTarget.X != 0.f; bLinearYVelocityDrive = LinearVelocityTarget.Y != 0.f; bLinearZVelocityDrive = LinearVelocityTarget.Z != 0.f; } }
void FTextHistory_AsCurrency::Serialize( FArchive& Ar ) { if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::AsCurrency; Ar << HistoryType; } if (Ar.UE4Ver() >= VER_UE4_ADDED_CURRENCY_CODE_TO_FTEXT) { Ar << CurrencyCode; } FTextHistory_FormatNumber::Serialize(Ar); }
bool FGameplayTagContainer::Serialize(FArchive& Ar) { const bool bOldTagVer = Ar.UE4Ver() < VER_UE4_GAMEPLAY_TAG_CONTAINER_TAG_TYPE_CHANGE; if (bOldTagVer) { Ar << Tags_DEPRECATED; } else { Ar << GameplayTags; } if (Ar.IsLoading()) { UGameplayTagsManager& TagManager = IGameplayTagsModule::GetGameplayTagsManager(); // If loading old version, add old tags to the new gameplay tags array so they can be saved out with the new version // This needs to happen // NOTE: DeprecatedTagNamesNotFoundInTagMap should be removed along with the bOldTagVer when we remove backwards // compatibility, and the signature of RedirectTagsForContainer (below) should be changed appropriately as well. TSet<FName> DeprecatedTagNamesNotFoundInTagMap; if (bOldTagVer) { for (auto It = Tags_DEPRECATED.CreateConstIterator(); It; ++It) { const bool bErrorIfNotFound = false; FGameplayTag Tag = TagManager.RequestGameplayTag(*It, bErrorIfNotFound); if (Tag.IsValid()) { TagManager.AddLeafTagToContainer(*this, Tag); } else { // For tags not found in the current table, add them to a list to be checked when handling // redirection (below). DeprecatedTagNamesNotFoundInTagMap.Add(*It); } } } // Rename any tags that may have changed by the ini file. Redirects can happen regardless of version. // Regardless of version, want loading to have a chance to handle redirects TagManager.RedirectTagsForContainer(*this, DeprecatedTagNamesNotFoundInTagMap); } return true; }
void ULightComponent::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (Ar.UE4Ver() >= VER_UE4_STATIC_SHADOW_DEPTH_MAPS) { if (Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::HighQualityLightmaps)) { // Toss lighting data only needed for high quality lightmaps FStaticShadowDepthMap EmptyDepthMap; Ar << EmptyDepthMap; } else { Ar << StaticShadowDepthMap; } } }
void FKAggregateGeom::Serialize( const FArchive& Ar ) { if ( Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_REFACTOR_PHYSICS_TRANSFORMS ) { for ( auto SphereElemIt = SphereElems.CreateIterator(); SphereElemIt; ++SphereElemIt ) { SphereElemIt->Serialize( Ar ); } for ( auto BoxElemIt = BoxElems.CreateIterator(); BoxElemIt; ++BoxElemIt ) { BoxElemIt->Serialize( Ar ); } for ( auto SphylElemIt = SphylElems.CreateIterator(); SphylElemIt; ++SphylElemIt ) { SphylElemIt->Serialize( Ar ); } } }
bool FRichCurveKey::Serialize(FArchive& Ar) { if (Ar.UE4Ver() < VER_UE4_SERIALIZE_RICH_CURVE_KEY) { return false; } // Serialization is handled manually to avoid the extra size overhead of UProperty tagging. // Otherwise with many keys in a rich curve the size can become quite large. Ar << InterpMode; Ar << TangentMode; Ar << TangentWeightMode; Ar << Time; Ar << Value; Ar << ArriveTangent; Ar << ArriveTangentWeight; Ar << LeaveTangent; Ar << LeaveTangentWeight; return true; }
bool FMovieSceneSpawnable::Serialize(FArchive& Ar) { Ar << Guid; Ar << Name; #if WITH_EDITOR if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_EDITORONLY_BLUEPRINTS) { UBlueprint* ObsoleteBlueprint = NULL; Ar << ObsoleteBlueprint; if(ObsoleteBlueprint) { GeneratedClass = ObsoleteBlueprint->GeneratedClass; } } else #endif //WITH_EDITOR { Ar << GeneratedClass; } return true; }
void FRawStaticIndexBuffer::Serialize(FArchive& Ar, bool bNeedsCPUAccess) { IndexStorage.SetAllowCPUAccess(bNeedsCPUAccess); if (Ar.UE4Ver() < VER_UE4_SUPPORT_32BIT_STATIC_MESH_INDICES) { TResourceArray<uint16,INDEXBUFFER_ALIGNMENT> LegacyIndices; b32Bit = false; LegacyIndices.BulkSerialize(Ar); int32 NumIndices = LegacyIndices.Num(); int32 IndexStride = sizeof(uint16); IndexStorage.Empty(NumIndices * IndexStride); IndexStorage.AddUninitialized(NumIndices * IndexStride); FMemory::Memcpy(IndexStorage.GetData(),LegacyIndices.GetData(),IndexStorage.Num()); } else { Ar << b32Bit; IndexStorage.BulkSerialize(Ar); } }
void UAssetImportData::Serialize(FArchive& Ar) { if (Ar.UE4Ver() >= VER_UE4_ASSET_IMPORT_DATA_AS_JSON) { FString Json; if (Ar.IsLoading()) { Ar << Json; TOptional<FAssetImportInfo> Copy = FromJson(MoveTemp(Json)); if (Copy.IsSet()) { CopyFrom(Copy.GetValue()); } } else if (Ar.IsSaving()) { Json = ToJson(); Ar << Json; } } Super::Serialize(Ar); }
void FSmartNameMapping::Serialize(FArchive& Ar) { if(Ar.UE4Ver() >= VER_UE4_SKELETON_ADD_SMARTNAMES) { Ar << NextUid; Ar << UidMap; if(Ar.ArIsLoading) { // Sort the Uid Map UidMap.KeySort([](const UID& A, const UID& B) { return A < B; }); // Build freelist as necessary UID ExpectedID = 0; UID Last = 0; for(TPair<UID, FName>& Pair : UidMap) { UID CurrentUid = Pair.Key; while(CurrentUid != ExpectedID) { FreeList.Add(ExpectedID++); } Last = CurrentUid; ++ExpectedID; } // In the case of multipled queued deletions previously, // fix up the next UID to match the last used key we found. NextUid = Last + 1; } } }
void USoundWave::Serialize( FArchive& Ar ) { DECLARE_SCOPE_CYCLE_COUNTER( TEXT("USoundWave::Serialize"), STAT_SoundWave_Serialize, STATGROUP_LoadTime ); Super::Serialize( Ar ); bool bCooked = Ar.IsCooking(); Ar << bCooked; if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading()) { UE_LOG(LogAudio, Fatal, TEXT("This platform requires cooked packages, and audio data was not cooked into %s."), *GetFullName()); } Ar.UsingCustomVersion(FFrameworkObjectVersion::GUID); if (Ar.IsLoading() && (Ar.UE4Ver() >= VER_UE4_SOUND_COMPRESSION_TYPE_ADDED) && (Ar.CustomVer(FFrameworkObjectVersion::GUID) < FFrameworkObjectVersion::RemoveSoundWaveCompressionName)) { FName DummyCompressionName; Ar << DummyCompressionName; } bool bSupportsStreaming = false; if (Ar.IsLoading() && FPlatformProperties::SupportsAudioStreaming()) { bSupportsStreaming = true; } else if (Ar.IsCooking() && Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming)) { bSupportsStreaming = true; } if (bCooked) { // Only want to cook/load full data if we don't support streaming if (!IsStreaming() || !bSupportsStreaming) { if (Ar.IsCooking()) { #if WITH_ENGINE TArray<FName> ActualFormatsToSave; if (!Ar.CookingTarget()->IsServerOnly()) { // for now we only support one format per wav FName Format = Ar.CookingTarget()->GetWaveFormat(this); GetCompressedData(Format); // Get the data from the DDC or build it ActualFormatsToSave.Add(Format); } CompressedFormatData.Serialize(Ar, this, &ActualFormatsToSave); #endif } else { CompressedFormatData.Serialize(Ar, this); } } } else { // only save the raw data for non-cooked packages RawData.Serialize( Ar, this ); } Ar << CompressedDataGuid; if (IsStreaming()) { if (bCooked) { // only cook/load streaming data if it's supported if (bSupportsStreaming) { SerializeCookedPlatformData(Ar); } } #if WITH_EDITORONLY_DATA if (Ar.IsLoading() && !Ar.IsTransacting() && !bCooked && !GetOutermost()->HasAnyPackageFlags(PKG_ReloadingForCooker)) { BeginCachePlatformData(); } #endif // #if WITH_EDITORONLY_DATA } }
void USoundWave::Serialize( FArchive& Ar ) { Super::Serialize( Ar ); bool bCooked = Ar.IsCooking(); Ar << bCooked; if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading()) { UE_LOG(LogAudio, Fatal, TEXT("This platform requires cooked packages, and audio data was not cooked into %s."), *GetFullName()); } if (Ar.IsCooking()) { CompressionName = Ar.CookingTarget()->GetWaveFormat(this); } if (Ar.UE4Ver() >= VER_UE4_SOUND_COMPRESSION_TYPE_ADDED) { Ar << CompressionName; } if (bCooked) { // Only want to cook/load full data if we don't support streaming if (!IsStreaming() || (Ar.IsLoading() && !FPlatformProperties::SupportsAudioStreaming()) || (Ar.IsCooking() && !Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming))) { if (Ar.IsCooking()) { #if WITH_ENGINE TArray<FName> ActualFormatsToSave; if (!Ar.CookingTarget()->IsServerOnly()) { // for now we only support one format per wav FName Format = Ar.CookingTarget()->GetWaveFormat(this); GetCompressedData(Format); // Get the data from the DDC or build it ActualFormatsToSave.Add(Format); } CompressedFormatData.Serialize(Ar, this, &ActualFormatsToSave); #endif } else { CompressedFormatData.Serialize(Ar, this); } } } else { // only save the raw data for non-cooked packages RawData.Serialize( Ar, this ); } Ar << CompressedDataGuid; if (IsStreaming()) { if (bCooked) { // only cook/load streaming data if it's supported if ((Ar.IsLoading() && FPlatformProperties::SupportsAudioStreaming()) || (Ar.IsCooking() && Ar.CookingTarget()->SupportsFeature(ETargetPlatformFeatures::AudioStreaming))) { SerializeCookedPlatformData(Ar); } } #if WITH_EDITORONLY_DATA if (Ar.IsLoading() && !Ar.IsTransacting() && !bCooked && !(GetOutermost()->PackageFlags & PKG_ReloadingForCooker)) { BeginCachePlatformData(); } #endif // #if WITH_EDITORONLY_DATA } }
void UReflectionCaptureComponent::Serialize(FArchive& Ar) { Super::Serialize(Ar); bool bCooked = false; if (Ar.UE4Ver() >= VER_UE4_REFLECTION_CAPTURE_COOKING) { bCooked = Ar.IsCooking(); // Save a bool indicating whether this is cooked data // This is needed when loading cooked data, to know to serialize differently Ar << bCooked; } if (FPlatformProperties::RequiresCookedData() && !bCooked && Ar.IsLoading()) { UE_LOG(LogMaterial, Fatal, TEXT("This platform requires cooked packages, and this reflection capture does not contain cooked data %s."), *GetName()); } if (bCooked) { static FName FullHDR(TEXT("FullHDR")); static FName EncodedHDR(TEXT("EncodedHDR")); // Saving for cooking path if (Ar.IsCooking()) { // Get all the reflection capture formats that the target platform wants TArray<FName> Formats; Ar.CookingTarget()->GetReflectionCaptureFormats(Formats); int32 NumFormats = Formats.Num(); Ar << NumFormats; for (int32 FormatIndex = 0; FormatIndex < NumFormats; FormatIndex++) { FName CurrentFormat = Formats[FormatIndex]; Ar << CurrentFormat; if (CurrentFormat == FullHDR) { // FullHDRDerivedData would have been set in PostLoad during cooking if it exists in the DDC // Can't generate it if missing, since that requires rendering the scene bool bValid = FullHDRDerivedData != NULL; Ar << bValid; if (bValid) { Ar << FullHDRDerivedData->CompressedCapturedData; } } else { check(CurrentFormat == EncodedHDR); TRefCountPtr<FReflectionCaptureEncodedHDRDerivedData> EncodedHDRData; // FullHDRDerivedData would have been set in PostLoad during cooking if it exists in the DDC // Generate temporary encoded HDR data for saving if (FullHDRDerivedData != NULL) { EncodedHDRData = FReflectionCaptureEncodedHDRDerivedData::GenerateEncodedHDRData(*FullHDRDerivedData, StateId, Brightness); } bool bValid = EncodedHDRData != NULL; Ar << bValid; if (bValid) { Ar << EncodedHDRData->CapturedData; } else if (!IsTemplate()) { // Temporary warning until the cooker can do scene captures itself in the case of missing DDC UE_LOG(LogMaterial, Warning, TEXT("Reflection capture requires encoded HDR data but none was found in the DDC! This reflection will be black. Fix by loading the map in the editor once. %s."), *GetFullName()); } } } } else { // Loading cooked data path int32 NumFormats = 0; Ar << NumFormats; for (int32 FormatIndex = 0; FormatIndex < NumFormats; FormatIndex++) { FName CurrentFormat; Ar << CurrentFormat; bool bValid = false; Ar << bValid; if (bValid) { if (CurrentFormat == FullHDR) { FullHDRDerivedData = new FReflectionCaptureFullHDRDerivedData(); Ar << FullHDRDerivedData->CompressedCapturedData; } else { check(CurrentFormat == EncodedHDR); EncodedHDRDerivedData = new FReflectionCaptureEncodedHDRDerivedData(); Ar << EncodedHDRDerivedData->CapturedData; } } else if (CurrentFormat == EncodedHDR) { // Temporary warning until the cooker can do scene captures itself in the case of missing DDC UE_LOG(LogMaterial, Error, TEXT("Reflection capture was loaded without any valid capture data and will be black. This can happen if the DDC was not up to date during cooking. Load the map in the editor once before cooking to fix. %s."), *GetFullName()); } } } } }
void UArrayProperty::SerializeItem( FArchive& Ar, void* Value, void const* Defaults ) const { checkSlow(Inner); // Ensure that the Inner itself has been loaded before calling SerializeItem() on it Ar.Preload(Inner); FScriptArrayHelper ArrayHelper(this, Value); int32 n = ArrayHelper.Num(); Ar << n; if( Ar.IsLoading() ) { // If using a custom property list, don't empty the array on load. Not all indices may have been serialized, so we need to preserve existing values at those slots. if (Ar.ArUseCustomPropertyList) { const int32 OldNum = ArrayHelper.Num(); if (n > OldNum) { ArrayHelper.AddValues(n - OldNum); } else if (n < OldNum) { ArrayHelper.RemoveValues(n, OldNum - n); } } else { ArrayHelper.EmptyAndAddValues(n); } } ArrayHelper.CountBytes( Ar ); // Serialize a PropertyTag for the inner property of this array, allows us to validate the inner struct to see if it has changed FPropertyTag InnerTag(Ar, Inner, 0, (uint8*)Value, (uint8*)Defaults); if (Ar.UE4Ver() >= VER_UE4_INNER_ARRAY_TAG_INFO && InnerTag.Type == NAME_StructProperty) { if (Ar.IsSaving()) { Ar << InnerTag; } else if (Ar.IsLoading()) { Ar << InnerTag; auto CanSerializeFromStructWithDifferentName = [](const FArchive& InAr, const FPropertyTag& PropertyTag, const UStructProperty* StructProperty) { return PropertyTag.StructGuid.IsValid() && StructProperty && StructProperty->Struct && (PropertyTag.StructGuid == StructProperty->Struct->GetCustomGuid()); }; // Check if the Inner property can successfully serialize, the type may have changed UStructProperty* StructProperty = CastChecked<UStructProperty>(Inner); // if check redirector to make sure if the name has changed FName* NewName = FLinkerLoad::StructNameRedirects.Find(InnerTag.StructName); FName StructName = CastChecked<UStructProperty>(StructProperty)->Struct->GetFName(); if (NewName != nullptr && *NewName == StructName) { InnerTag.StructName = *NewName; } if (InnerTag.StructName != StructProperty->Struct->GetFName() && !CanSerializeFromStructWithDifferentName(Ar, InnerTag, StructProperty)) { UE_LOG(LogClass, Warning, TEXT("Property %s of %s has a struct type mismatch (tag %s != prop %s) in package: %s. If that struct got renamed, add an entry to ActiveStructRedirects."), *InnerTag.Name.ToString(), *GetName(), *InnerTag.StructName.ToString(), *CastChecked<UStructProperty>(Inner)->Struct->GetName(), *Ar.GetArchiveName()); #if WITH_EDITOR // Ensure the structure is initialized for (int32 i = 0; i < n; i++) { StructProperty->Struct->InitializeDefaultValue(ArrayHelper.GetRawPtr(i)); } #endif // WITH_EDITOR // Skip the property const int64 StartOfProperty = Ar.Tell(); const int64 RemainingSize = InnerTag.Size - (Ar.Tell() - StartOfProperty); uint8 B; for (int64 i = 0; i < RemainingSize; i++) { Ar << B; } return; } } } // need to know how much data this call to SerializeItem consumes, so mark where we are int32 DataOffset = Ar.Tell(); // If we're using a custom property list, first serialize any explicit indices int32 i = 0; bool bSerializeRemainingItems = true; bool bUsingCustomPropertyList = Ar.ArUseCustomPropertyList; if (bUsingCustomPropertyList && Ar.ArCustomPropertyList != nullptr) { // Initially we only serialize indices that are explicitly specified (in order) bSerializeRemainingItems = false; const FCustomPropertyListNode* CustomPropertyList = Ar.ArCustomPropertyList; const FCustomPropertyListNode* PropertyNode = CustomPropertyList; while (PropertyNode && i < n && !bSerializeRemainingItems) { if (PropertyNode->Property != Inner) { // A null property value signals that we should serialize the remaining array values in full starting at this index if (PropertyNode->Property == nullptr) { i = PropertyNode->ArrayIndex; } bSerializeRemainingItems = true; } else { // Set a temporary node to represent the item FCustomPropertyListNode ItemNode = *PropertyNode; ItemNode.ArrayIndex = 0; ItemNode.PropertyListNext = nullptr; Ar.ArCustomPropertyList = &ItemNode; // Serialize the item at this array index i = PropertyNode->ArrayIndex; Inner->SerializeItem(Ar, ArrayHelper.GetRawPtr(i)); PropertyNode = PropertyNode->PropertyListNext; // Restore the current property list Ar.ArCustomPropertyList = CustomPropertyList; } } } if (bSerializeRemainingItems) { // Temporarily suspend the custom property list (as we need these items to be serialized in full) Ar.ArUseCustomPropertyList = false; // Serialize each item until we get to the end of the array while (i < n) { Inner->SerializeItem(Ar, ArrayHelper.GetRawPtr(i++)); } // Restore use of the custom property list (if it was previously enabled) Ar.ArUseCustomPropertyList = bUsingCustomPropertyList; } if (Ar.UE4Ver() >= VER_UE4_INNER_ARRAY_TAG_INFO && Ar.IsSaving() && InnerTag.Type == NAME_StructProperty) { // set the tag's size InnerTag.Size = Ar.Tell() - DataOffset; if (InnerTag.Size > 0) { // mark our current location DataOffset = Ar.Tell(); // go back and re-serialize the size now that we know it Ar.Seek(InnerTag.SizeOffset); Ar << InnerTag.Size; // return to the current location Ar.Seek(DataOffset); } } }
void UModel::Serialize( FArchive& Ar ) { Super::Serialize( Ar ); const int32 StripVertexBufferFlag = 1; FStripDataFlags StripFlags( Ar, GetOuter() && GetOuter()->IsA(ABrush::StaticClass()) ? StripVertexBufferFlag : FStripDataFlags::None ); Ar << Bounds; if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_BSP_UNDO_FIX ) { TTransArray<FVector> OldVectors(this); TTransArray<FVector> OldPoints(this); TTransArray<FBspNode> OldNodes(this); OldVectors.BulkSerialize(Ar); OldPoints.BulkSerialize(Ar); OldNodes.BulkSerialize(Ar); Vectors = OldVectors; Points = OldPoints; Nodes = OldNodes; } else { Vectors.BulkSerialize(Ar); Points.BulkSerialize(Ar); Nodes.BulkSerialize(Ar); } if( Ar.IsLoading() ) { for( int32 NodeIndex=0; NodeIndex<Nodes.Num(); NodeIndex++ ) { Nodes[NodeIndex].NodeFlags &= ~(NF_IsNew|NF_IsFront|NF_IsBack); } } if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_BSP_UNDO_FIX ) { TTransArray<FBspSurf> OldSurfs(this); TTransArray<FVert> OldVerts(this); Ar << OldSurfs; OldVerts.BulkSerialize(Ar); Surfs = OldSurfs; Verts = OldVerts; } else { Ar << Surfs; Verts.BulkSerialize(Ar); } if( Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_REMOVE_ZONES_FROM_MODEL) { int32 NumZones; Ar << NumSharedSides << NumZones; FZoneProperties DummyZones[FBspNode::MAX_ZONES]; for( int32 i=0; i<NumZones; i++ ) { Ar << DummyZones[i]; } } else { Ar << NumSharedSides; } #if WITH_EDITOR bool bHasEditorOnlyData = !Ar.IsFilterEditorOnly(); if ( Ar.UE4Ver() < VER_UE4_REMOVE_UNUSED_UPOLYS_FROM_UMODEL ) { bHasEditorOnlyData = true; } // if we are cooking then don't save this stuff out if ( bHasEditorOnlyData ) { Ar << Polys; LeafHulls.BulkSerialize( Ar ); Leaves.BulkSerialize( Ar ); } #else bool bHasEditorOnlyData = !Ar.IsFilterEditorOnly(); if ( Ar.UE4Ver() < VER_UE4_REMOVE_UNUSED_UPOLYS_FROM_UMODEL ) { bHasEditorOnlyData = true; } if((Ar.IsLoading() || Ar.IsSaving()) && bHasEditorOnlyData) { UPolys* DummyPolys = NULL; Ar << DummyPolys; TArray<int32> DummyLeafHulls; DummyLeafHulls.BulkSerialize( Ar ); TArray<FLeaf> DummyLeaves; DummyLeaves.BulkSerialize( Ar ); } #endif Ar << RootOutside << Linked; if(Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_REMOVE_ZONES_FROM_MODEL) { TArray<int32> DummyPortalNodes; DummyPortalNodes.BulkSerialize( Ar ); } Ar << NumUniqueVertices; // load/save vertex buffer if( StripFlags.IsEditorDataStripped() == false || StripFlags.IsClassDataStripped( StripVertexBufferFlag ) == false ) { Ar << VertexBuffer; } #if WITH_EDITOR if(GIsEditor) { CalculateUniqueVertCount(); } #endif // WITH_EDITOR // serialize the lighting guid if it's there Ar << LightingGuid; Ar << LightmassSettings; }
void USpineSkeletonDataAsset::Serialize (FArchive& Ar) { Super::Serialize(Ar); if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData) importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData")); }
void USimpleConstructionScript::Serialize(FArchive& Ar) { Super::Serialize(Ar); if(Ar.IsLoading()) { if(Ar.UE4Ver() < VER_UE4_REMOVE_NATIVE_COMPONENTS_FROM_BLUEPRINT_SCS) { // If we previously had a root node, we need to move it into the new RootNodes array. This is done in Serialize() in order to support SCS preloading (which relies on a valid RootNodes array). if(RootNode_DEPRECATED != NULL) { // Ensure it's been loaded so that its properties are valid if(RootNode_DEPRECATED->HasAnyFlags(RF_NeedLoad)) { RootNode_DEPRECATED->GetLinker()->Preload(RootNode_DEPRECATED); } // If the root node was not native if(!RootNode_DEPRECATED->bIsNative_DEPRECATED) { // Add the node to the root set RootNodes.Add(RootNode_DEPRECATED); } else { // For each child of the previously-native root node for (USCS_Node* Node : RootNode_DEPRECATED->GetChildNodes()) { if(Node != NULL) { // Ensure it's been loaded (may not have been yet if we're preloading the SCS) if(Node->HasAnyFlags(RF_NeedLoad)) { Node->GetLinker()->Preload(Node); } // We only care about non-native child nodes (non-native nodes could only be attached to the root node in the previous version, so we don't need to examine native child nodes) if(!Node->bIsNative_DEPRECATED) { // Add the node to the root set RootNodes.Add(Node); // Set the previously-native root node as its parent component Node->bIsParentComponentNative = true; Node->ParentComponentOrVariableName = RootNode_DEPRECATED->NativeComponentName_DEPRECATED; } } } } // Clear the deprecated reference RootNode_DEPRECATED = NULL; } // Add any user-defined actor components to the root set for (USCS_Node* Node : ActorComponentNodes_DEPRECATED) { if(Node != NULL) { // Ensure it's been loaded (may not have been yet if we're preloading the SCS) if(Node->HasAnyFlags(RF_NeedLoad)) { Node->GetLinker()->Preload(Node); } if(!Node->bIsNative_DEPRECATED) { RootNodes.Add(Node); } } } // Clear the deprecated ActorComponent list ActorComponentNodes_DEPRECATED.Empty(); } } }
void USkeleton::Serialize( FArchive& Ar ) { Super::Serialize(Ar); if( Ar.UE4Ver() >= VER_UE4_REFERENCE_SKELETON_REFACTOR ) { Ar << ReferenceSkeleton; } if (Ar.UE4Ver() >= VER_UE4_FIX_ANIMATIONBASEPOSE_SERIALIZATION) { // Load Animation RetargetSources if (Ar.IsLoading()) { int32 NumOfRetargetSources; Ar << NumOfRetargetSources; FName RetargetSourceName; FReferencePose RetargetSource; for (int32 Index=0; Index<NumOfRetargetSources; ++Index) { Ar << RetargetSourceName; Ar << RetargetSource; AnimRetargetSources.Add(RetargetSourceName, RetargetSource); } } else { int32 NumOfRetargetSources = AnimRetargetSources.Num(); Ar << NumOfRetargetSources; for (auto Iter = AnimRetargetSources.CreateIterator(); Iter; ++Iter) { Ar << Iter.Key(); Ar << Iter.Value(); } } } else { // this is broken, but we have to keep it to not corrupt content. for (auto Iter = AnimRetargetSources.CreateIterator(); Iter; ++Iter) { Ar << Iter.Key(); Ar << Iter.Value(); } } if (Ar.UE4Ver() < VER_UE4_SKELETON_GUID_SERIALIZATION) { RegenerateGuid(); } else { Ar << Guid; } // If we should be using smartnames, serialize the mappings if(Ar.UE4Ver() >= VER_UE4_SKELETON_ADD_SMARTNAMES) { SmartNames.Serialize(Ar); } #if WITH_EDITORONLY_DATA if (Ar.UE4Ver() < VER_UE4_SKELETON_ASSET_PROPERTY_TYPE_CHANGE) { PreviewAttachedAssetContainer.SaveAttachedObjectsFromDeprecatedProperties(); } #endif }
void FReverbSettings::PostSerialize(const FArchive& Ar) { if( Ar.UE4Ver() < VER_UE4_REVERB_EFFECT_ASSET_TYPE ) { FString ReverbAssetName; switch(ReverbType_DEPRECATED) { case REVERB_Default: // No replacement asset for default reverb type return; case REVERB_Bathroom: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Bathroom.Bathroom"); break; case REVERB_StoneRoom: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/StoneRoom.StoneRoom"); break; case REVERB_Auditorium: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Auditorium.Auditorium"); break; case REVERB_ConcertHall: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/ConcertHall.ConcertHall"); break; case REVERB_Cave: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Cave.Cave"); break; case REVERB_Hallway: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Hallway.Hallway"); break; case REVERB_StoneCorridor: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/StoneCorridor.StoneCorridor"); break; case REVERB_Alley: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Alley.Alley"); break; case REVERB_Forest: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Forest.Forest"); break; case REVERB_City: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/City.City"); break; case REVERB_Mountains: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Mountains.Mountains"); break; case REVERB_Quarry: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Quarry.Quarry"); break; case REVERB_Plain: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Plain.Plain"); break; case REVERB_ParkingLot: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/ParkingLot.ParkingLot"); break; case REVERB_SewerPipe: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/SewerPipe.SewerPipe"); break; case REVERB_Underwater: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Underwater.Underwater"); break; case REVERB_SmallRoom: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/SmallRoom.SmallRoom"); break; case REVERB_MediumRoom: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/MediumRoom.MediumRoom"); break; case REVERB_LargeRoom: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/LargeRoom.LargeRoom"); break; case REVERB_MediumHall: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/MediumHall.MediumHall"); break; case REVERB_LargeHall: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/LargeHall.LargeHall"); break; case REVERB_Plate: ReverbAssetName = TEXT("/Engine/EngineSounds/ReverbSettings/Plate.Plate"); break; default: // This should cover every type of reverb preset checkNoEntry(); break; } ReverbEffect = LoadObject<UReverbEffect>(NULL, *ReverbAssetName); check( ReverbEffect ); } }
void UModel::Serialize( FArchive& Ar ) { Super::Serialize( Ar ); const int32 StripVertexBufferFlag = 1; FStripDataFlags StripFlags( Ar, GetOuter() && GetOuter()->IsA(ABrush::StaticClass()) ? StripVertexBufferFlag : FStripDataFlags::None ); Ar << Bounds; Vectors.BulkSerialize( Ar ); Points.BulkSerialize( Ar ); Nodes.BulkSerialize( Ar ); if( Ar.IsLoading() ) { for( int32 NodeIndex=0; NodeIndex<Nodes.Num(); NodeIndex++ ) { Nodes[NodeIndex].NodeFlags &= ~(NF_IsNew|NF_IsFront|NF_IsBack); } } Ar << Surfs; Verts.BulkSerialize( Ar ); if( Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_REMOVE_ZONES_FROM_MODEL) { int32 NumZones; Ar << NumSharedSides << NumZones; FZoneProperties DummyZones[FBspNode::MAX_ZONES]; for( int32 i=0; i<NumZones; i++ ) { Ar << DummyZones[i]; } } else { Ar << NumSharedSides; } #if WITH_EDITOR Ar << Polys; LeafHulls.BulkSerialize( Ar ); Leaves.BulkSerialize( Ar ); #else if(Ar.IsLoading()) { UPolys* DummyPolys; Ar << DummyPolys; TArray<int32> DummyLeafHulls; DummyLeafHulls.BulkSerialize( Ar ); TArray<FLeaf> DummyLeaves; DummyLeaves.BulkSerialize( Ar ); } #endif Ar << RootOutside << Linked; if(Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_REMOVE_ZONES_FROM_MODEL) { TArray<int32> DummyPortalNodes; DummyPortalNodes.BulkSerialize( Ar ); } Ar << NumUniqueVertices; // load/save vertex buffer if( StripFlags.IsEditorDataStripped() == false || StripFlags.IsClassDataStripped( StripVertexBufferFlag ) == false ) { Ar << VertexBuffer; } #if WITH_EDITOR if(GIsEditor) { CalculateUniqueVertCount(); } #endif // WITH_EDITOR // serialize the lighting guid if it's there Ar << LightingGuid; Ar << LightmassSettings; }
void UBlueprint::Serialize(FArchive& Ar) { Super::Serialize(Ar); #if WITH_EDITORONLY_DATA if(Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_BLUEPRINT_VARS_NOT_READ_ONLY) { // Allow all blueprint defined vars to be read/write. undoes previous convention of making exposed variables read-only for (int32 i = 0; i < NewVariables.Num(); ++i) { FBPVariableDescription& Variable = NewVariables[i]; Variable.PropertyFlags &= ~CPF_BlueprintReadOnly; } } if(Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ADD_KISMETVISIBLE) { for (int32 i = 0; i < NewVariables.Num(); ++i) { FBPVariableDescription& Variable = NewVariables[i]; Variable.PropertyFlags |= CPF_BlueprintVisible; } } if (Ar.UE4Ver() < VER_UE4_K2NODE_REFERENCEGUIDS) { for (int32 Index = 0; Index < NewVariables.Num(); ++Index) { NewVariables[Index].VarGuid = FGuid::NewGuid(); } } // Preload our parent blueprints if (Ar.IsLoading()) { for (UClass* ClassIt = ParentClass; (ClassIt != NULL) && !(ClassIt->HasAnyClassFlags(CLASS_Native)); ClassIt = ClassIt->GetSuperClass()) { if (ClassIt->ClassGeneratedBy->HasAnyFlags(RF_NeedLoad)) { ClassIt->ClassGeneratedBy->GetLinker()->Preload(ClassIt->ClassGeneratedBy); } } } // If we don't have a skeleton class via compile-on-load, generate one now if( Ar.IsLoading() && (SkeletonGeneratedClass == NULL) ) { bool bWasRegen = bIsRegeneratingOnLoad; bIsRegeneratingOnLoad = true; FBlueprintEditorUtils::PreloadMembers(this); FBlueprintEditorUtils::PreloadConstructionScript(this); FKismetEditorUtilities::GenerateBlueprintSkeleton(this); bIsRegeneratingOnLoad = bWasRegen; } if (Ar.UE4Ver() < VER_UE4_BP_ACTOR_VARIABLE_DEFAULT_PREVENTING) { // Actor variables can't have default values (because Blueprint templates are library elements that can // bridge multiple levels and different levels might not have the actor that the default is referencing). for (int32 i = 0; i < NewVariables.Num(); ++i) { FBPVariableDescription& Variable = NewVariables[i]; const FEdGraphPinType& VarType = Variable.VarType; if (!VarType.PinSubCategoryObject.IsValid()) // ignore variables that don't have associated objects { continue; } const UClass* ClassObject = Cast<UClass>(VarType.PinSubCategoryObject.Get()); // if the object type is an actor... if ((ClassObject == NULL) && ClassObject->IsChildOf(AActor::StaticClass())) { // hide the default value field Variable.PropertyFlags |= CPF_DisableEditOnTemplate; } } } #endif // WITH_EDITORONLY_DATA }