Search code examples
unity-game-enginecollisionraytracing

Unity3D checking collisions without OnCollisionEnter


I'm using gameobjects as bullets in my game, but I probably do it bad. I cast rays from my gun's barrel, instantiate object and move it by Transform.MoveTowards () to a RaycastHit.point. Problem is when I'm shot to an enemy, but it moves before bullet reach it, becauase bullet is floating in air forever. I see two solutions there: I can check if bullet hit someting, but I don't know how because giving hundreds of bullets a script which is done every frame only for OnCollisionEnter is a bad idea. Second way is to changing target position every frame, but I don't know how to save it. How should I do that?

public static List <GameObject> bullets = new List <GameObject> ();
    public static List <Vector3> targets = new List <Vector3> ();

public override void Shot (Vector3 hitPoint) {
for (int i = 0; i < raysNumber; i++) {
            direction = new Vector3 (UnityEngine.Random.Range (-splash, splash), UnityEngine.Random.Range (-splash, splash), 100);
            direction = t_barrel.TransformDirection (direction);
            if (Physics.Raycast (t_barrel.position, direction, out cele[i], 100, layer)) {

                EnemyFPS enemyHealth = cele[i].collider.GetComponent <EnemyFPS> ();
                bullets.Add (MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation) as GameObject);
                targets.Add (cele [i].point);


            }
        }

public override void MoveBullets () {
        if (bullets.Count > 150) {
            bullets.RemoveAt (0);
            targets.RemoveAt (0);
        }
        for (int i = 0; i < bullets.Count; i++) {

            bullets [i].transform.position = Vector3.MoveTowards (bullets [i].transform.position, targets [i] * 10, 1f);
        }

    }

MoveBullets is called every frame.

Edit: Picture with my problem: enter image description here

Bullets:

Vector3 pro;
float speed = 10;

void Start () {
    pro = transform.InverseTransformDirection (transform.forward);
}

void Update () {
    transform.Translate (pro * speed * Time.deltaTime);
}

void OnTriggerEnter (Collider other) {
    Debug.Log ("Collision");
    EnemyFPS enemy = other.gameObject.GetComponent <EnemyFPS> ();
    if (enemy != null) {
        enemy.TakeDamage (5);
        other.gameObject.transform.SetParent (other.transform);
    }
    GetComponent<Collider>().gameObject.GetComponent <Collider> ().enabled = false;
    Destroy (gameObject.GetComponent <BulletS> ());
}

Shoting

t_barrel.LookAt (hitPoint);
MonoBehaviour.Instantiate (g_kubik, t_barrel.position, t_barrel.rotation);

Solution

  • If you follow the Unity3d space shooter tutorial thoroughly I believe all your queries will be solved. Here is the link to it.
    What I understand and what you basically need to do is add a collider to your enemy so that when the bullet touches the enemy, something happens. Like, the enemy dies or is injured and ofcourse the bullet gets destroyed, unless it's a sniper rifle bullet which can sometimes penetrate a skull and kill another enemy behind the first enemy, but that is something more advanced.
    Alternatively, you could limit the number of bullets that can be spawned per frame.