Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

Changing an actor's parent immediately after creation results in unpredictable behavior #728

Open
thespivey opened this issue Oct 9, 2020 · 1 comment
Labels
V2 To be included in version 2

Comments

@thespivey
Copy link
Member

thespivey commented Oct 9, 2020

If you create an Actor and change its parent before the created promise completes, things seem fine. The update will be sent and the change will take effect in the Unity runtime as expected. However, moments later when the object-spawned reply to the actor creation is received, it may reset the parentId property on the Actor to the original value.

Whether the object-spawned message contains the original or modified parentId appears to be dependent on timing.

If the parentId is overwritten with an incorrect value in this way, the defect may not be immediately obvious. The Actor is parented on the Unity side as expected and the SDK just has the wrong parent value. It becomes apparent when subsequent attempts to re-parent the Actor to its original parent are ignored, because the incorrect parent value causes them to be treated as a noop.

@thespivey
Copy link
Member Author

thespivey commented Oct 9, 2020

Here is a quick example of an MRE that creates 2 parent nodes ("A" and "B") and 100 child nodes, reparented from A to B in this fashion, and labels each of those children with its parentId value. Though all of the children are parented to B and aligned as expected, their text reveals the defect as a mix of "My parent is A" and "My parent is B".

app.ts:

import * as MRE from '@microsoft/mixed-reality-extension-sdk';

export default class Repro {

	constructor(private context: MRE.Context, private baseUrl: string) {
		context.onStarted(async () => {

			const a = MRE.Actor.Create(context, {
				actor: {
					name: 'A',
					transform: {
						app: { position: { x: -0.5, y: 0, z: 0 } }
					},
					text: {
						contents: "A",
						height: 0.3
					}
				}
			});
			await a.created();

			const b = MRE.Actor.Create(context, {
				actor: {
					name: 'B',
					transform: {
						app: { position: { x: 0.5, y: 0, z: 0 } }
					},
					text: {
						contents: "B",
						height: 0.3
					}
				}
			});
			await b.created();


			const nodes: MRE.Actor[] = [];

			setInterval(() => {
				nodes.forEach(node => {
					node.text.contents = "My parent is " + node.parent.name
				});
			}, 0);

			for (let i=0; i<100; i++) {
				const node = MRE.Actor.Create(context, {
					actor: {
						name: 'Test Node ' + i,
						parentId: a.id,
						transform: {
							local: { position: { x: 0, y: -0.5 * (i + 1), z: 0 } }
						},
						text: {
							contents: "Initial text",
							height: 0.3
						}
					}
				});
				node.parent = b;

				nodes.push(node);
				await node.created();
			}

		});
	}
}

If we were to subsequently try to reparent these nodes back to A, only the ones labelled "My parent is B" would correctly move.

This bug can be reproduced with only a single child node, but is intermittent due to timing. Using 100 nodes helps illustrates the random behavior.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
V2 To be included in version 2
Projects
None yet
Development

No branches or pull requests

1 participant