Search Unity

How to store multiple Vector3s inside of a single variable every frame?

Discussion in 'Scripting' started by embodied_computation, Jul 1, 2018.

  1. embodied_computation

    embodied_computation

    Joined:
    Jul 1, 2018
    Posts:
    2
    Hi all.

    I am building an interactive VR experience using the HTC Vive and the SteamVR Unity plugin. My experience involves navigating a space filled with "Sound Spheres" that generate sound when colliding with the Vive controllers. These Sound Spheres are static i.e they sit still in space. I am attempting to write code that triggers haptic feedback when the controllers are held in the vicinity of a Sound Sphere. I am trying to accomplish this using a Vector3.Distance function that compares the location of each controller and Sound Sphere, every frame. When the distance is less than 0.4 units, haptics should be fired in the specific controller that is near a Sound Sphere at that moment in time.

    I am running into issues when I attempt to compare the locations of every GameObject (controllers and Sound Spheres) every frame. How could I create a variable that contains the Vector3.transform.position of every controller, every frame? Concurrently, how could I create a variable that contains the Vector3.transform.position of every Sound Sphere, every frame?

    My pseudo-code solution is here. This code at the moment does not run because I receive the error message "Cannot implicitly convert type 'UnityEngine.Vector3' to 'UnityEngine.Vector3[]'". Am I going in the right direction by trying to create an array of Vector3 values and them comparing them every frame? Or should I be trying a different approach? Your help would be greatly appreciated.

    Code (CSharp):
    1. public class ControllerHaptics : MonoBehaviour {
    2.  
    3.     SteamVR_TrackedObject trackedObject;
    4.     SteamVR_Controller.Device device;
    5.  
    6.     [SerializeField] GameObject[] controllers;
    7.     [SerializeField] GameObject[] soundSpheres;
    8.  
    9.     Vector3[] controllerPositions;
    10.     Vector3[] soundSpherePositions;
    11.  
    12.     float distance;
    13.  
    14.     // Use this for initialization
    15.     void Start()
    16.     {
    17.  
    18.         trackedObject = GetComponent<SteamVR_TrackedObject>();
    19.         device = SteamVR_Controller.Input((int)trackedObject.index);
    20.  
    21.         controllers = GameObject.FindGameObjectsWithTag("Controller"); //VR Controllers
    22.         soundSpheres = GameObject.FindGameObjectsWithTag("Grabbable"); //Sound Spheres
    23.     }
    24.  
    25.     //Update is called once per frame
    26.     void Update()
    27.     {
    28.         GetControllerPositions();
    29.         GetSoundSpherePositions();
    30.         FireHapticsBasedOnDistance();
    31.     }
    32.  
    33.     void GetControllerPositions()
    34.     {
    35.         for (int i = 0; i < controllers.Length; i++)
    36.         {
    37.             controllerPositions = controllers[i].transform.position;
    38.         }
    39.     }
    40.  
    41.     void GetSoundSpherePositions()
    42.     {
    43.         for (int i = 0; i <soundSpheres.Length; i++)
    44.         {
    45.             soundSpherePositions = soundSpheres[i].transform.position;
    46.         }
    47.     }
    48.  
    49.     void FireHapticsBasedOnDistance()
    50.     {
    51.         distance = Vector3.Distance(controllerPositions, soundSpherePositions);
    52.  
    53.         if (distance < 0.4)
    54.         {
    55.             device.TriggerHapticPulse(500);
    56.         }
    57.     }
    58.  
    59. }
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Well 'controllerPositions' is an array. You can't equate an array to the type the array is supposed to hold.

    Instead you should be inserting them into the array. Something like:

    Code (csharp):
    1. controllerPositions[i] = controllers[i].transform.position;
    Note though, arrays are of static length and you must instantiate them at that length first. So in your start function you should probably instantiate the arrays with the length of the appropriate array you'll be getting lengths from. Something like this:

    Code (csharp):
    1. controllerPositions = new Vector3[controllers.Length]
     
  3. embodied_computation

    embodied_computation

    Joined:
    Jul 1, 2018
    Posts:
    2
    Awesome. Thanks for this! Your solution makes sense and I implemented it in my code. However, I now run into a similar error that occurs when I compare the Vector3 positions in order to trigger the haptics:
    Code (CSharp):
    1. void FireHapticsBasedOnDistance()
    2.     {
    3.         distance = Vector3.Distance(controllerPositions, soundSpherePositions);
    4.  
    5.         if (distance < 0.4)
    6.         {
    7.             device.TriggerHapticPulse(500);
    8.         }
    9.     }
    "Argument `#1' cannot convert `UnityEngine.Vector3[]' expression to type `UnityEngine.Vector3'" shows up on both controllerPositions and soundSpherePositions
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    It's still an array. You need to loop over the entries.