Dictionary being cleared when reaching end of Update
Asked Answered
A

3

0

Hello everyone, I have an update function below that is supposed to be tracking bodies from the Kinect.

However I have an issue where the _Bodies Dictionary doesn’t store anything and is always cleared when the Update loop starts back from the top. Once it gets to this point:

List knownIds = new List (_Bodies.Keys);

_Bodies is already at a count of zero. So the code that is supposed to remove a key value pair if it’s not being tracked by the Kinect anymore doesn’t run. Also this means that it just keeps instantiating new objects over and over again.

Can anyone see why my Dictionary might not be storing values properly?

private Dictionary<ulong, GameObject> _Bodies = new Dictionary<ulong, GameObject> ();

void Update()          
{
	if (BodySourceManager == null) {
		return;
	}
	
	_BodyManager = BodySourceManager.GetComponent<BodySourceManager> ();
	if (_BodyManager == null) {
		return;
	}
	
	Kinect.Body[] data = _BodyManager.GetData ();
	if (data == null) {
		return;
	}
	
	List<ulong> trackedIds = new List<ulong> ();
	foreach (var body in data) {
		if (body == null) {
			continue;
		}
			
		if (body.IsTracked) {
			trackedIds.Add (body.TrackingId);
		}
	}

	List<ulong> knownIds = new List<ulong> (_Bodies.Keys);

	// First delete untracked bodies
	foreach (ulong trackingId in knownIds) {
		if (!trackedIds.Contains (trackingId)) {
			Destroy (_Bodies [trackingId]);
			_Bodies.Remove (trackingId);
		}
	}

	foreach (var body in data){
		if (body == null) {
			continue;
		}
		
		if (body.IsTracked) 
		{   
			if (!_Bodies.ContainsKey (body.TrackingId)) {
				_Bodies [body.TrackingId] = InstantiateMyObject(body);
			}

			RefreshBodyObject (body);
		}
	}
}
Approval answered 6/5 at 16:58 Comment(2)

_BodyManager = BodySourceManager.GetComponent<BodySourceManager> (); Put that in Start(). So, whats this RefreshBodyObject and whats in that BodySourceManager? Could they cause the problems?

Democritus

So, I should try switching to "v2f vert (appdata v)" and calculate transforms using something like this: v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); If i understand you correctly.

Titty
D
0

Every time you use new you are overwriting what was there before. If you want the data to persist this will not work. Maybe this is your intention? I don’t know.

Also, you need to make sure your null check is working on _Bodies. Put a Debug.Log before the return to see what the situation is.

Democritus answered 6/5 at 16:58 Comment(1)

The two lists "trackedIds" and "knownIds" I do want overwritten. The only one I want to persist data is the "_Bodies" list. The null check is just there in case the Kinect isn't connected so it doesn't just throw null errors. Theres always a list of 6 populated "bodies" from the Kinect when it's connected and running. I don't see anything that should be clearing the _Bodies list but for some reason between update loops its being cleared every time by the very top of the loop.

Approval
S
0

Remember that you are using an external Hardware sensor which isn’t managed by Unity, so my bet is that the Kinect is likely updating at a much slower rate than unity. in the frames that things are getting deleted is likely due to the Kinect is still generating the body for its next update (which is asynchronous to Unity’s Update). I’ve done a quick search and I’ve seen that the kinect (not the unity wrapper, but the SDK itself) doesn’t present a body data on every frame (30 or 60 fps), but only on the frames that it is ready (usually much lower some examples I’ve seen are at 16fps).

what this likely means is that you shouldn’t be adding/removing Gameobjects based on tracked bodies inside an Update() call. instead try having the Gameobject always instantiated, but either hidden or moved off screen.

Or only go by the last updated frame. you likely want to get the last updated frame like is done in this guy’s body manager:

Sargeant answered 6/5 at 16:57 Comment(1)

That body manager is the same one included in the Kinect SDK that I am using, the class I have above was also just adapted from their SDK example. I followed instantiating when they did, I thought it might be because of the update discrepancy as well. I changed it around a bit so I never store a reference to the actual bodies tracking id, but a copy of it and its still being cleared.

Approval
E
0

I spent a day and a half trying to figure this out and found no fixes online or from multiple AIs.

For anyone hoping to keep their dictionary intact, I succeed simply by making it static. This way it is no longer mysteriously cleared at the end of frame. If anyone know why this is happening, or another fix to this issue, please post!

Ethbinium answered 5/5 at 1:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.