For context, I am currently integrating the Gameplay Camera System in our workflow, and I’m trying to implement a way to add “one-off” changes to parameters. By that, I mean adding a generic option to change a parameter under specific circumstances (like during a Gameplay Ability activation), then reset it back to the original value.
The challenges I’m facing are multiple:
The Getters and Setters are only BP-facing and individualised per parameter, which means a generic system to change parameters on the fly requires a dedicated API per parameter, which makes it delicate to maintain as the number of parameters increases, and is unpractical for non-programmers
To my knowledge, there’s no way of resetting a parameter to its default value set in a camera rig. It seems the SetDefaultCameraRigs functions only allows for initialisation and not reinitialisation of parameters. I thought of getting the default values on component activation to then reset the parameter when needed, but storing them is another headache since the parameters don’t have a fixed type, and we’re going back to the issue of maintainability with more parameters
I’m not sure what can be done with the current system to solve this issue without bloating our workflow with a dedicated API for every parameter. A way would be to store the actual default parameters outside of the camera rigs but that seems counter-intuitive to the way GCS is supposed to work.
My question is two-fold then: Is there a way to reset a parameter to its default value, and it there a way to reduce the API bloat with a generic node or function to set parameters instead of having a dedicated one per parameter?
Let me preface this answer by saying that the Gameplay Cameras System is still experimental. Most experimental modules are subject to change and the gameplay camera system is likely to as well. The area of the module that your asking about has been dubbed the “Parameterization System” by the developer. This system is still a work in progress & has changed in each version of the engine. The developer plans to make it easier to do some sorts of value processing directly inside camera rigs. It’s likely to change again quite significantly as the module moves into beta (hopefully in 5.8).
Unfortunately for both parts of your question there is not a simple solution. You will need to use C++ to access the data that isn’t blueprint facing.
If you look into the c++ for the UBlueprintCameraVariableTableFunctionLibrary you can see how the current get/set is implemented, essentially they are:
They access the FBlueprintCameraEvaluationDataRef’s Variable table. Looking up the Variable based on the ID. To reduce the API bloat you would need to implement a system to help store/look up the ID’s & then re-implement a function library using that.
The UCameraVariableAsset that is used in the blueprint get/setters does store the default value of the variable. It would just be a matter of getting that value and setting the variable to that on the FBlueprintCameraEvaluationDataRef’s data datatable.
I hope this is helpful, Let me know if there is anything I could clarify for you.
At first I was a bit stumped because I couldn’t find a way to retrieve the U[VariableType]CameraVariable objects from the camera rig since the latter seems to only contain the FCameraVariableID of each parameter, but it turns out it’s possible to set values on the variable table with only the ID instead of the whole variable object. That should be enough to get the default values from the rig default parameters and set the current values whenever needed directly from C++.
Nevertheless, if you know how to directly retrieve the camera variable objects, that would probably be a bit more robust than having to go through the rig default parameters. Is there a way to get them?
If you’re looking to get the variable in c++ the easiest method would be to have a pointer of some kind (e.g TSoftObjectPtr) to a UCameraVariableCollection asset. Once you have that there is a public array containing the UCameraVariableAssets for that collection.
Is there a way to link the parameters inside a Camera Rig to an outside UCameraVariableCollection? It seemed like the parameter collection was only local to each Camera Rig.
I don’t think there is a built in way to achieve this. You could manually add those UCameraVariableAssets to a UCameraVariableCollection manually as the Variables array is public.
Alright, thanks for all the answers, they’ve been really helpful.
For those wondering, in the end I managed to retrieve all the parameters by directly getting the camera rig assets data through the FAssetRegistryModule, as done in UK2Node_CameraRigBase::GetMenuActions, then getting the assets from it which contains all parameter definitions:
FARFilter Filter;
Filter.ClassPaths.Add(UCameraRigAsset::StaticClass()->GetClassPathName());
TArray<FAssetData> CameraRigAssetDatas;
IAssetRegistry& AssetRegistry = FAssetRegistryModule::GetRegistry();
AssetRegistry.GetAssets(Filter, CameraRigAssetDatas);
for (const FAssetData& CameraRigAssetData : CameraRigAssetDatas)
{
UCameraRigAsset* CameraRigAsset = Cast<UCameraRigAsset>(CameraRigAssetData->GetAsset());
CameraRigAsset->GetParameterDefinitions(); // Contains the ID, type, name of all parameters
}
Then to set the values I’m getting the variable table from the shared or conditional camera data, then setting the data on the table depending on the variable type:
UE::Cameras::FCameraVariableTable& VariableTable = CameraData.GetResult()->VariableTable;
switch (ParameterType)
{
case ECameraVariableType::ParamType1:
VariableTable.TrySetValue<ParamType1>(ParameterID, Value);
. . . // Other types
}
Lastly to reset the values, I’m using the same way that’s used by the plugin to set the initial data, as implemented in FCameraObjectInterfaceParameterOverrideHelper::ApplyDefaultParametersImpl: