How to handle touch selection on Unity3D using LeanTouch free asset?












1















I'm working on an AR app that tracks planes with ARCore and makes me choose from a series of different models that I can then instantiate on the plane. After the model is instatiated on the scene I used the free asset Lean Touch by Carlos Wilkes to interact with it using gestures. Using the scripts from this asset I'm also trying to make a circle appear under the model when it is selected, but while it works perfectly appling components on a cube directly in the scene, I can't make it work when I apply the components via script.



This is my scene. It shows how I set up the components on my cube.



LeanSelectable is a script from the asset that is used to define which objects can be selected. LeanSelectableCircle is my script, it extends LeanSelectableBehavior, an abtract class from the asset specifically made to make handling selectable actions easier. My script finds the circle, child of the cube, and overide the functions OnSelect and OnDeselect of the abstract class. In the method OnSelect it activate the circle, making it visible when the object is selected. In the method OnDeselect it deactivate the circle, hiding it when the object is not selected. As I said this combination of components works fine on the cube in the scene: if I select the cube the circle appears, if I deselect the cube the circle disappears.



This is the abstract class:



public abstract class LeanSelectableBehaviour : MonoBehaviour
{
[System.NonSerialized]
private LeanSelectable selectable;

public LeanSelectable Selectable
{
get
{
if (selectable == null)
{
UpdateSelectable();
}

return selectable;
}
}

protected virtual void OnEnable()
{
UpdateSelectable();

// Hook LeanSelectable events
selectable.OnSelect.AddListener(OnSelect);
selectable.OnSelectUp.AddListener(OnSelectUp);
selectable.OnDeselect.AddListener(OnDeselect);
}

protected virtual void OnDisable()
{
UpdateSelectable();

// Unhook LeanSelectable events
selectable.OnSelect.RemoveListener(OnSelect);
selectable.OnSelectUp.RemoveListener(OnSelectUp);
selectable.OnDeselect.RemoveListener(OnDeselect);
}

// Called when selection begins (finger = the finger that selected this)
protected virtual void OnSelect(LeanFinger finger)
{
}

// Called when the selecting finger goes up (finger = the finger that selected this)
protected virtual void OnSelectUp(LeanFinger finger)
{
}

// Called when this is deselected, if OnSelectUp hasn't been called yet, it will get called first
protected virtual void OnDeselect()
{
}

private void UpdateSelectable()
{
if (selectable == null)
{
selectable = GetComponentInParent<LeanSelectable>();

if (selectable == null)
{
Debug.LogError("This GameObject or one of its parents must have the LeanSelectable component.", this);
}
}
}
}


This is my class:



public class LeanSelectableCircle : LeanSelectableBehaviour
{
GameObject circle;

protected virtual void Awake()
{
circle = this.gameObject.transform.GetChild(1).gameObject;
Debug.Log(circle.ToString());
}

protected override void OnSelect(LeanFinger finger)
{
circle.SetActive(true);
Debug.Log("Oggetto selezionato");
}

protected override void OnDeselect()
{
circle.SetActive(false);
Debug.Log("Oggetto deselezionato");
}
}


Lastly I have an ARController class that handles all AR related stuff, including the placing of the model on the plane (the model is instantiated in another class, but it's not relevant here). After the model is scaled, placed in position and made child of the anchor, it instantiate the circle and set it to false to make it hidden. Then I add all the required components to make the touch gestures work with LeanTouch asset. And then I set the model active.



This is the method that handles this part, and that is called during the Update() function in the ARController.



public void _InteractWithARScene()
{
Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began) // If the player has not touched the screen, we are done with this update.
{
return;
}
_SpawnARObject();
}

