immersivecognition / unity-experiment-framework

UXF - Framework for creating human behaviour experiments in Unity
https://immersivecognition.github.io/unity-experiment-framework/
MIT License
214 stars 41 forks source link

Custom Trackers need to be re-added as a component after changes to the customHeader #103

Closed Avdbergnmf closed 2 years ago

Avdbergnmf commented 2 years ago

Otherwise the Table headers aren't filled in the UXFDataTable.

InvalidOperationException: The row does not contain values for the same columns as the columns in the table!
Table: time
Row: right_pos_x, right_pos_y, right_pos_z, right_rot_x, right_rot_y, right_rot_z, left_pos_x, left_pos_y, left_pos_z, left_rot_x, left_rot_y, left_rot_z, time
UXF.UXFDataTable.AddCompleteRow (UXF.UXFDataRow newRow) (at Assets/UXF/Scripts/Etc/UXFDataTable.cs:109)
UXF.Tracker.RecordRow () (at Assets/UXF/Scripts/Etc/Tracker.cs:97)
UXF.Tracker.LateUpdate () (at Assets/UXF/Scripts/Etc/Tracker.cs:79)

Not sure if this is a bug or a feature, but it took me a good hour to figure out this problem.

Edit: Another solution could be to just mention this fact in the Wiki documentation!

thefirstfloor commented 2 years ago

Hi, I'm having the same issue, but not quite understanding what you are saying as a 'solution'?

I'm using the same UXF version is 2 projects, but with one of them I get this error. Looking at the tracker.cs script, it seems as if the column name 'time' is added on first index of the array.

        public string[] header
        { 
            get
            {
                var newHeader = new string[customHeader.Length + 1];
                newHeader[0] = "time";
                customHeader.CopyTo(newHeader, 1);
                return newHeader;
            }
        }

and in adding values to the new UXFdatarow, the current timestamp looks to be added at the END of the array.

    public void RecordRow()
        {
            if (!recording) throw new System.InvalidOperationException("Tracker measurements cannot be taken when not in a trial!");

            UXFDataRow newRow = GetCurrentValues();
            newRow.Add(("time", Time.time));
            data.AddCompleteRow(newRow);
        }

Or am I reading it wrong? Big mystery why it DOES work in the other project, if this were true though.

I'm using the default PositionRotationTracker

jackbrookes commented 2 years ago

and in adding values to the new UXFdatarow, the current timestamp looks to be added at the END of the array.

I think its not an ordering issue- the error message shows the customHeader would have been blank, so that is probably the issue

@Avdbergnmf can you explain what you actually did ("Custom Trackers need to be re-added as a component after changes to the customHeader"). When are you changing the header, and when are you re-adding the component?

Avdbergnmf commented 2 years ago

Sure!

When I change the customHeader values, just compiling in the editor doesn't correctly change it. What I need to do instead, is remove the component (in Inspector -> RMB -> Remove component), then simply re-add it and make sure you re-assign all the serialized fields + the data collection in the UXF rig. This fixes it for me.

Edit: though this does seem like a bug to me, but this workaround fixed it for me.

thefirstfloor commented 2 years ago

In my case the situation was slightly different.

The Position Rotation Tracker script is on a custom prefab, but has all default UXF values in the header (so no customheader). After adding it to the scene, disabling that component/script on the prefab in the hierarchy and adding a new one from the UXF folder seemed to fix the issue. Not very convenient but it works.

Avdbergnmf commented 2 years ago

In my case the situation was slightly different.

The Position Rotation Tracker script is on a custom prefab, but has all default UXF values in the header (so no customheader). After adding it to the scene, disabling that component/script on the prefab in the hierarchy and adding a new one from the UXF folder seemed to fix the issue. Not very convenient but it works.

Glad u got it to work :)

jackbrookes commented 2 years ago

what are you guys trying to do by changing the custom values? they should be read-only:

image

Avdbergnmf commented 2 years ago

Creating a new custom tracker script with the SetupDescriptorAndHeader method defined. Saves script, compile, test script (run scene), open the script to change it, change the customHeader values (and the related GetCurrentValues stuff), save script, compile, run scene, get error.

jackbrookes commented 2 years ago

got it, I understand the issue, will fix! In the meantime delete/re-add. You also may be able to right click -> reset the component.

jackbrookes commented 2 years ago

This is now fixed in UXF 2.4.1, with some improvements to the inspector. The issue is related to Unity Serialisation. If you have a custom tracker script, you will need implement the two properties CustomHeader and MeasurementDescriptor. See here: https://github.com/immersivecognition/unity-experiment-framework/wiki/Tracker-system