- Home /
Is it better to use colliders or a function? (2D game)
I wrote a script which checks to see if a moving object would get hit by a projectile launched from a stationary object based on the velocities, initial positions, and angles of the given objects when the mouse is clicked rather then using 2D colliders and checking for collisions. I was hoping that by doing this the processing would be decreased since it isn't checking frame by frame rather only when the mouse is clicked. I am wonder whether or not this is actually the case. I am planning on making a game which will have many moving objects (anywhere from 1 to 30+) and want it to be able to be run on mobile devices and am not sure how much having many colliders effects processing vs a mathmatical computation.
Code I wrote:
using UnityEngine;
using System.Collections;
public class Meteor : MonoBehaviour {
public float halfSpriteLength;
private float Ax;
private float By;
public float speed = 8;
private float x;
public Rotation rotation;
public float t;
private float tx;
private float ty;
private float X;
private float X1;
private float X2;
private float Xi1;
private float Xi2;
private float Xe1;
private float Xe2;
private Rigidbody2D rigid;
private float Speed;
public float R;
// Use this for initialization
void Start ()
{
rigid = GetComponent<Rigidbody2D> ();
rigid.velocity = transform.right * speed;
Speed = GameObject.Find("Barrel").GetComponent<Rotation>().speed;
rotation = GameObject.Find ("Barrel").GetComponent<Rotation> ();
}
// Update is called once per frame
void Update ()
{
R = rotation.rotZ;
x = rigid.transform.eulerAngles.z;
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Check ();
if (transform.position.x < 0)
{
if (x + 180 < R)
{
if ((R < Xi2 && R > Xe2))
{
Destroy (gameObject, t);
}
}
if (x + 180 > R)
{
if ((rotation.rotZ > Xi2 && rotation.rotZ < Xe2))
{
Destroy (gameObject, t);
}
}
}
if (transform.position.x > 0) {
if (x + 180 > R) {
if ((R < Xi1 && R > Xe1)) {
Destroy (gameObject, t);
}
}
if (x + 180 < R) {
if ((rotation.rotZ > Xi1 && rotation.rotZ < Xe1)) {
Destroy (gameObject, t);
}
}
}
}
}
void Check ()
{
float Ai = transform.position.x;
float Bi = transform.position.y;
float Ci = (-Bi * rigid.velocity.x + Ai * rigid.velocity.y)/Speed;
tx = Mathf.Abs((transform.position.x) / (Speed*Mathf.Cos(R*Mathf.Deg2Rad) - rigid.velocity.x));
ty = Mathf.Abs((transform.position.y) / (Speed*Mathf.Sin(R*Mathf.Deg2Rad) - rigid.velocity.y));
if (ty > tx)
{
t = ty;
}
else
{
t = tx;
}
X1 = Mathf.Rad2Deg*(Mathf.Acos ((-(Bi * Ci) + Mathf.Sqrt ((Mathf.Pow (Ai, 4)) + (Mathf.Pow (Ai, 2) * Mathf.Pow (Bi, 2)) - (Mathf.Pow (Ai, 2) * Mathf.Pow (Ci, 2)))) / (Mathf.Pow (Ai, 2) + Mathf.Pow (Bi, 2))));
X2 = Mathf.Rad2Deg*(Mathf.Acos ((-(Bi * Ci) - Mathf.Sqrt ((Mathf.Pow (Ai, 4)) + (Mathf.Pow (Ai, 2) * Mathf.Pow (Bi, 2)) - (Mathf.Pow (Ai, 2) * Mathf.Pow (Ci, 2)))) / (Mathf.Pow (Ai, 2) + Mathf.Pow (Bi, 2))));
Xi1 = X1 + Mathf.Rad2Deg*(Mathf.Atan2 (halfSpriteLength, (Speed * t)));
Xi2 = X2 - Mathf.Rad2Deg*(Mathf.Atan2 (halfSpriteLength, (Speed * t)));
Xe1 = X1 - Mathf.Rad2Deg*(Mathf.Atan2 (halfSpriteLength, (Speed * t)));
Xe2 = X2 + Mathf.Rad2Deg*(Mathf.Atan2 (halfSpriteLength, (Speed * t)));
}
Input would be apreciated.
Answer by Tourist · Nov 04, 2016 at 08:45 AM
The question is : do you want to do it yourself and how precise should it be?
Since you are doing it only on event, you may do it yourself. But you could also cast a volume (using Physics2D cast methods) and check the result. With this method, your objects must have a collider but you may deactivate the collisions between them.
Answer by tanoshimi · Nov 04, 2016 at 09:11 AM
The only answer to your question is to use the profiler and see. Your logic of performing a calculation only once should of cause yield better performance than checking for collisions every frame. But, in the code above you've still got a rigidbody2d attached to this object, which means the physics simulation is having to run every frame anyway. A circle/box collision check on top of that is very unlikely to make any noticeable difference.
Your bigger problem comes from having 30 dynamic objects - do you really need to check every possible collision between every pair of those objects? (what is that, some 435 combinations?)
I would just have those 30 objects be checking for collisions with the object being launched at them not with eachother. I didn't even think about the fact that the rigidbody2d would have to run every frame. I didn't see a noticable difference when running the script vs collision checks (although I was only using 5 objects) so I might just go with collision checks since it will be a lot easier to code; considering I want multiple projectile types and would have to write similar but varying scripts for each type. Also considering the new code is just
public class Test : $$anonymous$$onoBehaviour {
public float speed = 0.5f;
private Rigidbody2D rigid;
private bool Hit = false;
// Use this for initialization
void Start () {
rigid = GetComponent<Rigidbody2D> ();
rigid.velocity = transform.right * speed;
}
void Update ()
{
if (Hit == true) {
Destroy (gameObject);
}
}
void OnTriggerEnter2D(Collider2D coll)
{
Hit = true;
}
}