Skip to content

Commit e2dbdcf

Browse files
madvladkeveleigh
authored andcommitted
Refactor TapToPlace.cs to be more generic (#405)
* Refactor TapToPlace.cs to be more generic * Fix formatting * Add documentation to the README * Add braces * Fix potential null referencing and fix parent relative position assignment * Move Raycast parameters to one line * Rename placing to IsBeingDragged and make it public * Explicitly declare camera position and direction * Rename IsBeingDragged to IsBeingPlaced * Reword comments for IsBeingPlaced * Add rotation on parent when moving parent Also some small changes: * Remove the unused variable objectToPlace * Add private field to keep track of parent-child relational distance * Refactor movement code so that it only sets the position of either the child or the parent * Uncapitalized private data field
1 parent f825a57 commit e2dbdcf

File tree

2 files changed

+75
-20
lines changed

2 files changed

+75
-20
lines changed

Assets/HoloToolkit/SpatialMapping/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ Generates and retrieves meshes based on spatial mapping data coming from the cur
5858
SpatialMappingManager.cs manages switching between source types and interacting with this class.
5959

6060
#### TapToPlace.cs
61-
Simple script to add to a GameObject that allows users to tap and place the GameObject along the spatial mapping mesh.
61+
Simple extendable script to add to a GameObject that allows users to tap and place the GameObject along the spatial mapping mesh.
62+
63+
TapToPlace also allows the user to specify a parent GameObject to move along with the selected GameObject.
64+
6265
Requires GazeManager, GestureManager, and SpatialMappingManager in the scene.
6366

6467
### [Scripts\RemoteMapping](Scripts/RemoteMapping)

Assets/HoloToolkit/SpatialMapping/Scripts/TapToPlace.cs

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License. See LICENSE in the project root for license information.
33

4+
using System;
45
using HoloToolkit.Unity.InputModule;
56
using UnityEngine;
67

@@ -22,6 +23,18 @@ public class TapToPlace : MonoBehaviour, IInputClickHandler
2223
[Tooltip("Supply a friendly name for the anchor as the key name for the WorldAnchorStore.")]
2324
public string SavedAnchorFriendlyName = "SavedAnchorFriendlyName";
2425

26+
[Tooltip("Place parent on tap instead of current game object.")]
27+
public bool PlaceParentOnTap = false;
28+
29+
[Tooltip("Specify the parent game object to be moved on tap, if the immediate parent is not desired.")]
30+
public GameObject ParentGameObjectToPlace;
31+
32+
/// <summary>
33+
/// Keeps track of if the user is moving the object or not.
34+
/// Setting this to true will enable the user to move and place the object in the scene.
35+
/// </summary>
36+
public bool IsBeingPlaced;
37+
2538
/// <summary>
2639
/// Manages persisted anchors.
2740
/// </summary>
@@ -34,11 +47,12 @@ public class TapToPlace : MonoBehaviour, IInputClickHandler
3447
private SpatialMappingManager spatialMappingManager;
3548

3649
/// <summary>
37-
/// Keeps track of if the user is moving the object or not.
50+
/// Keeps track of the relative position between the parent object to be moved and
51+
/// the current gameobject this script is attached to.
3852
/// </summary>
39-
private bool placing;
53+
private Vector3 parentPositionRelativeToChild;
4054

41-
private void Start()
55+
public virtual void Start()
4256
{
4357
// Make sure we have all the components in the scene we need.
4458
anchorManager = WorldAnchorManager.Instance;
@@ -62,46 +76,67 @@ private void Start()
6276
// If we don't have what we need to proceed, we may as well remove ourselves.
6377
Destroy(this);
6478
}
79+
80+
if (PlaceParentOnTap)
81+
{
82+
if (ParentGameObjectToPlace != null && !gameObject.transform.IsChildOf(ParentGameObjectToPlace.transform))
83+
{
84+
Debug.LogError("The specified parent object is not a parent of this object.");
85+
}
86+
87+
DetermineParent();
88+
89+
parentPositionRelativeToChild = gameObject.transform.position - ParentGameObjectToPlace.transform.position;
90+
}
6591
}
6692

67-
private void Update()
93+
public virtual void Update()
6894
{
6995
// If the user is in placing mode,
7096
// update the placement to match the user's gaze.
71-
if (placing)
97+
if (IsBeingPlaced)
7298
{
99+
if (gameObject.GetComponent<TapToPlace>().IsBeingPlaced) { }
73100
// Do a raycast into the world that will only hit the Spatial Mapping mesh.
74-
var headPosition = Camera.main.transform.position;
75-
var gazeDirection = Camera.main.transform.forward;
101+
Vector3 headPosition = Camera.main.transform.position;
102+
Vector3 gazeDirection = Camera.main.transform.forward;
76103

77104
RaycastHit hitInfo;
78-
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,
79-
30.0f, spatialMappingManager.LayerMask))
105+
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo, 30.0f, spatialMappingManager.LayerMask))
80106
{
107+
// Rotate this object to face the user.
108+
Quaternion toQuat = Camera.main.transform.localRotation;
109+
toQuat.x = 0;
110+
toQuat.z = 0;
111+
81112
// Move this object to where the raycast
82113
// hit the Spatial Mapping mesh.
83114
// Here is where you might consider adding intelligence
84115
// to how the object is placed. For example, consider
85116
// placing based on the bottom of the object's
86117
// collider so it sits properly on surfaces.
87-
this.transform.position = hitInfo.point;
88-
89-
// Rotate this object to face the user.
90-
Quaternion toQuat = Camera.main.transform.localRotation;
91-
toQuat.x = 0;
92-
toQuat.z = 0;
93-
this.transform.rotation = toQuat;
118+
if (PlaceParentOnTap)
119+
{
120+
// Place the parent object as well but keep the focus on the current game object
121+
ParentGameObjectToPlace.transform.position = hitInfo.point - parentPositionRelativeToChild;
122+
ParentGameObjectToPlace.transform.rotation = toQuat;
123+
}
124+
else
125+
{
126+
gameObject.transform.position = hitInfo.point;
127+
gameObject.transform.rotation = toQuat;
128+
}
94129
}
95130
}
96131
}
97132

98-
public void OnInputClicked(InputEventData eventData)
133+
public virtual void OnInputClicked(InputEventData eventData)
99134
{
100135
// On each tap gesture, toggle whether the user is in placing mode.
101-
placing = !placing;
136+
IsBeingPlaced = !IsBeingPlaced;
102137

103138
// If the user is in placing mode, display the spatial mapping mesh.
104-
if (placing)
139+
if (IsBeingPlaced)
105140
{
106141
spatialMappingManager.DrawVisualMeshes = true;
107142

@@ -117,5 +152,22 @@ public void OnInputClicked(InputEventData eventData)
117152
anchorManager.AttachAnchor(gameObject, SavedAnchorFriendlyName);
118153
}
119154
}
155+
156+
private void DetermineParent()
157+
{
158+
if (ParentGameObjectToPlace == null)
159+
{
160+
if (gameObject.transform.parent == null)
161+
{
162+
Debug.LogError("The selected GameObject has no parent.");
163+
PlaceParentOnTap = false;
164+
}
165+
else
166+
{
167+
Debug.LogError("No parent specified. Using immediate parent instead: " + gameObject.transform.parent.gameObject.name);
168+
ParentGameObjectToPlace = gameObject.transform.parent.gameObject;
169+
}
170+
}
171+
}
120172
}
121173
}

0 commit comments

Comments
 (0)