Hello,
I am currently trying to make a sphere projectile that is decently sized. Since it is not super small like a bullet it can not do 1 regular raycast or it would only detect collision with the center of the projectile. I have thought of the idea to make multiple raycasts from the edges of the projectile and around the center but that is just too many raycasts and seems very messy and hacky. Is there anyway of making a raycast that raycasts the size of the projectile. If not please do suggest some other method of detecting collision with this projectile if you have any.
Could you think of any other methods I could use instead of having to do 17 raycasts? I have seen games use medium to bigger sized projectiles but doubt they are firing a lot of raycasts.
You could use the Touched event or :GetTouchingParts() ? You don’t need to do 17 raycasts, just around 2 or 3. One in the center, one from the left side, and another from the right.
I am presently working on an RPG game where it is possible for enemies to shoot bullet balls. Honestly we don’t have a very complicated implementation and they’ve been working awesomely so far. Haven’t had a real need to modify them in some time. We do manually handle bullet “physics” though.
When bullets are created, they’re added to a list of all bullets in the game.
Each bullet has a deterministic “direction” in which they are to travel. This direction is determined by the given origin and target points passed in a create function.
Every Heartbeat these bullets are moved forward (relative) slightly. The delta from Heartbeat helps smooth out the movement of the bullets so they don’t look jumpy.
A raycast is performed between the bullet’s new and old positions. Since they’re all short, we allow ourselves some enemies to shoot out a large number of bullets per frame. No problem.
If a Humanoid is found within this raycast, damage is calculated and applied to them.
You don’t need that many raycasts for a single projectile unless your projectile is large and you want more accuracy which in that case you’ll probably want to look towards using Touched. A small to mid size bullet doesn’t need complete edge accuracy and the center of the bullet can still nip most characters enough that a bullet grazing someone’s limb and not dealing damage would be unnoticeable and not really game breaking.
Additionally, if you just want some accuracy anyhow and want to try and hit players with the bullet as much as possible you could predict the player’s movement path and angle the projectile slightly so it approximately reaches the player on contact unless they change directions.
I’m using the same type of method for moving the projectile, where it raycasts between last and current position, using deltaTime, and all of that too, would doing 5 raycasts per Heartbeat be performance costing? I would imagine not but I would like to make sure.
Nope. Raycasts are only expensive when they’re long; if your raycasts are all short then go wild, you can fire off thousands of them every frame with no hit to performance. I do that on a production level game with my NPCs, each one of them has anywhere from 10-200 raycast points to serve as a hitbox.
I know this does not relate to the topic much, but I am interested in how you use raycasts to make hitboxes, I thought they were just parts that detected touching players then applied damage, how does using raycasts to make hitboxes work?
We have this module publicly available as RaycastHitbox. Raycasts do not have dependencies besides vector space in the 3D world so in our case we used attachments as a spatial reference for the origin point and raycast slightly outward from that attachment. The result is being able to raycast over a large area and essentially become a hitbox.
I do not work on RaycastHitbox except minor adjustments every now and again. All the genius behind it is Swordphin, open sourced directly from the game it was originally created for.
Lucky me, you seem to know about this module and I have been trying to understand how it works. One part I do not understand is do they shoot raycasts out from the attachments every Heartbeat or how does that work?
Yeah that’s right. Every frame for all active hitboxes, a raycast is sent out from the attachments. Pretty much the same thing as the bullet example raised above except on a more arbitrary scale.
2 more questions then I will stop bugging you about all of this.
How do you do this method with doing it arbitrarily, would you do something like,
RunService.Heartbeat:Connect(function(delta)
local lastPosition = part.Position
RunService.Heartbeat:Wait()
local currentPos = part.Position
end)
Also however you apply the deltaTime in this situation, I don’t really know how to apply it here.
With shooting raycasts from attachments, do they shoot it forward, or do they do the same thing as the bullet, take the lastPosition and currentPosition then raycast from last to current?
Referring to the bullets, we just have one table created to hold all existing bullets. There’s a single connection to Heartbeat that updates the data for all active bullets in a for loop across the table.
When bullets are created they have some data attached to them (a CFrame constructed from an origin and a target via lookAt) and a speed value that determines their movement speed, usually about how fast they should move per frame (we multiply this value by a constant FPS for a frame of reference, which is 60). The Heartbeat bit takes care of the rest of it.
Regarding applying delta, the speed of the bullet is multiplied by this. It gives us the amount of space that the bullet should travel over for the current frame so that it glides rather than jumps every frame over to the player. Most of these values work in terms of studs.
For the raycasting hitbox stuff, I’m not particularly familiar with the math behind it but the attachment stuff is essentially the same just that operates in world space. The last position of the attachment is recorded as the origin point and then the direction is derived as a subtraction of the last position from the current world point. Enabling debugger mode might help you see why this is the case.
Currently I have it where there is a Heartbeat function for each singular projectile, from what I understand you have 1 heartbeat function moving all projectiles, does this make much of a difference? Also are you using a meta-table or just a regular table?
I don’t think it makes a relatively large difference but you should aim to consolidate as much as possible so you don’t have many connections lying around. This can especially be bad if you don’t manage those connections well and end up with memory leaks. You understand correctly though, we only have one Heartbeat function that is responsible for updating all bullets.