1
\$\begingroup\$

I'm developing a top-down shooter with multiple levels (ground for ground units, middle level for buildings, top level for air unity).

The problem is the collision. Though I can make the collider box of a bullet be long enough to reach the ground (and collide with it), the real issue is optical.

When the bullet is fired from a aircraft and collides with some object on the ground (building, ground unit) it will be optically offset due to the perspective camera, because it looks like the shot "by-passed" the target as seen below

top down shooter graphical issue

Is there any way to make the bullets collide perspectively correct? I'm using Unity3d Engine and it offers only simple colliders (box, sphere, cylinder, mesh and wheel), though I don't think a cone-formed collider would solve this issue.

I'd need a (cheap) way to check if it's overlapping a destructible object? I thought of casting a ray from the camera through the bullet and if it hits something destructible, trigger an action, but that's quite punctual and maybe to performance heavy on certain number of bullets

\$\endgroup\$
1
  • \$\begingroup\$ You could try doing collisions in screen space. This way ground objects can be hit as well as flying objetcs without bullet knowing which one you wanted to shoot. \$\endgroup\$ – zzandy Jun 22 '12 at 15:08
1
\$\begingroup\$

I've solved it by putting the projectile collider in a child object and rotate it towards the camera.

Update

It was as simple as dropping this script into the collider for the projectiles. One makes them very long, so they can touch the ground objects.

public class AlignWithCamera : MonoBehaviour {
    private Transform myTransform;
    private Transform cameraTransform;

    public void Update () {
        Align();
    }

    public void OnEnable() {
        Initialize();
        Align();
    }
    public void Initialize() {
        myTransform = transform;
        cameraTransform = Camera.main.transform;
    }

    public void Align() {
        Vector3 direction = cameraTransform.position - myTransform.position;
        myTransform.rotation = Quaternion.FromToRotation(Vector3.up, direction);
    }
}

Some of this isn't necessary anymore, since Unity3D has been optimized a lot in the past 6 years. The myTransform was basically an optimization to avoid calling transform property on every update, but it should be a non-issue by now.

And the reason I did initialize in OnEnable is cause my projectiles were recycled in an object pool, so they are only created once and then put inactive one used or go out of screen and return back to the pool.

\$\endgroup\$
3
  • \$\begingroup\$ i'm new in developing and i have the same problem, can you explain more detailed how you solve this ? \$\endgroup\$ – John Firtz Aug 4 '18 at 14:59
  • \$\begingroup\$ @JohnFirtz If the author does not get back to you, I suggest you create a new question on how to achieve this. You can link this question if it helps. \$\endgroup\$ – Vaillancourt Aug 4 '18 at 15:42
  • \$\begingroup\$ @JohnFirtz: Added the script I used back then, but calculating its rotation toward the camera is actually pretty easy math. Nothing fancy \$\endgroup\$ – Tseng Aug 4 '18 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.