-
Notifications
You must be signed in to change notification settings - Fork 51
Description
I've been working on a tracking system for what is currently on the screen by shooting rays from the camera and that all works fine. My aim is to detect whether or not a number of rays are hitting objects and if they do what object they hit.
My code works fine if I only have one ray but it doesn't when I use multiple rays because want to submit the result for each ray as a new row.
I really want to avoid having one tracker for each ray or even a new colum for each ray so I am wondering whether something like this is possible?
The problem with having a colum for each ray is that I wouldn't know how to header etc. Could that be done in for loop?
When I provide more than one ray I get the following error arises form the for loop in GetCurrentValues()
:
InvalidOperationException: The row does not contain values for the same columns as the columns in the table!
Table: time, rayIndex, x, y, objectDetected
Row: rayIndex, x, y, objectDetected, rayIndex, x, y, objectDetected, time
UXF.UXFDataTable.AddCompleteRow (UXF.UXFDataRow newRow) (at Assets/UXF/Scripts/Etc/UXFDataTable.cs:109)
Here is my script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UXF;
public class screenTracker : Tracker {
// Public vars
public Camera cam;
public List<float> x = new List<float>();
public List<float> y = new List<float>();
public int numRays;
public bool showDebugRays = true;
public string noObjectString = "NA";
// Private vars
public List<string> objectDetected = new List<string>();
// // Start calc
// void Start(){
// numRays = y.Count;
// }
// Set up header
protected override void SetupDescriptorAndHeader(){
measurementDescriptor = "objectsOnScreenTracker";
customHeader = new string[]
{
"rayIndex",
"x",
"y",
"objectDetected"
};
}
// Get values
protected override UXFDataRow GetCurrentValues(){
objectDetected = ray2detectObjects(x, y, cam);
var values = new UXFDataRow();
// Write rows in a loop
for(int i = 0; i < numRays; i++){
values.Add(("rayIndex", i));
values.Add(("x", x[i]));
values.Add(("y", y[i]));
values.Add(("objectDetected", objectDetected[i]));
}
return values;
}
// Function to detect objects on screen by rays
List<string> ray2detectObjects(List<float> x, List<float> y, Camera cam){
// Get number of rays
numRays = y.Count;
// Create var
List<string> nameOfObjects = new List<string>();
List<Ray> rays = new List<Ray>();
for (int i = 0; i < numRays; i++){
// Cast the ray and add to list
Ray ray = cam.ViewportPointToRay(new Vector3(x[i], y[i], 0));
rays.Add (ray);
if(showDebugRays){
Debug.DrawRay(rays[i].origin, rays[i].direction * 50, Color.red);
}
RaycastHit hit1;
if (Physics.Raycast(rays[i], out hit1)){
if(showDebugRays){
Debug.DrawRay(rays[i].origin, rays[i].direction * 50, Color.green);
}
print("I'm looking at " + hit1.transform.name + " with ray " + i);
nameOfObjects.Add(hit1.transform.name);
} else {
nameOfObjects.Add(noObjectString);
}
}
return nameOfObjects;
}
}