Search Unity

Question Setting "Pawn" position and scale on an instantiated AR plane. Please help.

Discussion in 'AR' started by unity_45BF252F0D401B5C4B2D, Oct 31, 2022.

  1. unity_45BF252F0D401B5C4B2D

    unity_45BF252F0D401B5C4B2D

    Joined:
    Oct 30, 2022
    Posts:
    1
    Hi, I am currently new and learning the AR Foundation kit. Currently, I am in the process of converting a normal game into AR.
    In this project I have=
    - A Plane that instantiates a Pawn gameobject on click based on the click position
    - A Pawn gameobject that is included as a public GameObject in the Plane spawn script.

    The plane gets instantiated by ARPlaneManager, everything works great until I instantiated the "pawn" game object on the plane that is part of the plane prefab but didnt scale to size with the Plane prefab. The pawn also spawns right in front of the ar camera instead of the field. What do I change to make the public GameObjects in the prefab follow the same scale and position as the AR spawned plane?


    This is the script for spawning the initial plane:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.XR.ARFoundation;
    5. using UnityEngine.XR.ARSubsystems;
    6.  
    7. [RequireComponent(typeof(ARRaycastManager))]
    8. public class ARTapToPlace : MonoBehaviour
    9. {
    10.  
    11.     public GameObject gameObjectToInstantiate;
    12.  
    13.     private GameObject spawnedObject;
    14.     private ARRaycastManager _arRaycastManager;
    15.     private Vector2 touchPosition;
    16.     private ARPlaneManager _arPlaneManager;
    17.  
    18.     [SerializeField]
    19.     Camera arCamera;
    20.  
    21.     private bool object_spawned = false;
    22.     Vector2 first_touch;
    23.     Vector2 second_touch;
    24.     float distance_current;
    25.     float distance_prev;
    26.     bool first_pinch = true;
    27.  
    28.     static List<ARRaycastHit> hits = new List<ARRaycastHit>();
    29.  
    30.     private void Awake()
    31.     {
    32.         _arRaycastManager = GetComponent<ARRaycastManager>();
    33.         _arPlaneManager = GetComponent<ARPlaneManager>();
    34.     }
    35.  
    36.     bool TryGetTouchPosition(out Vector2 touchPosition) {
    37.         if(Input.touchCount > 0)
    38.         {
    39.             touchPosition = Input.GetTouch(0).position;
    40.             return true;
    41.         }
    42.  
    43.         touchPosition = default;
    44.         return false;
    45.     }
    46.  
    47.     public void TogglePlaneDetection()
    48.     {
    49.         _arPlaneManager.enabled = !_arPlaneManager.enabled;
    50.  
    51.         if (_arPlaneManager.enabled)
    52.         {
    53.             SetAllPlanesActive(true);
    54.         }
    55.         else
    56.         {
    57.             SetAllPlanesActive(false);
    58.         }
    59.     }
    60.     private void SetAllPlanesActive(bool value)
    61.     {
    62.         foreach(var plane in _arPlaneManager.trackables)
    63.         {
    64.             plane.gameObject.SetActive(value);
    65.         }
    66.     }
    67.  
    68.     void Update()
    69.     {
    70.         if (!TryGetTouchPosition(out Vector2 touchPosition))
    71.             return;
    72.  
    73.         if (_arRaycastManager.Raycast(touchPosition, hits, TrackableType.PlaneWithinPolygon))
    74.         {
    75.             var hitPose = hits[0].pose;
    76.  
    77.             if(spawnedObject == null)
    78.             {
    79.                 spawnedObject = Instantiate(gameObjectToInstantiate, hitPose.position, hitPose.rotation);
    80.                 object_spawned = true;
    81.                 TogglePlaneDetection();
    82.             }
    83.             else
    84.             {
    85.                 // What to do when there is Game Object
    86.  
    87.                 //Move gameobject elsewhere
    88.                 //spawnedObject.transform.position = hitPose.position;
    89.  
    90.                 Ray ray = arCamera.ScreenPointToRay(Input.GetTouch(0).position);
    91.  
    92.                 //_arPlaneManager.enabled = false;
    93.  
    94.                 gameObject.GetComponent<SpawnOnClick>().SpawnPlayer(gameObject.transform.GetChild(1).gameObject, gameObject.transform.GetChild(0).gameObject, arCamera, Input.GetTouch(0).position, "AR_MODE");
    95.  
    96.             }
    97.         }
    98.  
    99.         // Resize Object
    100.         if(Input.touchCount>1 && object_spawned)
    101.         {
    102.             first_touch = Input.GetTouch(0).position;
    103.             second_touch = Input.GetTouch(1).position;
    104.             distance_current = second_touch.magnitude - first_touch.magnitude;
    105.             if (first_pinch)
    106.             {
    107.                 distance_prev = distance_current;
    108.                 first_pinch = false;
    109.             }
    110.             if (distance_current != distance_prev)
    111.             {
    112.                 Vector3 scale_value = spawnedObject.transform.localScale * (distance_current / distance_prev);
    113.                 spawnedObject.transform.localScale = scale_value;
    114.                 distance_prev = distance_current;
    115.             }
    116.         }
    117.     }
    118. }
    119.  

    And this is the script for spawning in the "Pawn" gameobjects on the plane on click based on Raycast.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpawnOnClick : MonoBehaviour
    6. {
    7.  
    8.     Ray myRay;
    9.     RaycastHit hit;
    10.     public GameObject player1Attacking;
    11.     public GameObject player2Defending;
    12.     public GameObject player1Defending;
    13.     public GameObject player2Attacking;
    14.     public bool isAttacking;
    15.  
    16.     // Start is called before the first frame update
    17.     void Start()
    18.     {
    19.         isAttacking = true;
    20.     }
    21.  
    22.     public void SpawnPlayer(GameObject playerFieldAttacking, GameObject playerFieldDefending, Camera rayCamera, Vector3 targetPosition, string gameMode)
    23.     {
    24.         //myRay = Camera.main.ScreenPointToRay(Input.mousePosition);
    25.         myRay = rayCamera.ScreenPointToRay(targetPosition);
    26.         if (Physics.Raycast(myRay, out hit))
    27.         {
    28.             if (hit.collider.name == playerFieldAttacking.name && FieldState.instance.GetLeftFieldState() == "attack")
    29.             {
    30.  
    31.                 if (EnergyP1.instance.UseEnergy(2))
    32.                 {
    33.                     SpawnPlayerOnField( playerFieldAttacking.name, gameMode);
    34.                 }
    35.                 //isAttacking = !isAttacking;
    36.             }
    37.             else if (hit.collider.name == playerFieldDefending.name && FieldState.instance.GetLeftFieldState() == "attack")
    38.             {
    39.                 if (EnergyP2.instance.UseEnergy(3))
    40.                 {
    41.                     SpawnPlayerOnField( playerFieldDefending.name, gameMode);
    42.                 }
    43.                 //isAttacking = !isAttacking;
    44.             }
    45.             else if (hit.collider.name == playerFieldAttacking.name && FieldState.instance.GetLeftFieldState() == "defend")
    46.             {
    47.                 if (EnergyP2.instance.UseEnergy(2))
    48.                 {
    49.                     SpawnPlayerOnField( playerFieldAttacking.name, gameMode);
    50.                 }
    51.                 //isAttacking = !isAttacking;
    52.             }
    53.             else if (hit.collider.name == playerFieldDefending.name && FieldState.instance.GetLeftFieldState() == "defend")
    54.             {
    55.                 if (EnergyP1.instance.UseEnergy(3))
    56.                 {
    57.                     SpawnPlayerOnField( playerFieldDefending.name, gameMode);
    58.                 }
    59.                 //isAttacking = !isAttacking;
    60.             }
    61.         }
    62.     }
    63.  
    64.     public void SpawnPlayerOnField( string fieldClicked, string gameMode)
    65.     {
    66.         GameObject player = player1Attacking;
    67.        
    68.         if (fieldClicked == "Field P2" && FieldState.instance.GetLeftFieldState() == "attack")
    69.         {
    70.             player = player2Defending;
    71.         }
    72.         else if (fieldClicked == "Field P1" && FieldState.instance.GetLeftFieldState() == "defend")
    73.         {
    74.             player = player1Defending;
    75.         }
    76.         else if (fieldClicked == "Field P2" && FieldState.instance.GetLeftFieldState() == "defend")
    77.         {
    78.             player = player2Attacking;
    79.         }
    80.  
    81.         if (gameMode == "AR_MODE")
    82.         {
    83.             player.transform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
    84.         }
    85.  
    86.         Instantiate(player, new Vector3(hit.point.x, 5, hit.point.z), Quaternion.identity);
    87.     }
    88. }
    89.  
    Sample call of the SpawnPlayer on
    Normal mode:
    Code (CSharp):
    1. game.GetComponent<SpawnOnClick>().SpawnPlayer(game.transform.GetChild(0).gameObject, game.transform.GetChild(1).gameObject, Camera.main, Input.mousePosition,"NORMAL_MODE");
    AR mode:
    Code (CSharp):
    1. gameObject.GetComponent<SpawnOnClick>().SpawnPlayer(gameObject.transform.GetChild(1).gameObject, gameObject.transform.GetChild(0).gameObject, arCamera, Input.GetTouch(0).position, "AR_MODE");
    Please help, any form would be appreciated. Thank you in advance.