public UScriptSet(FAssetArchive Ar, FPropertyTagData?tagData) { var innerType = tagData?.InnerType ?? throw new ParserException(Ar, "UScriptSet needs inner type"); var numElementsToRemove = Ar.Read <int>(); for (var i = 0; i < numElementsToRemove; i++) { FPropertyTagType.ReadPropertyTagType(Ar, innerType, tagData, ReadType.ARRAY); } var num = Ar.Read <int>(); Properties = new List <FPropertyTagType>(num); for (var i = 0; i < num; i++) { var property = FPropertyTagType.ReadPropertyTagType(Ar, innerType, tagData, ReadType.ARRAY); if (property != null) { Properties.Add(property); } else { Log.Debug($"Failed to read element for index {i} in set"); } } }
public AsTime(FAssetArchive Ar) { SourceDateTime = Ar.Read <FDateTime>(); TimeStyle = Ar.Read <EDateTimeStyle>(); TimeZone = Ar.ReadFString(); TargetCulture = Ar.ReadFString(); }
public FSkeletalMeshVertexBuffer(FAssetArchive Ar) { var stripDataFlags = new FStripDataFlags(Ar, (int)UE4Version.VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX); NumTexCoords = Ar.Read <int>(); bUseFullPrecisionUVs = Ar.ReadBoolean(); if (Ar.Ver >= UE4Version.VER_UE4_SUPPORT_GPUSKINNING_8_BONE_INFLUENCES && FSkeletalMeshCustomVersion.Get(Ar) < FSkeletalMeshCustomVersion.Type.UseSeparateSkinWeightBuffer) { bExtraBoneInfluences = Ar.ReadBoolean(); } MeshExtension = Ar.Read <FVector>(); MeshOrigin = Ar.Read <FVector>(); if (!bUseFullPrecisionUVs) { VertsHalf = Ar.ReadBulkArray(() => new FGPUVertHalf(Ar, NumTexCoords)); } else { VertsFloat = Ar.ReadBulkArray(() => new FGPUVertFloat(Ar, NumTexCoords)); } }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); var bCooked = false; if (FFortniteMainBranchObjectVersion.Get(Ar) >= FFortniteMainBranchObjectVersion.Type.SerializeInstancedStaticMeshRenderData || FEditorObjectVersion.Get(Ar) >= FEditorObjectVersion.Type.SerializeInstancedStaticMeshRenderData) { bCooked = Ar.ReadBoolean(); } PerInstanceSMData = Ar.ReadBulkArray(() => new FInstancedStaticMeshInstanceData(Ar)); if (FRenderingObjectVersion.Get(Ar) >= FRenderingObjectVersion.Type.PerInstanceCustomData) { PerInstanceSMCustomData = Ar.ReadBulkArray(Ar.Read <float>); } if (bCooked && (FFortniteMainBranchObjectVersion.Get(Ar) >= FFortniteMainBranchObjectVersion.Type.SerializeInstancedStaticMeshRenderData || FEditorObjectVersion.Get(Ar) >= FEditorObjectVersion.Type.SerializeInstancedStaticMeshRenderData)) { var renderDataSizeBytes = Ar.Read <long>(); if (renderDataSizeBytes > 0) { // idk what to do here... But it fixes the warnings ЪциРђЇ Ar.Position = validPos; } } }
public UScriptArray(FAssetArchive Ar, FPropertyTagData?tagData) { InnerType = tagData?.InnerType ?? throw new ParserException(Ar, "UScriptArray needs inner type"); var elementCount = Ar.Read <int>(); if (Ar.HasUnversionedProperties) { InnerTagData = tagData.InnerTypeData; } else if (InnerType == "StructProperty" || InnerType == "ArrayProperty") { InnerTagData = new FPropertyTag(Ar, false).TagData; if (InnerTagData == null) { throw new ParserException(Ar, $"Couldn't read ArrayProperty with inner type {InnerType}"); } } Properties = new List <FPropertyTagType>(elementCount); for (int i = 0; i < elementCount; i++) { var property = FPropertyTagType.ReadPropertyTagType(Ar, InnerType, InnerTagData, ReadType.ARRAY); if (property != null) { Properties.Add(property); } else { Log.Debug( $"Failed to read array property of type {InnerType} at ${Ar.Position}, index {i}"); } } }
public FPackageIndex AreaClass; // UNavArea public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); var startPos = Ar.Position; int version; var myMagic = Ar.Read <uint>(); if (myMagic != Consts.Magic) { version = Consts.Initial; Ar.Position = startPos; } else { version = Ar.Read <int>(); } var _ = Ar.Read <FGuid>(); // Zeroed GUID, unused var bCooked = Ar.ReadBoolean(); if (bCooked) { CookedFormatData = new FFormatContainer(Ar); } if (version >= Consts.AreaClass) { AreaClass = new FPackageIndex(Ar); } }
public UScriptMap(FAssetArchive Ar, FPropertyTagData tagData) { if (tagData.InnerType == null || tagData.ValueType == null) { throw new ParserException(Ar, "Can't serialize UScriptMap without key or value type"); } int numKeyToRemove = Ar.Read <int>(); for (int i = 0; i < numKeyToRemove; i++) { FPropertyTagType.ReadPropertyTagType(Ar, tagData.InnerType, tagData, ReadType.MAP); } int numEntries = Ar.Read <int>(); Properties = new Dictionary <FPropertyTagType?, FPropertyTagType?>(numEntries); for (int i = 0; i < numEntries; i++) { try { Properties[FPropertyTagType.ReadPropertyTagType(Ar, tagData.InnerType, tagData.InnerTypeData, ReadType.MAP)] = FPropertyTagType.ReadPropertyTagType(Ar, tagData.ValueType, tagData.ValueTypeData, ReadType.MAP); } catch (ParserException e) { throw new ParserException(Ar, $"Failed to read key/value pair for index {i} in map", e); } } }
public EnumProperty(FAssetArchive Ar, FPropertyTagData?tagData, ReadType type) { if (type == ReadType.ZERO) { Value = new FName(IndexToEnum(Ar, tagData?.EnumName, 0)); } else if (Ar.HasUnversionedProperties && type == ReadType.NORMAL) { var index = 0; if (tagData?.InnerType != null) { var underlyingProp = ReadPropertyTagType(Ar, tagData.InnerType, tagData.InnerTypeData, ReadType.NORMAL)?.GenericValue; if (underlyingProp != null && underlyingProp.IsNumericType()) { index = Convert.ToInt32(underlyingProp); } } else { index = Ar.Read <byte>(); } Value = new FName(IndexToEnum(Ar, tagData?.EnumName, index)); } else { Value = Ar.ReadFName(); } }
public None(FAssetArchive Ar) { if (Ar.ReadBoolean()) // bHasCultureInvariantString { CultureInvariantString = Ar.ReadFString(); } }
public FSkeletalMaterial(FAssetArchive Ar) { Material = Ar.ReadObject <UMaterialInterface>(); if (FEditorObjectVersion.Get(Ar) >= FEditorObjectVersion.Type.RefactorMeshEditorMaterials) { MaterialSlotName = Ar.ReadFName(); var bSerializeImportedMaterialSlotName = false; if (FCoreObjectVersion.Get(Ar) >= FCoreObjectVersion.Type.SkeletalMaterialEditorDataStripping) { bSerializeImportedMaterialSlotName = Ar.ReadBoolean(); } if (bSerializeImportedMaterialSlotName) { ImportedMaterialSlotName = Ar.ReadFName(); } } else { if (Ar.Ver >= UE4Version.VER_UE4_MOVE_SKELETALMESH_SHADOWCASTING) { Ar.Position += 4; } if (FRecomputeTangentCustomVersion.Get(Ar) >= FRecomputeTangentCustomVersion.Type.RuntimeRecomputeTangent) { Ar.Position += 4; } } if (FRenderingObjectVersion.Get(Ar) >= FRenderingObjectVersion.Type.TextureStreamingMeshUVChannelData) { UVChannelData = new FMeshUVChannelInfo(Ar); } }
public FReferenceSkeleton(FAssetArchive Ar) { FinalRefBoneInfo = Ar.ReadArray(() => new FMeshBoneInfo(Ar)); FinalRefBonePose = Ar.ReadArray <FTransform>(); if (Ar.Ver >= EUnrealEngineObjectUE4Version.REFERENCE_SKELETON_REFACTOR) { var num = Ar.Read <int>(); FinalNameToIndexMap = new Dictionary <FName, int>(num); for (var i = 0; i < num; ++i) { FinalNameToIndexMap[Ar.ReadFName()] = Ar.Read <int>(); } } if (Ar.Ver < EUnrealEngineObjectUE4Version.FIXUP_ROOTBONE_PARENT) { if (FinalRefBoneInfo.Length > 0 && FinalRefBoneInfo[0].ParentIndex != -1) { FinalRefBoneInfo[0] = new FMeshBoneInfo(FinalRefBoneInfo[0].Name, -1); } } AdjustBoneScales(FinalRefBonePose); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); SuperStruct = new FPackageIndex(Ar); if (Ar.Game == EGame.GAME_SOD2) { Ar.Position += 4; //var someScriptImport = new FPackageIndex(Ar); } if (FFrameworkObjectVersion.Get(Ar) < FFrameworkObjectVersion.Type.RemoveUField_Next) { var firstChild = new FPackageIndex(Ar); Children = firstChild.IsNull ? Array.Empty <FPackageIndex>() : new[] { firstChild }; } else { Children = Ar.ReadArray(() => new FPackageIndex(Ar)); } if (FCoreObjectVersion.Get(Ar) >= FCoreObjectVersion.Type.FProperties) { DeserializeProperties(Ar); } var bytecodeBufferSize = Ar.Read <int>(); var serializedScriptSize = Ar.Read <int>(); Ar.Position += serializedScriptSize; // should we read the bytecode some day? }
private void SerializeCompressedData(FAssetArchive Ar) { // These fields were serialized as properties in pre-UE4.12 engine version KeyEncodingFormat = Ar.Read <AnimationKeyFormat>(); TranslationCompressionFormat = Ar.Read <AnimationCompressionFormat>(); RotationCompressionFormat = Ar.Read <AnimationCompressionFormat>(); ScaleCompressionFormat = Ar.Read <AnimationCompressionFormat>(); CompressedTrackOffsets = Ar.ReadArray <int>(); CompressedScaleOffsets = new FCompressedOffsetData(Ar); if (Ar.Game >= EGame.GAME_UE4_21) { // UE4.21+ - added compressed segments; disappeared in 4.23 CompressedSegments = Ar.ReadArray <FCompressedSegment>(); if (CompressedSegments.Length > 0) { Log.Information("animation has CompressedSegments!"); } } CompressedTrackToSkeletonMapTable = Ar.ReadArray <FTrackToSkeletonMap>(); if (Ar.Game < EGame.GAME_UE4_22) { CompressedCurveData = new FStructFallback(Ar, "RawCurveTracks"); } else { var compressedCurveNames = Ar.ReadArray(() => new FSmartName(Ar)); } if (Ar.Game >= EGame.GAME_UE4_17) { // UE4.17+ var compressedRawDataSize = Ar.Read <int>(); } if (Ar.Game >= EGame.GAME_UE4_22) { var compressedNumFrames = Ar.Read <int>(); } // compressed data var numBytes = Ar.Read <int>(); CompressedByteStream = Ar.ReadBytes(numBytes); if (Ar.Game >= EGame.GAME_UE4_22) { var curveCodecPath = Ar.ReadFString(); var compressedCurveByteStream = Ar.ReadArray <byte>(); } // Fix layout of "byte swapped" data (workaround for UE4 bug) if (KeyEncodingFormat == AnimationKeyFormat.AKF_PerTrackCompression && CompressedScaleOffsets.OffsetData.Length > 0 && Ar.Game < EGame.GAME_UE4_23) { throw new NotImplementedException(); } }
private static string IndexToEnum(FAssetArchive Ar, FPropertyTagData?tagData, int index) { var enumName = tagData?.EnumName; if (enumName == null) { return(index.ToString()); } if (tagData.Enum != null) // serialized { foreach (var(name, value) in tagData.Enum.Names) { if (value == index) { return(name.Text); } } return(string.Concat(enumName, "::", index)); } if (Ar.Owner.Mappings != null && Ar.Owner.Mappings.Enums.TryGetValue(enumName, out var values) && values.TryGetValue(index, out var member)) { return(string.Concat(enumName, "::", member)); } return(string.Concat(enumName, "::", index)); }
public FObjectImport(FAssetArchive Ar) { ClassPackage = Ar.ReadFName(); ClassName = Ar.ReadFName(); OuterIndex = new FPackageIndex(Ar); ObjectName = Ar.ReadFName(); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); var stripFlags = new FStripDataFlags(Ar); if (!stripFlags.IsDataStrippedForServer()) { var numEntries = Ar.Read <int>(); MeshBuildData = new Dictionary <FGuid, FMeshMapBuildData>(numEntries); for (var i = 0; i < numEntries; ++i) { MeshBuildData[Ar.Read <FGuid>()] = new FMeshMapBuildData(Ar); } numEntries = Ar.Read <int>(); LevelPrecomputedLightVolumeBuildData = new Dictionary <FGuid, FPrecomputedLightVolumeData>(numEntries); for (var i = 0; i < numEntries; ++i) { LevelPrecomputedLightVolumeBuildData[Ar.Read <FGuid>()] = new FPrecomputedLightVolumeData(Ar); } if (FRenderingObjectVersion.Get(Ar) >= FRenderingObjectVersion.Type.VolumetricLightmaps) { numEntries = Ar.Read <int>(); LevelPrecomputedVolumetricLightmapBuildData = new Dictionary <FGuid, FPrecomputedVolumetricLightmapData>(numEntries); for (var i = 0; i < numEntries; ++i) { LevelPrecomputedVolumetricLightmapBuildData[Ar.Read <FGuid>()] = new FPrecomputedVolumetricLightmapData(Ar); } } numEntries = Ar.Read <int>(); LightBuildData = new Dictionary <FGuid, FLightComponentMapBuildData>(numEntries); for (var i = 0; i < numEntries; ++i) { LightBuildData[Ar.Read <FGuid>()] = new FLightComponentMapBuildData(Ar); } if (FReflectionCaptureObjectVersion.Get(Ar) >= FReflectionCaptureObjectVersion.Type.MoveReflectionCaptureDataToMapBuildData) { numEntries = Ar.Read <int>(); ReflectionCaptureBuildData = new Dictionary <FGuid, FReflectionCaptureMapBuildData>(numEntries); for (var i = 0; i < numEntries; ++i) { ReflectionCaptureBuildData[Ar.Read <FGuid>()] = new FReflectionCaptureMapBuildData(Ar); } } if (FRenderingObjectVersion.Get(Ar) >= FRenderingObjectVersion.Type.SkyAtmosphereStaticLightingVersioning) { numEntries = Ar.Read <int>(); SkyAtmosphereBuildData = new Dictionary <FGuid, FSkyAtmosphereMapBuildData>(numEntries); for (var i = 0; i < numEntries; ++i) { SkyAtmosphereBuildData[Ar.Read <FGuid>()] = new FSkyAtmosphereMapBuildData(Ar); } } } }
protected static void DeserializeObject(UObject obj, FAssetArchive Ar, long serialSize) { var serialOffset = Ar.Position; var validPos = serialOffset + serialSize; try { obj.Deserialize(Ar, validPos); #if DEBUG if (validPos != Ar.Position) { Log.Warning("Did not read {0} correctly, {1} bytes remaining", obj.ExportType, validPos - Ar.Position); } else { Log.Debug("Successfully read {0} at {1} with size {2}", obj.ExportType, serialOffset, serialSize); } #endif } catch (Exception e) { if (Globals.FatalObjectSerializationErrors) { throw new ParserException($"Could not read {obj.ExportType} correctly", e); } Log.Error(e, "Could not read {0} correctly", obj.ExportType); } }
public FMovieSceneSegment(FAssetArchive Ar) { Range = Ar.Read <TRange <FFrameNumber> >(); ID = Ar.Read <FMovieSceneSegmentIdentifier>(); bAllowEmpty = Ar.ReadBoolean(); Impls = Ar.ReadArray <FSectionEvaluationData>(); }
} // Index of the string in the NameMap public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); StringTable = new FStringTable(Ar); StringTableId = Ar.Read <int>(); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); PersistentLevel = new FPackageIndex(Ar); ExtraReferencedObjects = Ar.ReadArray(() => new FPackageIndex(Ar)); StreamingLevels = Ar.ReadArray(() => new FPackageIndex(Ar)); }
public FSkelMeshChunk(FAssetArchive Ar) { var stripDataFlags = Ar.Read <FStripDataFlags>(); if (!stripDataFlags.IsDataStrippedForServer()) { BaseVertexIndex = Ar.Read <int>(); } if (!stripDataFlags.IsEditorDataStripped()) { RigidVertices = Ar.ReadArray(() => new FRigidVertex(Ar)); SoftVertices = Ar.ReadArray(() => new FSoftVertex(Ar)); } BoneMap = Ar.ReadArray <ushort>(); NumRigidVertices = Ar.Read <int>(); NumSoftVertices = Ar.Read <int>(); MaxBoneInfluences = Ar.Read <int>(); HasClothData = false; if (Ar.Ver >= UE4Version.VER_UE4_APEX_CLOTH) { // Physics data, drop var clothMappingData = Ar.ReadArray(() => new FApexClothPhysToRenderVertData(Ar)); Ar.ReadArray <FVector>(); // PhysicalMeshVertices Ar.ReadArray <FVector>(); // PhysicalMeshNormals Ar.Position += 4; // CorrespondClothAssetIndex, ClothAssetSubmeshIndex HasClothData = clothMappingData.Length > 0; } }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); var numRows = Ar.Read <int>(); var bUpgradingCurveTable = FFortniteMainBranchObjectVersion.Get(Ar) < FFortniteMainBranchObjectVersion.Type.ShrinkCurveTableSize; if (bUpgradingCurveTable) { CurveTableMode = numRows > 0 ? ECurveTableMode.RichCurves : ECurveTableMode.Empty; } else { CurveTableMode = Ar.Read <ECurveTableMode>(); } RowMap = new Dictionary <FName, FStructFallback>(numRows); for (var i = 0; i < numRows; i++) { var rowName = Ar.ReadFName(); string rowStruct = CurveTableMode switch { ECurveTableMode.SimpleCurves => "SimpleCurve", ECurveTableMode.RichCurves => "RichCurve", _ => "" }; RowMap[rowName] = new FStructFallback(Ar, rowStruct); } }
public FZoneProperties(FAssetArchive Ar) { ZoneActor = new FPackageIndex(Ar); Connectivity = Ar.Read <FZoneSet>(); Visibility = Ar.Read <FZoneSet>(); LastRenderTime = Ar.Read <float>(); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); bStreaming = Ar.Game >= EGame.GAME_UE4_25; if (TryGetValue(out bool s, nameof(bStreaming))) // will return false if not found { bStreaming = s; } else if (TryGetValue(out FName loadingBehavior, "LoadingBehavior")) { bStreaming = !loadingBehavior.IsNone && loadingBehavior.Text != "ESoundWaveLoadingBehavior::ForceInline"; } bCooked = Ar.ReadBoolean(); if (!bStreaming) { if (bCooked) { CompressedFormatData = new FFormatContainer(Ar); } else { RawData = new FByteBulkData(Ar); } CompressedDataGuid = Ar.Read <FGuid>(); } else { CompressedDataGuid = Ar.Read <FGuid>(); RunningPlatformData = new FStreamedAudioPlatformData(Ar); } }
public FTexture2DMipMap(FAssetArchive Ar) { SizeZ = 1; var cooked = Ar.Ver >= UE4Version.VER_UE4_TEXTURE_SOURCE_ART_REFACTOR && Ar.ReadBoolean(); Data = new FByteBulkData(Ar); if (Ar.Game == EGame.GAME_BORDERLANDS3) { SizeX = Ar.Read <ushort>(); SizeY = Ar.Read <ushort>(); SizeZ = Ar.Read <ushort>(); } else { SizeX = Ar.Read <int>(); SizeY = Ar.Read <int>(); if (Ar.Game >= EGame.GAME_UE4_20) { SizeZ = Ar.Read <int>(); } } if (Ar.Ver >= UE4Version.VER_UE4_TEXTURE_DERIVED_DATA2 && !cooked) { var derivedDataKey = Ar.ReadFString(); } }
public static Type Get(FAssetArchive Ar) { int ver = VersionUtils.GetUE4CustomVersion(Ar, GUID); if (ver >= 0) { return((Type)ver); } if (Ar.Game < EGame.GAME_UE4_21) { return(Type.BeforeCustomVersionWasAdded); } if (Ar.Game < EGame.GAME_UE4_25) { return(Type.StoreMarkerNamesOnSkeleton); } if (Ar.Game < EGame.GAME_UE4_26) { return((Type)7); } if (Ar.Game < EGame.GAME_UE4_27) { return((Type)15); } return(Type.LatestVersion); }
public FSoftObjectPath OwningLevel; // UWorld public FLevelStreamedDeleteActorRecord(FAssetArchive Ar) { ActorId = Ar.ReadFName(); Transform = Ar.Read <FTransform>(); ActorClass = new FSoftObjectPath(Ar); OwningLevel = new FSoftObjectPath(Ar); }
public FSkeletalMaterial(FAssetArchive Ar) { Material = new FPackageIndex(Ar).ResolvedObject; if (FEditorObjectVersion.Get(Ar) >= FEditorObjectVersion.Type.RefactorMeshEditorMaterials) { MaterialSlotName = Ar.ReadFName(); var bSerializeImportedMaterialSlotName = !Ar.Owner.HasFlags(EPackageFlags.PKG_FilterEditorOnly); if (FCoreObjectVersion.Get(Ar) >= FCoreObjectVersion.Type.SkeletalMaterialEditorDataStripping) { bSerializeImportedMaterialSlotName = Ar.ReadBoolean(); } if (bSerializeImportedMaterialSlotName) { ImportedMaterialSlotName = Ar.ReadFName(); } } else { if (Ar.Ver >= EUnrealEngineObjectUE4Version.MOVE_SKELETALMESH_SHADOWCASTING) { Ar.Position += 4; } if (FRecomputeTangentCustomVersion.Get(Ar) >= FRecomputeTangentCustomVersion.Type.RuntimeRecomputeTangent) { var bRecomputeTangent = Ar.ReadBoolean(); } } if (FRenderingObjectVersion.Get(Ar) >= FRenderingObjectVersion.Type.TextureStreamingMeshUVChannelData) { UVChannelData = new FMeshUVChannelInfo(Ar); } }
public UScriptMap(FAssetArchive Ar, FPropertyTagData tagData) { if (tagData.InnerType == null || tagData.ValueType == null) { throw new ParserException(Ar, "Can't serialize UScriptMap without key or value type"); } var numKeysToRemove = Ar.Read <int>(); for (var i = 0; i < numKeysToRemove; i++) { FPropertyTagType.ReadPropertyTagType(Ar, tagData.InnerType, tagData.InnerTypeData, ReadType.MAP); } var numEntries = Ar.Read <int>(); Properties = new Dictionary <FPropertyTagType?, FPropertyTagType?>(numEntries); for (var i = 0; i < numEntries; i++) { var isReadingValue = false; try { var key = FPropertyTagType.ReadPropertyTagType(Ar, tagData.InnerType, tagData.InnerTypeData, ReadType.MAP); isReadingValue = true; var value = FPropertyTagType.ReadPropertyTagType(Ar, tagData.ValueType, tagData.ValueTypeData, ReadType.MAP); Properties[key] = value; } catch (ParserException e) { throw new ParserException(Ar, $"Failed to read {(isReadingValue ? "value" : "key")} for index {i} in map", e); } } }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); ScalarParameterValues = GetOrDefault <FScalarParameterValue[]>(nameof(ScalarParameterValues)) ?? new FScalarParameterValue[0]; TextureParameterValues = GetOrDefault <FTextureParameterValue[]>(nameof(TextureParameterValues)) ?? new FTextureParameterValue[0]; VectorParameterValues = GetOrDefault <FVectorParameterValue[]>(nameof(VectorParameterValues)) ?? new FVectorParameterValue[0]; }