- Home /
Bullet Management: Possible Without Rigidbody?
What are the correct methods of bullet management for 3d top scrolling shooter like "Raiden", "R-Type", "Gunbird" ? I want to make some lightweight code for bullets, without rigidbody, so the bullet just uses "bullet.transform.position = transform.forward*speed;" it moves forwards until it hits a collider, then the bullet can use "on collision enter" to play a sound. I dont think i need rigidbody, and those things? Is it wrong to make bullets without rigidbody?
I have a spacecraft flying in a straight tube very fast, and if i use physics, it isnt made for very fast bullets, it's more for bouncing cars around. The bullets would take up too much processor, would miss collisions, because they dont need drag, rotation etc?
What is the computationally simple way to detect collider intersections?
Either your bullet or your target needs a Rigidbody to register a collision, and both must have a collider. $$anonymous$$oving objects by directly manipulating the transform teleports them from one position to the next, so there is a chance (which goes up with speed), that some collisions will not register. You can get around this kind of problem using Raycasting, or by directly detecting a collision with something like Physics.OverlapSphere(), but neither can be considered light weight.
One simple solution would be to check with Physics.Raycast or Physics.Spherecast if the bullet will hit the target. Either via a script on the camera that shoots the bullet or directly from the bullet in its forward direction. Be carefull with that seccond option though, make sure you Destroy() bullets that hit objects and bullets that just have been living for to long.
Hi, One of the 2 (potentially) colliding objects must have a rigidbody for collisions callbacks to be triggered. What I use in a similar game is a sphere collider for each bullet and some box/sphere/other colliders plus rigidbody for ships. The important thing is to have physics layers setup for enemy and player's bullets and enemy and player ship so the physics engine can optimize tests (= no need to test player's bullets against enemy bullets, unless you want this to happen in your game, use edit/project settings/physics). You can also freeze rotation and zero gravity if you don't use it.
To not miss collisions due to high speed: try reducing the fixed time interval to 60Hz. You can also use rigidbody.moveposition to ask the physics engine for more accuracy.
Unity's engine is already quite optimized and if a faster/simple way would exist, I guess they would use it. If you want to have your own "high speed proof" collisions detection, you have to test collisions for the object's "movement volume", not only the object's collider. That is, for a sphere, you have to test the capsule volume that represent the volume the sphere will cover when going from point A to B between 2 fixedupdates. I guess that's what rigidbody.moveposition does. This becomes more complicated for box colliders or other colliders. Physics.SphereCast may help to implement this for spheres, this should be enough for high speed bullets against ships.
I would try with unity's engine first before coding my own system. Their system is already in c++ and optimized with space partitioning algorithms like "sweep and prune" and layer masks that you would have to re-implement.
Wow thanks ALOT those are brilliant advice. i found complementary information, it said triggers can work without collision from eric5h5 and to use rigidbody except tick "is kinematic" so it switches off physics and only use transform controls.
found this page with advice about physics settings and timestep and about making collider same width as distance moved between frames: http://answers.unity3d.com/questions/52455/issues-with-continuous-dynamic-collision.html
Answer by Khyrid · Jul 05, 2017 at 01:21 PM
Nobody answered you, but your question is a good one. Often using the rigidbodies in Unity takes precise control away from the developer. You may have already found your answer long ago, but for others like myself that wondered the same thing here is what works.
Set Projectile rigidbody to Is Kinematic in the inspector. This keeps it from being affected by physics but allows trigger collisions.
Set the colliders you intend for the projectile to hit to "Is Trigger"
For the code of shooting the bullet here is a sample of what I used (C#);
public float projSpeed = 12.0f;
void Fire ()
{
// Create the Bullet from the Bullet Prefab
var bullet = (GameObject)Instantiate(
bulletPrefab,
bulletSpawn.position,
bulletSpawn.rotation);
//Ignore collision (Not sure if needed for kinematic)
Physics.IgnoreCollision(bullet.GetComponent<Collider>(), GetComponent<Collider>());
//Set speed of bullet
bullet.GetComponent<Bullet>().bulletSpeed = projSpeed;
// Destroy the bullet after 2 seconds
Destroy(bullet, 2.0f);
}
For the Bullet itself;
public float bulletSpeed = 0.0f;
public Vector3 myDir;
public float speed = 30.0f; //Probably don't need a slerp for this
private Transform target;
void Start()
{
//Find object I want bullets to move towards, in this case it is my
//crosshairs on the screen "CHWave"
Transform nearestT; nearestT = GameObject.Find("CHWave").transform;
target = nearestT;
Vector3 vectorToTarget = target.position - transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);
}
void Update()
{
//Move Projectile
transform.position += transform.right * bulletSpeed*Time.deltaTime;
}
void OnTriggerEnter(Collider other)//void OnCollisionEnter(Collision hit)
{
if (other.gameObject.tag == "PlayerTarget")// || hit.gameObject.tag == "Bullet")
{
// Physics.IgnoreCollision(other.GetComponent<Collider>(), GetComponent<Collider>());
Physics.IgnoreCollision(other.GetComponent<Collider>(), GetComponent<Collider>());
return;
}
var otherObj = other.gameObject;
var health = otherObj.GetComponent<HealthRTS>();
if (health != null)
{
health.TakeDamage(10);
}
Destroy(gameObject);
}
*Note I set $$anonymous$$e to move transform.right because of the way my top down game works. You will probably need transform.forward.
Answer by Ambrose998800 · Jul 05, 2017 at 01:51 PM
I use particles ever since... You can control spread, simulate grain, speed, gravity, bouncing with speed loss, subemitters for splinters, sending message to collider for damage and decals... no spam of bullet-gameobjects while autofiring thousands of rounds. Now visualisation is easy, you can make tracers and much more.
Of course you can grab position and speed of every single particle... script-examples are in the web.
Answer by Vollmondum · Jul 05, 2017 at 02:04 PM
Check if (bullet.position - gun.position) >= (target.position - gun.position). 2. Check if X/Z coordinate of the bullet is inside preset area (which is target.position +/- its radius)
On both true the will be a headshot. Destroy, decrease HP and voilah.