- Home /
Comparing tags stored in array with the tag of GameObject (Raycasting)
Hey guys am creating an array which is used for storing the tags of all the elements that are currently present on the screen.This array is of string type.Now i want to compare this with the tag of gameobject that is being touched.Am able to save the tags in one script,access it in other script.So just want to know how to compare.Here is the code snipet of what i have done so far..This is the first Script TestScriptJavaScript
.The if loop is written in the Update()
.
var tagsarray=new Array(String);
if (Input.GetMouseButtonDown(0))
{
var ray:Ray;
var raycast:RaycastHit;
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, raycast))
{
switch( raycast.collider.name)
{
case "Element_Plane1":
count++;
var elementpos=FirstElement.transform.position;
elementpos.z=elementpos.z-2.0f;
elementpos.y=elementpos.y-15.0f;
elementpos.x=elementpos.x-11.0f;
//FirstElement.renderer.enabled=false;
var go:GameObject;
go = Instantiate(Resources.Load("Sphere_Element"),elementpos,Quaternion.identity);
go.AddComponent("Touchtestscript");
go.tag="sphere1";
testtext.GetComponent(TextMesh).text = go.tag;
tagsarray.Add("sphere1");
print ("Sphere 1 tag ::: "+go.tag);
break;
case "Element_Plane2":
count++;
var elementpos1=FirstElement.transform.position;
elementpos1.z=elementpos1.z-2.0f;
elementpos1.y=elementpos1.y-15.0f;
elementpos1.x=elementpos1.x-2.0f;
//SecondElement.renderer.enabled=false;
var go1:GameObject;
go1 = Instantiate(Resources.Load("Sphere_Element"),elementpos,Quaternion.identity);
go1.AddComponent("Touchtestscript");
go1.tag="sphere2";
testtext.GetComponent(TextMesh).text = go1.tag;
print ("Sphere 2 tag ::: "+go1.tag);
tagsarray.Add("sphere2");
break;
case "Element_Plane3":
count++;
var elementpos2=FirstElement.transform.position;
elementpos2.z=elementpos2.z-2.0f;
elementpos2.y=elementpos2.y-15.0f;
elementpos2.x=elementpos2.x+10.0f;
//FirstElement.renderer.enabled=false;
var go2:GameObject;
go2 = Instantiate(Resources.Load("Sphere_Element"),elementpos,Quaternion.identity);
go2.AddComponent("Touchtestscript");
go2.tag="sphere3";
testtext.GetComponent(TextMesh).text = go2.tag;
print ("Sphere 3 tag ::: "+go2.tag);
tagsarray.Add("sphere3");
break;
}
}
}
Now the other script where i am accessing this array is Touchtestscript
.And the code in this script is as below.
var testscript:TestScriptJavaScript;
function Start()
{
testscript=FindObjectOfType(typeof(TestScriptJavaScript));
}
function Update ()
{
var length=testscript.tagsarray.length;
print(length);
var tags;
for (var touch : Touch in Input.touches)
{
var ray:Ray;
var raycast:RaycastHit;
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, raycast))
{
for(tags in testscript.tagsarray)
{
print("whooaaaa inside found");
if(raycast.collider.tag.Equals(tags))
{
print("whooaaaa inside found");
}
}
} }
So how to do it.Where i am mistaking. Using this code it is not getting in the for loop at all. Not printing the statement.
Can you please explain what you are trying to do? One scriptchecks mouse inout, the other touches. Not clear at all!
The first script has some elements on top,on click of which i instantiate the gameobjects and add the script to it.I used Input.Get$$anonymous$$ouseButtonDown(0))
because i just want to get the touch. And this work fine in android devices.So carried on with it.Now the gameobjects that are created i want to drag them on mobile devices so i used Input.Touches
.I have achieved drag.But need to check tag for something.Hope the use of Input.Get$$anonymous$$ouseButtonDown(0))
and Input.touches
are clear.
Answer by gregzo · Jul 31, 2013 at 07:53 AM
Hi sanks,
Your whole approach is a bit off. 1) Adding the touch script to every sphere is wrong. You should have one script that manages touches, and sends messages to GameObjects ( or directly calls methods on scripts).
2) I strongly advise you to use List and not Array. Lists are faster, and Array is not supported on iOS. List needs System.Collections.Generic.
3) If every sphere prefab has it's own tag, you can just check against the tags without referencing them when instantiating.
4) Why load your prefabs from resources? It is much slower than assigning a prefab to a public GameObject in the inspector.
Thanks for your reply.. I am new to unity so using my limited knowledge.I would like you bring it to your notice what i am actually trying to do.I have few Planes on top of the screen. Which when touched will instantiate sphere prefabs,which could be drag.Next when there are more than 1 sphere on the screen if user touches one by one on two spheres then the two spheres should be joined.The joining part is somewhat done with the help of one of the question asked earlier.Now in regards to you answer.I will try and say what i am doing in terms of point you said.
How to do the first part.. The issue which is generally faced by me is where to assign the scripts.To the prefab or each individual game object.Do you mean i should assign the script to the prefab.
You mean just the one mentioned here.
Didn't got your third point.Hope after reading about what i am trying to do you will be able to elaborate.
I do it because want to load the already created prefabs and not create them at run time and tried finding solutions for it but most of them suggested to load it from resources.
hey done with the question.. I just changed the array defination in the first script from var tagsarray=new Array(String);
to var tagsarray=new String[20];
and accordingly tweaked assigning of values to element of array to : tagsarray[count]="sphere1";
Here is a short example of using Lists and public variables assigned in the inspector. It does the same as your first script.
import System.Collections.Generic; //needed for lists
public var planeColliders : List.<Collider>; //here, drag and drop your "Element_plane" objects ( all 3 ) in the inspector.
public var sphereTags : List.<String>; //here, in the inspector you can set it to 3 elements, "sphere1","sphere2" and "sphere3".
public var spherePrefab : GameObject; //drag and drop your prefab in the inspector
//Now when you raycast, nothing is hardcoded :
function Update()
{
if (Input.Get$$anonymous$$ouseButtonDown(0))
{
var ray:Ray;
var hit:RaycastHit;
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, hit))
{
var planeIndex : int = planeColliders.IndexOf ( hit.collider ); // List is practical : it has methods such as Contains and IndexOf. If hit.collider is not found in planeColliders, planeIndex will be -1
if ( planeIndex!= -1 ) // we found an index : we hit one of the planes.
{
var go : GameObject = Instantiate ( spherePrefab ); //no need for Resources.Load
go.tag = sphereTags [ planeIndex ]; //you need to have matching tags and colliders lists in the inspector!
}
}
}
}
Just one more question what if the number of gameobjects are unknown.as is the case for planeColliders.It may not be fixed,then how to go about it using the method u suggested.And as per the link i mentioned regarding the arrays (the second point) it says using InBuilt arrays are advisable.As they are faster and are supported by iPhone as well ..
Hi Sanks, If your number of planeColliders can vary, you could reference them in a static List. Let's say each planeCollider has the following PlaneCollider script attached to it :
private static var planeColliders : List.<PlaneCollider>;
public String sphereTag; // each PlaneCollider references a
function Awake () //Every time you instantiate a new PlaneCollider, it will add itself to the class's static List
{
if ( planeColliders = null ) //$$anonymous$$ake sure the List is created
planeColliders = new List.<PlaneCollider>(3);
planeColliders.Add ( this ); // Add self
}
public static function GetSphereTag ( Collider col ) : String
{
if ( planeColliders == null )
return null;
var planeIndex : int = -1;
for ( var i : int = 0; i < planeColliders.Length; i++ )
{
if ( planeColliders[i].collider == col )
{
planeIndex = i;
break;
}
}
if ( i == -1 )
return null;
return planeColliders[i].sphereTag;
}
$$anonymous$$y JS might be a bit rusty, but that's a general idea. Then, when you raycast, you can get the tag if the object hit has a PlaneCollider script :
public var sphereTag : String = PlaneCollider.GetSphereTag ( hit.collider ); //a class's static functions can be called from anywhere
if ( sphereTag != null )
{
//Instantiate sphere prefab and tag it with sphereTag
}