public void _SpawnARObject()
{
Touch touch;
touch = Input.GetTouch(0);

TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon | TrackableHitFlags.FeaturePointWithSurfaceNormal; // Raycast against the location the player touched to search for planes.

if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) //Evita di istanziare oggetti se il touch non è sopra un elemento dell'UI
{
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
{
// Use hit pose and camera pose to check if hittest is from the back of the plane, if it is, no need to create the anchor.
if ((hit.Trackable is DetectedPlane) && Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position, hit.Pose.rotation * Vector3.up) < 0)
{
Debug.Log("Hit at back of the current DetectedPlane");
}
else
{
//Choose the Andy model for the Trackable that got hit.
GameObject modelObject = assetBundleSytem.transform.GetChild(0).gameObject;
//GameObject modelObject = GameObject.FindWithTag("NEW");
if (modelObject != null) Debug.Log("Model foud");


//Scale model
GameObject scaledObject = scalingCube.Scale(modelObject);
scaledObject.transform.SetPositionAndRotation(hit.Pose.position, hit.Pose.rotation);
scaledObject.tag = "AR";

// Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
scaledObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);

// Create an anchor to allow ARCore to track the hitpoint as understanding of the physical world evolves.
var anchor = hit.Trackable.CreateAnchor(hit.Pose);

// Make Andy model a child of the anchor.
scaledObject.transform.parent = anchor.transform;

//Instantiate the circle that tells when the object is selected
GameObject circle = Instantiate(selectionCircle, scaledObject.transform, true) as GameObject;
circle.transform.SetPositionAndRotation(scaledObject.transform.position, circle.transform.rotation);
circle.SetActive(false);

//Add a MeshCollider Componet to the object mesh
GameObject modelObjectMesh = scaledObject.transform.GetChild(0).gameObject;
modelObjectMesh.AddComponent<MeshCollider>();

//Implement LeanTouch
scaledObject.AddComponent<LeanSelectable>();
scaledObject.AddComponent<LeanSelectableCircle>();

//Set the object to active
scaledObject.SetActive(true);
}
}
}
}


When it tries to add the component LeanSelectableCircle to the medel, the OnEnable() function of LeanSelectableBehaviour is called and it returns this error:




NullReferenceException: Object reference not set to an instance of an
object Lean.Touch.LeanSelectableBehaviour.OnEnable () (at




Assets/LeanTouch/Examples/Scripts/LeanSelectableBehaviour.cs:29) UnityEngine.GameObject:AddComponent() ARController:_SpawnARObject()
(at Assets/Scripts/ARController.cs:117)
ARController:_InteractWithARScene() (at
Assets/Scripts/ARController.cs:64) ARController:Update() (at
Assets/Scripts/ARController.cs:38)





This is my scene after i placed the model on the plane. It shows all the components on the model.
The odd thing is that if I deactivate the model and then reactivate it in the inspector while the scene is playing, then it works fine!



I can't for the life of me understand what I'm doing wrong, so any help will be appreciated, thanks!



Ps. Please forgive me any imprecision, I'm a beginner programmer and english is not my mothertongue!










