Just a note m_UV contains the last 2 elements of the barycentricCoordinates. But it should contain the first 2 elements. Seems to be a bug. I don’t know if they are going to fix this as it is an non-public part of this struct. But on the otherhand what is the meaning of having it at all, when it contains wrong data.
With respect of DOTS/Burst/Jobs access to m_UV as a value type would be more than welcome!
That said, I understand the sentiment about being able to access the data of RaycastHit from threads, that should be doable and I’m adding a card to track this work for a future release.
With 2021 changes its finally possible to get collider instance id. But at the same time there’s no way to get actually Collider for that id, since Object.FindObjectFromInstanceID is internal.
Wonder if reinterpreting custom structure of RaycastHit layout to RaycastHit, and then fetching collider property will do the trick. Maybe there’s a simpler way?
Yeah I know. I’ve got a case where results of raycasting comes from two separate sources - customly written trigger interactions, and Physx based queries. They’re gathered into single buffer and processed by systems. Some are managed and they run on main thread, here’s where getting actual collider is required.
I’d like to avoid storing whole RaycastHit struct, since its values aren’t used, and pretty much a waste of memory for this case (and data duplication, such as extra HitPoint, HitNormal, and HitDistance stored). Plus, its user error prone.
But without RaycastHit, there’s no way to fetch collider by instance id.
Then you already had your answer. There’s no avoiding it.
I mean, there’s a special access for things like Transforms (TransformAccess). I guess conceivably it could be done for specific types like Collider/Collider2D but a collider is so much more than a simple Transform so it’d be very limited on what access you’d get. Thinking out loud!
That said, there’s nothing stopping the 2D/3D physics teams from exposing that somehow via the RaycastHit(2D) or Collider(2D) or Rigidbody(2D) types. I’ll ask “around”.
using System.Runtime.InteropServices;
using UnityEngine;
namespace HitsGathering {
/// <summary>
/// Hacked version of RaycastHit, allows to obtain collider by reinterpreting
///
/// RaycastHitHack structure to RaycastHit and obtaining collider via property
/// (since Object.FindObjectFromInstanceID is internal)
///
/// TODO remove once exposed
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct RaycastHitHack {
public Vector3 m_Point;
public Vector3 m_Normal;
public uint m_FaceID;
public float m_Distance;
public Vector2 m_UV;
public int m_Collider;
}
public static class RaycastHitHackExt {
public static Collider GetColliderByInstanceId(this int instanceId) {
RaycastHitHack hack = new RaycastHitHack();
hack.m_Collider = instanceId;
unsafe {
RaycastHit hit = *(RaycastHit*) &hack;
Collider result = hit.collider;
#if DEBUG
if (result != null)
Debug.Assert(instanceId == result.GetInstanceID());
#endif
return result;
}
}
}
}
Assert matches, and it seems to return correct colliders.
If anyone else stumbles upon it, works with 2021 - struct layout may vary based on the version used.
using UnityEngine;
using System.Reflection;
public class TestReflect : MonoBehaviour
{
object[] instanceIDArg = new object[1];
void Start()
{
instanceIDArg[0] = GetInstanceID();
var DoesObjectWithInstanceIDExist = typeof(Object).GetMethod("DoesObjectWithInstanceIDExist", BindingFlags.Static | BindingFlags.NonPublic);
if (DoesObjectWithInstanceIDExist != null)
{
var wasFound = (bool)DoesObjectWithInstanceIDExist.Invoke(null, instanceIDArg);
if (wasFound)
{
Debug.Log("We found the object from its instance ID.");
}
}
var FindObjectFromInstanceID = typeof(Object).GetMethod("FindObjectFromInstanceID", BindingFlags.Static | BindingFlags.NonPublic);
if (FindObjectFromInstanceID != null)
{
var foundObj = FindObjectFromInstanceID.Invoke(null, instanceIDArg);
if (GetType() == foundObj.GetType())
{
Debug.Log("We found the object from its instance ID.");
}
}
}
}
For some reason GetHashCode() in Android builds does not actually resolve to instance id which trips the Assert.
Probably an intended behaviour (GetHashCode() gets patched or smth?) but in any case edited this to GetInstanceId() for safety reasons. Speed in ns does not matter in editor / debug environment anyway.
There is no documentation page for 2021.1 . I always look for stuff this way… Let me tell you why … Because searching for that easy change on the unity ChangeLog page is IMPOSSIBLE. (Please, please, make it easier to find changes related to X… better filters… etc)
Being as you specifically tagged me in I have to tell you that I am not part of the 3D physics team nor would I have any way of implementing what you just asked for.
I have a problem using RaycastCommand on Objects with RidigBodys using Unity 2022.3.27f1.
When the target has a Rigidbody Component there are no Hit entries in the result array. I can reproduce it with a standard 3dCube. When I add a Rigidbody it is not hitting any more, vice versa if i remove the RigidBody it hits again. (took me a while to drill it down to that)
Any suggestions?