I’m trying to determine if an object is present in a physics linecast. My debugging has led me to this situation where I print the ID of the object I am looking for and its coordinates, and the ID of the object in my linecast results.
The green line shows my LineCast. The bottom three lines of the console show:
I’m looking for “rock”, ID “-40976” at position (51.7, 33.9, 0.0)
My linecast has hit one collider, “rock”, ID “-40958” at position (51.7, 33.9, 0.0)
A comparison of the two transforms is false - the object is not found.
As you can see, there’s only one rock at that position, and only one ‘rock’ Transform in the game object. The target I’m looking for determined by using a circle test:
So the physics OverlapCircle test found Rock ID -40976, set it as the target, then a subsequent linecast found a rock at the same place but Unity considers it’s a different object.
The instance ID is unique for every UnityEngine.Object. A GameObject, a Transform and a Collider are all different objects, they’re just connected. So if you’re comparing either the instanceID or doing and == (which compares instanceID under the hood), make sure that you’re comparing the same thing.
public static bool LineTestForObject(Transform target, Vector2 startPos, Vector2 endPos, LayerMask layerMask){
// performs a ray test to see if this object is hit
tempInt = Physics2D.LinecastNonAlloc(startPos, endPos, spc_DataCache.phys2Drays, layerMask);
print("LineTestForObject "+target.name+" "+target.GetInstanceID()+" position "+target.position);
spc_DataCache.ListRays(tempInt);
for(int n = 0; n < tempInt; n++){
if(spc_DataCache.phys2Drays[n].transform == target){
return true;
}
}
return false;
}
public static void ListRays(int count){
string s = "colliders (count = "+count+") : ";
for(int n = 0; n < count; n++){
s += phys2Drays[n].collider.name+" "+phys2Drays[n].transform.GetInstanceID()+" position "+phys2Drays[n].transform.position+ ", ";
}
print(s);
}
Of the other rocks, none are close. They’d have to be overlapping to share the same coordinates. The ray test also only records one rock, not two.
The transform of the hit object and the target have a different instanceID, and they return false for ==. This means one of two things:
1: You have triggered some weird bug where objects change instance ID arbitrarilly
2: There’s two different objects at the exact same position.
The easiest way to check for 2 is to add the context argument to your Debugs:
Debug.Log("LineTestForObject "+target.name+" "+target.GetInstanceID()+" position "+target.position, target);
That will make it so when you click the debug message in the console, the corresponding object will get pinged in the hierarchy. If you create such a log call for both the target and the hit object, you can check if they’re different things.
Thanks for that. Context reveals that the different transform value is for the asteroid object parent.
phys2Drays[n].collider.name returned ‘rock’ but phys2Drays[n].transform referenced its parent. I can reference the rock’s transform directly with phys2Drays[n].collider.transform and get a working equality test.
So, what’s happening here is that whenever you have a Collider that’s a child of a Rigidbody, Unity considers the Rigidbody as the object you’ve collided with. This means that scripts on the rigidbody gets collision messages, and that the rigidbody is returned as the object collided with.
This allows you to use several colliders as a single, large collider, by having them the children of the same rigidbody. It’s also somewhat confusing in instances like this.