share|improve this question



























    1















    I'm working on an AR app that tracks planes with ARCore and makes me choose from a series of different models that I can then instantiate on the plane. After the model is instatiated on the scene I used the free asset Lean Touch by Carlos Wilkes to interact with it using gestures. Using the scripts from this asset I'm also trying to make a circle appear under the model when it is selected, but while it works perfectly appling components on a cube directly in the scene, I can't make it work when I apply the components via script.



    This is my scene. It shows how I set up the components on my cube.



    LeanSelectable is a script from the asset that is used to define which objects can be selected. LeanSelectableCircle is my script, it extends LeanSelectableBehavior, an abtract class from the asset specifically made to make handling selectable actions easier. My script finds the circle, child of the cube, and overide the functions OnSelect and OnDeselect of the abstract class. In the method OnSelect it activate the circle, making it visible when the object is selected. In the method OnDeselect it deactivate the circle, hiding it when the object is not selected. As I said this combination of components works fine on the cube in the scene: if I select the cube the circle appears, if I deselect the cube the circle disappears.



    This is the abstract class:



    public abstract class LeanSelectableBehaviour : MonoBehaviour
    {
    [System.NonSerialized]
    private LeanSelectable selectable;

    public LeanSelectable Selectable
    {
    get
    {
    if (selectable == null)
    {
    UpdateSelectable();
    }

    return selectable;
    }
    }

    protected virtual void OnEnable()
    {
    UpdateSelectable();

    // Hook LeanSelectable events
    selectable.OnSelect.AddListener(OnSelect);
    selectable.OnSelectUp.AddListener(OnSelectUp);
    selectable.OnDeselect.AddListener(OnDeselect);
    }

    protected virtual void OnDisable()
    {
    UpdateSelectable();

    // Unhook LeanSelectable events
    selectable.OnSelect.RemoveListener(OnSelect);
    selectable.OnSelectUp.RemoveListener(OnSelectUp);
    selectable.OnDeselect.RemoveListener(OnDeselect);
    }

    // Called when selection begins (finger = the finger that selected this)
    protected virtual void OnSelect(LeanFinger finger)
    {
    }

    // Called when the selecting finger goes up (finger = the finger that selected this)
    protected virtual void OnSelectUp(LeanFinger finger)
    {
    }

    // Called when this is deselected, if OnSelectUp hasn't been called yet, it will get called first
    protected virtual void OnDeselect()
    {
    }

    private void UpdateSelectable()
    {
    if (selectable == null)
    {
    selectable = GetComponentInParent<LeanSelectable>();

    if (selectable == null)
    {
    Debug.LogError("This GameObject or one of its parents must have the LeanSelectable component.", this);
    }
    }
    }
    }


    This is my class:



    public class LeanSelectableCircle : LeanSelectableBehaviour
    {
    GameObject circle;

    protected virtual void Awake()
    {
    circle = this.gameObject.transform.GetChild(1).gameObject;
    Debug.Log(circle.ToString());
    }

    protected override void OnSelect(LeanFinger finger)
    {
    circle.SetActive(true);
    Debug.Log("Oggetto selezionato");
    }

    protected override void OnDeselect()
    {
    circle.SetActive(false);
    Debug.Log("Oggetto deselezionato");
    }
    }


    Lastly I have an ARController class that handles all AR related stuff, including the placing of the model on the plane (the model is instantiated in another class, but it's not relevant here). After the model is scaled, placed in position and made child of the anchor, it instantiate the circle and set it to false to make it hidden. Then I add all the required components to make the touch gestures work with LeanTouch asset. And then I set the model active.



    This is the method that handles this part, and that is called during the Update() function in the ARController.



    public void _InteractWithARScene()
    {
    Touch touch;
    if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began) // If the player has not touched the screen, we are done with this update.
    {
    return;
    }
    _SpawnARObject();
    }

    public void _SpawnARObject()
    {
    Touch touch;
    touch = Input.GetTouch(0);

    TrackableHit hit;
    TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon | TrackableHitFlags.FeaturePointWithSurfaceNormal; // Raycast against the location the player touched to search for planes.

    if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) //Evita di istanziare oggetti se il touch non è sopra un elemento dell'UI
    {
    if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
    {
    // Use hit pose and camera pose to check if hittest is from the back of the plane, if it is, no need to create the anchor.
    if ((hit.Trackable is DetectedPlane) && Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position, hit.Pose.rotation * Vector3.up) < 0)
    {
    Debug.Log("Hit at back of the current DetectedPlane");
    }
    else
    {
    //Choose the Andy model for the Trackable that got hit.
    GameObject modelObject = assetBundleSytem.transform.GetChild(0).gameObject;
    //GameObject modelObject = GameObject.FindWithTag("NEW");
    if (modelObject != null) Debug.Log("Model foud");


    //Scale model
    GameObject scaledObject = scalingCube.Scale(modelObject);
    scaledObject.transform.SetPositionAndRotation(hit.Pose.position, hit.Pose.rotation);
    scaledObject.tag = "AR";

    // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
    scaledObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);

    // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical world evolves.
    var anchor = hit.Trackable.CreateAnchor(hit.Pose);

    // Make Andy model a child of the anchor.
    scaledObject.transform.parent = anchor.transform;

    //Instantiate the circle that tells when the object is selected
    GameObject circle = Instantiate(selectionCircle, scaledObject.transform, true) as GameObject;
    circle.transform.SetPositionAndRotation(scaledObject.transform.position, circle.transform.rotation);
    circle.SetActive(false);

    //Add a MeshCollider Componet to the object mesh
    GameObject modelObjectMesh = scaledObject.transform.GetChild(0).gameObject;
    modelObjectMesh.AddComponent<MeshCollider>();

    //Implement LeanTouch
    scaledObject.AddComponent<LeanSelectable>();
    scaledObject.AddComponent<LeanSelectableCircle>();

    //Set the object to active
    scaledObject.SetActive(true);
    }
    }
    }
    }


    When it tries to add the component LeanSelectableCircle to the medel, the OnEnable() function of LeanSelectableBehaviour is called and it returns this error:




    NullReferenceException: Object reference not set to an instance of an
    object Lean.Touch.LeanSelectableBehaviour.OnEnable () (at




    Assets/LeanTouch/Examples/Scripts/LeanSelectableBehaviour.cs:29) UnityEngine.GameObject:AddComponent() ARController:_SpawnARObject()
    (at Assets/Scripts/ARController.cs:117)
    ARController:_InteractWithARScene() (at
    Assets/Scripts/ARController.cs:64) ARController:Update() (at
    Assets/Scripts/ARController.cs:38)





    This is my scene after i placed the model on the plane. It shows all the components on the model.
    The odd thing is that if I deactivate the model and then reactivate it in the inspector while the scene is playing, then it works fine!



    I can't for the life of me understand what I'm doing wrong, so any help will be appreciated, thanks!



    Ps. Please forgive me any imprecision, I'm a beginner programmer and english is not my mothertongue!










    share|improve this question

























      1












      1








      1








      I'm working on an AR app that tracks planes with ARCore and makes me choose from a series of different models that I can then instantiate on the plane. After the model is instatiated on the scene I used the free asset Lean Touch by Carlos Wilkes to interact with it using gestures. Using the scripts from this asset I'm also trying to make a circle appear under the model when it is selected, but while it works perfectly appling components on a cube directly in the scene, I can't make it work when I apply the components via script.



      This is my scene. It shows how I set up the components on my cube.



      LeanSelectable is a script from the asset that is used to define which objects can be selected. LeanSelectableCircle is my script, it extends LeanSelectableBehavior, an abtract class from the asset specifically made to make handling selectable actions easier. My script finds the circle, child of the cube, and overide the functions OnSelect and OnDeselect of the abstract class. In the method OnSelect it activate the circle, making it visible when the object is selected. In the method OnDeselect it deactivate the circle, hiding it when the object is not selected. As I said this combination of components works fine on the cube in the scene: if I select the cube the circle appears, if I deselect the cube the circle disappears.



      This is the abstract class:



      public abstract class LeanSelectableBehaviour : MonoBehaviour
      {
      [System.NonSerialized]
      private LeanSelectable selectable;

      public LeanSelectable Selectable
      {
      get
      {
      if (selectable == null)
      {
      UpdateSelectable();
      }

      return selectable;
      }
      }

      protected virtual void OnEnable()
      {
      UpdateSelectable();

      // Hook LeanSelectable events
      selectable.OnSelect.AddListener(OnSelect);
      selectable.OnSelectUp.AddListener(OnSelectUp);
      selectable.OnDeselect.AddListener(OnDeselect);
      }

      protected virtual void OnDisable()
      {
      UpdateSelectable();

      // Unhook LeanSelectable events
      selectable.OnSelect.RemoveListener(OnSelect);
      selectable.OnSelectUp.RemoveListener(OnSelectUp);
      selectable.OnDeselect.RemoveListener(OnDeselect);
      }

      // Called when selection begins (finger = the finger that selected this)
      protected virtual void OnSelect(LeanFinger finger)
      {
      }

      // Called when the selecting finger goes up (finger = the finger that selected this)
      protected virtual void OnSelectUp(LeanFinger finger)
      {
      }

      // Called when this is deselected, if OnSelectUp hasn't been called yet, it will get called first
      protected virtual void OnDeselect()
      {
      }

      private void UpdateSelectable()
      {
      if (selectable == null)
      {
      selectable = GetComponentInParent<LeanSelectable>();

      if (selectable == null)
      {
      Debug.LogError("This GameObject or one of its parents must have the LeanSelectable component.", this);
      }
      }
      }
      }


      This is my class:



      public class LeanSelectableCircle : LeanSelectableBehaviour
      {
      GameObject circle;

      protected virtual void Awake()
      {
      circle = this.gameObject.transform.GetChild(1).gameObject;
      Debug.Log(circle.ToString());
      }

      protected override void OnSelect(LeanFinger finger)
      {
      circle.SetActive(true);
      Debug.Log("Oggetto selezionato");
      }

      protected override void OnDeselect()
      {
      circle.SetActive(false);
      Debug.Log("Oggetto deselezionato");
      }
      }


      Lastly I have an ARController class that handles all AR related stuff, including the placing of the model on the plane (the model is instantiated in another class, but it's not relevant here). After the model is scaled, placed in position and made child of the anchor, it instantiate the circle and set it to false to make it hidden. Then I add all the required components to make the touch gestures work with LeanTouch asset. And then I set the model active.



      This is the method that handles this part, and that is called during the Update() function in the ARController.



      public void _InteractWithARScene()
      {
      Touch touch;
      if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began) // If the player has not touched the screen, we are done with this update.
      {
      return;
      }
      _SpawnARObject();
      }

      public void _SpawnARObject()
      {
      Touch touch;
      touch = Input.GetTouch(0);

      TrackableHit hit;
      TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon | TrackableHitFlags.FeaturePointWithSurfaceNormal; // Raycast against the location the player touched to search for planes.

      if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) //Evita di istanziare oggetti se il touch non è sopra un elemento dell'UI
      {
      if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
      {
      // Use hit pose and camera pose to check if hittest is from the back of the plane, if it is, no need to create the anchor.
      if ((hit.Trackable is DetectedPlane) && Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position, hit.Pose.rotation * Vector3.up) < 0)
      {
      Debug.Log("Hit at back of the current DetectedPlane");
      }
      else
      {
      //Choose the Andy model for the Trackable that got hit.
      GameObject modelObject = assetBundleSytem.transform.GetChild(0).gameObject;
      //GameObject modelObject = GameObject.FindWithTag("NEW");
      if (modelObject != null) Debug.Log("Model foud");


      //Scale model
      GameObject scaledObject = scalingCube.Scale(modelObject);
      scaledObject.transform.SetPositionAndRotation(hit.Pose.position, hit.Pose.rotation);
      scaledObject.tag = "AR";

      // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
      scaledObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);

      // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical world evolves.
      var anchor = hit.Trackable.CreateAnchor(hit.Pose);

      // Make Andy model a child of the anchor.
      scaledObject.transform.parent = anchor.transform;

      //Instantiate the circle that tells when the object is selected
      GameObject circle = Instantiate(selectionCircle, scaledObject.transform, true) as GameObject;
      circle.transform.SetPositionAndRotation(scaledObject.transform.position, circle.transform.rotation);
      circle.SetActive(false);

      //Add a MeshCollider Componet to the object mesh
      GameObject modelObjectMesh = scaledObject.transform.GetChild(0).gameObject;
      modelObjectMesh.AddComponent<MeshCollider>();

      //Implement LeanTouch
      scaledObject.AddComponent<LeanSelectable>();
      scaledObject.AddComponent<LeanSelectableCircle>();

      //Set the object to active
      scaledObject.SetActive(true);
      }
      }
      }
      }


      When it tries to add the component LeanSelectableCircle to the medel, the OnEnable() function of LeanSelectableBehaviour is called and it returns this error:




      NullReferenceException: Object reference not set to an instance of an
      object Lean.Touch.LeanSelectableBehaviour.OnEnable () (at




      Assets/LeanTouch/Examples/Scripts/LeanSelectableBehaviour.cs:29) UnityEngine.GameObject:AddComponent() ARController:_SpawnARObject()
      (at Assets/Scripts/ARController.cs:117)
      ARController:_InteractWithARScene() (at
      Assets/Scripts/ARController.cs:64) ARController:Update() (at
      Assets/Scripts/ARController.cs:38)





      This is my scene after i placed the model on the plane. It shows all the components on the model.
      The odd thing is that if I deactivate the model and then reactivate it in the inspector while the scene is playing, then it works fine!



      I can't for the life of me understand what I'm doing wrong, so any help will be appreciated, thanks!



      Ps. Please forgive me any imprecision, I'm a beginner programmer and english is not my mothertongue!










      share|improve this question














      I'm working on an AR app that tracks planes with ARCore and makes me choose from a series of different models that I can then instantiate on the plane. After the model is instatiated on the scene I used the free asset Lean Touch by Carlos Wilkes to interact with it using gestures. Using the scripts from this asset I'm also trying to make a circle appear under the model when it is selected, but while it works perfectly appling components on a cube directly in the scene, I can't make it work when I apply the components via script.



      This is my scene. It shows how I set up the components on my cube.



      LeanSelectable is a script from the asset that is used to define which objects can be selected. LeanSelectableCircle is my script, it extends LeanSelectableBehavior, an abtract class from the asset specifically made to make handling selectable actions easier. My script finds the circle, child of the cube, and overide the functions OnSelect and OnDeselect of the abstract class. In the method OnSelect it activate the circle, making it visible when the object is selected. In the method OnDeselect it deactivate the circle, hiding it when the object is not selected. As I said this combination of components works fine on the cube in the scene: if I select the cube the circle appears, if I deselect the cube the circle disappears.



      This is the abstract class:



      public abstract class LeanSelectableBehaviour : MonoBehaviour
      {
      [System.NonSerialized]
      private LeanSelectable selectable;

      public LeanSelectable Selectable
      {
      get
      {
      if (selectable == null)
      {
      UpdateSelectable();
      }

      return selectable;
      }
      }

      protected virtual void OnEnable()
      {
      UpdateSelectable();

      // Hook LeanSelectable events
      selectable.OnSelect.AddListener(OnSelect);
      selectable.OnSelectUp.AddListener(OnSelectUp);
      selectable.OnDeselect.AddListener(OnDeselect);
      }

      protected virtual void OnDisable()
      {
      UpdateSelectable();

      // Unhook LeanSelectable events
      selectable.OnSelect.RemoveListener(OnSelect);
      selectable.OnSelectUp.RemoveListener(OnSelectUp);
      selectable.OnDeselect.RemoveListener(OnDeselect);
      }

      // Called when selection begins (finger = the finger that selected this)
      protected virtual void OnSelect(LeanFinger finger)
      {
      }

      // Called when the selecting finger goes up (finger = the finger that selected this)
      protected virtual void OnSelectUp(LeanFinger finger)
      {
      }

      // Called when this is deselected, if OnSelectUp hasn't been called yet, it will get called first
      protected virtual void OnDeselect()
      {
      }

      private void UpdateSelectable()
      {
      if (selectable == null)
      {
      selectable = GetComponentInParent<LeanSelectable>();

      if (selectable == null)
      {
      Debug.LogError("This GameObject or one of its parents must have the LeanSelectable component.", this);
      }
      }
      }
      }


      This is my class:



      public class LeanSelectableCircle : LeanSelectableBehaviour
      {
      GameObject circle;

      protected virtual void Awake()
      {
      circle = this.gameObject.transform.GetChild(1).gameObject;
      Debug.Log(circle.ToString());
      }

      protected override void OnSelect(LeanFinger finger)
      {
      circle.SetActive(true);
      Debug.Log("Oggetto selezionato");
      }

      protected override void OnDeselect()
      {
      circle.SetActive(false);
      Debug.Log("Oggetto deselezionato");
      }
      }


      Lastly I have an ARController class that handles all AR related stuff, including the placing of the model on the plane (the model is instantiated in another class, but it's not relevant here). After the model is scaled, placed in position and made child of the anchor, it instantiate the circle and set it to false to make it hidden. Then I add all the required components to make the touch gestures work with LeanTouch asset. And then I set the model active.



      This is the method that handles this part, and that is called during the Update() function in the ARController.



      public void _InteractWithARScene()
      {
      Touch touch;
      if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began) // If the player has not touched the screen, we are done with this update.
      {
      return;
      }
      _SpawnARObject();
      }

      public void _SpawnARObject()
      {
      Touch touch;
      touch = Input.GetTouch(0);

      TrackableHit hit;
      TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon | TrackableHitFlags.FeaturePointWithSurfaceNormal; // Raycast against the location the player touched to search for planes.

      if (!EventSystem.current.IsPointerOverGameObject(touch.fingerId)) //Evita di istanziare oggetti se il touch non è sopra un elemento dell'UI
      {
      if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
      {
      // Use hit pose and camera pose to check if hittest is from the back of the plane, if it is, no need to create the anchor.
      if ((hit.Trackable is DetectedPlane) && Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position, hit.Pose.rotation * Vector3.up) < 0)
      {
      Debug.Log("Hit at back of the current DetectedPlane");
      }
      else
      {
      //Choose the Andy model for the Trackable that got hit.
      GameObject modelObject = assetBundleSytem.transform.GetChild(0).gameObject;
      //GameObject modelObject = GameObject.FindWithTag("NEW");
      if (modelObject != null) Debug.Log("Model foud");


      //Scale model
      GameObject scaledObject = scalingCube.Scale(modelObject);
      scaledObject.transform.SetPositionAndRotation(hit.Pose.position, hit.Pose.rotation);
      scaledObject.tag = "AR";

      // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
      scaledObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);

      // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical world evolves.
      var anchor = hit.Trackable.CreateAnchor(hit.Pose);

      // Make Andy model a child of the anchor.
      scaledObject.transform.parent = anchor.transform;

      //Instantiate the circle that tells when the object is selected
      GameObject circle = Instantiate(selectionCircle, scaledObject.transform, true) as GameObject;
      circle.transform.SetPositionAndRotation(scaledObject.transform.position, circle.transform.rotation);
      circle.SetActive(false);

      //Add a MeshCollider Componet to the object mesh
      GameObject modelObjectMesh = scaledObject.transform.GetChild(0).gameObject;
      modelObjectMesh.AddComponent<MeshCollider>();

      //Implement LeanTouch
      scaledObject.AddComponent<LeanSelectable>();
      scaledObject.AddComponent<LeanSelectableCircle>();

      //Set the object to active
      scaledObject.SetActive(true);
      }
      }
      }
      }


      When it tries to add the component LeanSelectableCircle to the medel, the OnEnable() function of LeanSelectableBehaviour is called and it returns this error:




      NullReferenceException: Object reference not set to an instance of an
      object Lean.Touch.LeanSelectableBehaviour.OnEnable () (at




      Assets/LeanTouch/Examples/Scripts/LeanSelectableBehaviour.cs:29) UnityEngine.GameObject:AddComponent() ARController:_SpawnARObject()
      (at Assets/Scripts/ARController.cs:117)
      ARController:_InteractWithARScene() (at
      Assets/Scripts/ARController.cs:64) ARController:Update() (at
      Assets/Scripts/ARController.cs:38)





      This is my scene after i placed the model on the plane. It shows all the components on the model.
      The odd thing is that if I deactivate the model and then reactivate it in the inspector while the scene is playing, then it works fine!



      I can't for the life of me understand what I'm doing wrong, so any help will be appreciated, thanks!



      Ps. Please forgive me any imprecision, I'm a beginner programmer and english is not my mothertongue!







      c# unity3d arcore






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 11:00









      tinatotty91tinatotty91

      61




      61
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53279556%2fhow-to-handle-touch-selection-on-unity3d-using-leantouch-free-asset%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53279556%2fhow-to-handle-touch-selection-on-unity3d-using-leantouch-free-asset%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Full-time equivalent

          さくらももこ

          13 indicted, 8 arrested in Calif. drug cartel investigation