public override bool CanWrite => false; // Only use for read operations, not write operations. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Instantiate the object the way Unity needs GameObject go = new GameObject(); // Add a SpatialFrame to it SpatialFrame frame = go.AddComponent <SpatialFrame>(); // Deserialize into the instance serializer.Populate(reader, frame); // Update the game object name to match go.name = frame.Id; // Return the frame return(frame); }
/// <summary> /// Gathers all dependency components and disables the behavior if a /// dependency is not found. /// </summary> private void GatherDependencies() { // If no anchor container is specified, create one. if (anchorContainer == null) { anchorContainer = new GameObject("Anchor Container"); } // We must have a prefab to generate for anchors. if (anchorPrefab == null) { Debug.LogError($"{nameof(anchorPrefab)} is required but is not set. {nameof(RefinementExampleManager)} has been disabled."); this.enabled = false; } // We must have a large-scale model to turn on and off if (largeScaleModel == null) { Debug.LogError($"{nameof(largeScaleModel)} is required but is not set. {nameof(RefinementExampleManager)} has been disabled."); this.enabled = false; } else { // Attempt to get the frame largeScaleFrame = largeScaleModel.GetComponent <SpatialFrame>(); } // The large scale model should be sitting on a spatial frame if (largeScaleFrame == null) { Debug.LogError($"{nameof(largeScaleModel)} should have a {nameof(SpatialFrame)} component but none was found. {nameof(RefinementExampleManager)} has been disabled."); this.enabled = false; } else { multiParent = largeScaleFrame.AlignmentStrategy as MultiParentAlignment; } // The spatial frames alignment strategy should be MultiParent. if (multiParent == null) { Debug.LogError($"The alignment strategy for {nameof(largeScaleModel)} should be {nameof(MultiParentAlignment)} but none was found. {nameof(RefinementExampleManager)} has been disabled."); this.enabled = false; } }
/// <summary> /// Executes the specified step in a series of steps. /// </summary> /// <param name="step"> /// The <see cref="AddAnchorStep"/> step to execute. /// </param> private void DoStep(AddAnchorStep step) { // Log Debug.Log($"Doing {nameof(AddAnchorStep)}: {step}"); // Execute actions switch (step) { case AddAnchorStep.PlacingAnchor: // Hide the large-scale model HideModel(); // Instantiate the anchor prefab GameObject anchorGO = GameObject.Instantiate(anchorPrefab); // Set the parent so it's in the anchor container anchorGO.transform.SetParent(anchorContainer.transform, worldPositionStays: true); // Get the refining behavior newAnchor = anchorGO.GetComponentInChildren <RefinableModel>(); if (newAnchor == null) { throw new InvalidOperationException($"{nameof(AnchorPrefab)} does not have a {nameof(RefinableModel)} component."); } // Subscribe to anchor events SubscribeAnchor(newAnchor); // Put the anchor in placement mode newAnchor.RefinementMode = RefinableModelMode.Placing; break; //case AddAnchorStep.RefiningAnchor: // // Now refining anchor // newAnchor.RefinementMode = RefinableModelMode.Refining; // break; case AddAnchorStep.ModelRay: // Add a WorldAnchor to the anchor so it stays in place newAnchor.gameObject.AddComponent <WorldAnchor>(); // Done placing anchor newAnchor.RefinementMode = RefinableModelMode.Placed; // Show the model ShowModel(); // Disable MultiParent alignment on large-scale model so // that it can be positioned multiParent.enabled = false; // Detach from any current parent (if there is one) largeScaleFrame.transform.parent = null; // Create and subscribe to RayRefinement largeScaleRefinement = SubscribeRefinement <RayRefinement>(); // Start the new refining mode largeScaleRefinement.StartRefinement(); break; case AddAnchorStep.ModelNudge: // Unsubscribe from RayRefinement UnsubscribeRefinement <RayRefinement>(); // Create and subscribe to NudgeRefinement largeScaleRefinement = SubscribeRefinement <NudgeRefinement>(); // Start the new refining mode largeScaleRefinement.StartRefinement(); break; case AddAnchorStep.Finishing: // Finish refinement if still in progress if (largeScaleRefinement != null) { // Finish refinement of the large scale model if in progress if (largeScaleRefinement.IsRefining) { largeScaleRefinement.FinishRefinement(); } // Unsubscribe from refinement events UnsubscribeRefinement(largeScaleRefinement); // No current large scale refinement largeScaleRefinement = null; } // Unsubscribe from anchor events UnsubscribeAnchor(newAnchor); // Come up with an ID for this anchor string id = DateTime.Now.ToUniversalTime().Ticks.ToString(); // Create a new game object GameObject frameGO = new GameObject(id); // Set position and rotation same as the anchor frameGO.transform.position = newAnchor.transform.position; frameGO.transform.rotation = newAnchor.transform.rotation; // Parent it in the anchor container frameGO.transform.SetParent(anchorContainer.transform, worldPositionStays: true); // Add spatial frame to game object SpatialFrame newFrame = frameGO.AddComponent <SpatialFrame>(); // Give the frame an ID newFrame.Id = id; // Add a WorldAnchorAlignment to SpatialFrame WorldAnchorAlignment worldAlignment = frameGO.AddComponent <WorldAnchorAlignment>(); // Give the anchor an ID worldAlignment.AnchorId = id; // Temporarily parent the large model to the new frame largeScaleFrame.transform.SetParent(newFrame.transform, worldPositionStays: true); // Add this new frame to MultiParentAlignment as a new // parent option and using the current large-scale offset // from the anchor. multiParent.ParentOptions.Add(new ParentAlignmentOptions() { // Set frame Frame = newFrame, // Set offsets Position = largeScaleFrame.transform.localPosition, Rotation = largeScaleFrame.transform.localRotation.eulerAngles, Scale = largeScaleFrame.transform.localScale, }); // Unparent the large-scale model largeScaleFrame.transform.parent = null; // Delete the new anchor game object and all children DestroyImmediate(newAnchor.gameObject); newAnchor = null; // Show the model ShowModel(); // Re-enable MultiParent alignment multiParent.enabled = true; // Done anchorStep = AddAnchorStep.Done; mode = RefinementExampleMode.None; break; default: Debug.LogError($"Unknown step {step}"); break; } }