hello so im currently in research phase of making a quake like game and i was wondering what is the best way to make a fluid shooting system in unity? like raycast instantiate using rigidbody transform etc for a quake game?
Whichever works is the best way.
Quake uses raycast for pistol and shotgun.
Nailgun has travel time on projectile but those do not have to be rigid bodies, and can e âBetween frame raycastsâ, i.e. scripted.
Grenade Launcher shoots rigidbodies (or quake equivalent of it).
Rocket launcher is a travel time projectile, which could be a rigid body or could be a scripted projectile.
Scripted projectile means it does not have a rigidbody and instead controls its own position through scripting, and also checks collisions by running OVerlap Sphere and/or either Raycast/Spherecast between old position and the new one.
With projectiles I always had problems with fast moving rigidbodies not registering the OnHit callbacks, especially with arrows that you want to freeze and attach to the hit surface when/where it hit, every other one just fly through, even after optimizing the physics settings/layers/interval/etc.
I use a variation of this ancient relic: https://wiki.unity3d.com/index.php/DontGoThroughThings (c# at the bottom) and shoot a short ray while the projectile is flying.
I believe thatâs what continuous dynamic collision detection is for.
https://docs.unity3d.com/Manual/class-Rigidbody.html
Yeah I tried that at the time and it still didnât work, maybe they fixed it in newer versions Iâve used raycasts for years and didnât look back. But as recently as 2018, Iâll mock it up
edit:: can confirm shooting spheres at a sphere with continuous dynamic doesnât register numerous hits in 2021.1.13f1 using rig.AddForce(cameraTrans.forward * 50, ForceMode.Impulse)
Then in OnCollisionEnter on a sphere projectile it simply sets the rigidbody iskinematic and sets its parent to the object hit. About 8 in 10 will register a hit and stick to the target, at faster speeds less register. Also depending on the angle youâre shooting the target it may not register at all with numerous consecutive shots.
Iâll try to make a gif or something when I get back from the store.
You do NOT want to use instantiate.
Whenever you use instantiate you are making a new bullet/projectile.
When you are firing hundreds of times you fill up your ram very fast, which turns on the garbage collector, which gives a massive performance hit.
What you want is an object pool.
Thereâs hundreds of tutorials out there on it, but the gist is you have a list instances of an object.
When you need one you check the list for a disabled one, teleport it there, and turn it on.
If there isnât one free, then you make one.
No matter what, donât buy one from the store. This is one of the easiest scripts to make and you can do it in like 20 minutes.
This is with continuous dynamic in Unity 2021.1, notice it works straight on but at the edges itâs really finicky, like balls either just fly through or get attached to the backside, missing the first collision on the front face. Too finicky for me. Imagine a shooter game that dropped hits depending on the angle you shot from, people would be pissed lol
https://www.youtube.com/watch?v=zcocygUUyVg
Projectile.cs
void Start(){ rig = GetComponent<Rigidbody>(); }
private void OnCollisionEnter(Collision collision)
{
rig.isKinematic = true;
}
So literally the second it touches anything it should freeze immediately, sometimes it works, sometimes it doesnât.
Shoot.cs
void Update()
{
if (Input.GetMouseButtonDown(0))
{
var obj = Instantiate(prefab.gameObject, shootFrom.position, shootFrom.rotation);
obj.GetComponent<Rigidbody>().AddForce(shootFrom.forward * force, ForceMode.Impulse);
}
}
If there are lots of bullets/beams, rockets and traces flying around you can use the particle system as your âgun(s)â. Itâs designed to be very fast and has in built oncollision functions.
Ive heard this but never saw a good tutorial on it.
know of any?
It is literally OnParticleCollision.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnParticleCollision.html
Iâm not aware of any but the documentation isnât too lacking here that itâs impossible to figure it out. Basically you can get the particles with GetParticles(), modify them, and then feed them back in with SetParticles().
https://docs.unity3d.com/ScriptReference/ParticleSystem.GetParticles.html
https://docs.unity3d.com/ScriptReference/ParticleSystem.SetParticles.html
You can retrieve the collider that is being interacted with using GetCollider() and GetColliderCount(), or you can use the method mentioned above by @neginfinity .
https://docs.unity3d.com/ScriptReference/ParticleSystem.ColliderData.GetCollider.html
https://docs.unity3d.com/ScriptReference/ParticleSystem.ColliderData.GetColliderCount.html
If you want a particle to disappear you can set remainingLifetime to 0. If you want them to last forever until youâve manually killed them you can set startLifetime to float.PositiveInfinity.
https://docs.unity3d.com/ScriptReference/ParticleSystem.Particle.html
https://docs.unity3d.com/ScriptReference/ParticleSystem.Particle-remainingLifetime.html
https://docs.unity3d.com/ScriptReference/ParticleSystem.MainModule-startLifetime.html
Wow thanks