[C#] RaycastResult HitPosition

Hi, I’ve been working on a map editor for FiveM and recently started porting stuff to C#.
In the following video you can see me flying around in freecam and showing a crosshair indicating if the ray hit anything (based on RaycastResult.DitHit, which seems to be a misspelling of DidHit?) and if so, where it hit (based on RaycastResult.HitPosition). When I click, the current ray is also drawn on the screen. This is all done in C#, and you can see that the HitPosition is always Vector3(0,0,0) (which is the result when it did NOT hit anything).

To show that it works in Lua, I cast the same ray in Lua on mouseclick, and create a checkpoint at the hitPosition that I get from Lua.

Am I fucking up in C# or is this an actual bug?

Relevant code:
(you can be fairly certain that my forwardVector etc are correct, look at the red line in the video)
C#

ray = World.Raycast(_cam.Position, _cam.Position + (forwardVector * 100f), IntersectOptions.Everything);
if (ray.DitHit)
{
    Utils.DrawText("+", 0.5f, 0.5f, 0, 255, 0); // Crosshairs
    Utils.DrawText("Hit @ "+ray.HitPosition, 0.5f, 0.6f, 0, 255, 0);
}
else
{
    Utils.DrawText("+", 0.5f, 0.5f, 255, 0, 0); // Crosshairs
    Utils.DrawText("No Hit", 0.5f, 0.6f, 255, 0, 0);
}

On click I fire an event to Lua which is handled by:

AddEventHandler('dev:ray', function(fromx, fromy, fromz, tox, toy, toz)
	Citizen.CreateThread(function()
		local rayhandle = CastRayPointToPoint(fromx, fromy, fromz, tox, toy, toz, -1, nil, 0)
		local statusint, hit, endcoords, surfacenormal, entityhandle = GetRaycastResult(rayhandle)
		Citizen.Trace(hit)
		Citizen.Trace(endcoords)
		CreateCheckpoint(1, endcoords.x, endcoords.y, endcoords.z, endcoords.x, endcoords.y, endcoords.z, 5.0, 255,0,0,255,0);
	end)
end)

If anyone could try the same thing in C# and see if they get the same faulty result, I would be grateful :slight_smile:

I don’t know if it can help you, but maybe ? :slight_smile:

public static RaycastResult Raycast(Vector3 source, Vector3 target, IntersectOptions options, Entity ignoreEntity = null)
		{
			return new RaycastResult(Function.Call<int>(Hash._CAST_RAY_POINT_TO_POINT, source.X, source.Y, source.Z, target.X, target.Y, target.Z, options, ignoreEntity == null ? 0 : ignoreEntity.Handle, 7));
		}
public static RaycastResult Raycast(Vector3 source, Vector3 direction, float maxDistance, IntersectOptions options, Entity ignoreEntity = null)
		{
			Vector3 target = source + direction * maxDistance;

			return new RaycastResult(Function.Call<int>(Hash._CAST_RAY_POINT_TO_POINT, source.X, source.Y, source.Z, target.X, target.Y, target.Z, options, ignoreEntity == null ? 0 : ignoreEntity.Handle, 7));
		}
public static RaycastResult RaycastCapsule(Vector3 source, Vector3 target, float radius, IntersectOptions options, Entity ignoreEntity = null)
		{
			return new RaycastResult(Function.Call<int>(Hash.START_SHAPE_TEST_CAPSULE, source.X, source.Y, source.Z, target.X, target.Y, target.Z, radius, options, ignoreEntity == null ? 0 : ignoreEntity.Handle, 7));
		}
public static RaycastResult RaycastCapsule(Vector3 source, Vector3 direction, float maxDistance, float radius, IntersectOptions options, Entity ignoreEntity = null)
		{
			Vector3 target = source + direction * maxDistance;

			return new RaycastResult(Function.Call<int>(Hash.START_SHAPE_TEST_CAPSULE, source.X, source.Y, source.Z, target.X, target.Y, target.Z, radius, options, ignoreEntity == null ? 0 : ignoreEntity.Handle, 7));
		}
public static RaycastResult GetCrosshairCoordinates()
		{
			return Raycast(GameplayCamera.Position, GameplayCamera.GetOffsetPosition(new Vector3(0f, 1000f, 0f)), IntersectOptions.Everything, null);
		}
public static RaycastResult GetCrosshairCoordinates(Entity ignoreEntity)
		{
			return Raycast(GameplayCamera.Position, GameplayCamera.GetOffsetPosition(new Vector3(0f, 1000f, 0f)), IntersectOptions.Everything, ignoreEntity);
		}

Nevermind … I found that ^^’
public bool DitHit { get; private set; } So I suppose this is normal that doesn’t work
You should use an event between your C# and Lua just on this part :slight_smile:

But I don’t want to spam events from Lua to C# with “new raycastresult” 60 times a second :frowning:, I do that now and I don’t like it. Seems inefficient.

Really fixed with https://github.com/citizenfx/fivem/commit/04e034829f75169f11ee33abf67281ecd74728e3
Thank you CFX Collective :slight_smile:

1 Like