Search code examples
unity-game-enginespritemultiplayer

Rotating a projectile sprite to face an angled camera and the target it is flying at. 2D top down


Results that im getting, and result that I want. Descriptive image.

I know that this question has been asked before not quite in this way, believe me I have been looking all over this forum and unity answers for a solution.

I am making a 2d top down game where monsters can shoot projectile at my character. I have solved that by making it do that they instantiate a projectile prefab from a specific point in their animation at the location of an empty gameobject and it looks fine. I have made the projectile find the player and make it dodgable by aiming at where he was originally and not where he constantly is. so the movement of the projectile at the moment is perfect and im oh so proud of myself!, yes semi new to this. here is the code I used:

    public void OnCastComplete()
{
    var projectile = Instantiate(fireball, projectileInitialLocation.transform.position, transform.rotation);

    projectile.transform.LookAt(currentTarget.transform.position);

    projectile.velocity = projectile.transform.forward * projectileSpeed;

    Vector2 dir = currentTarget.transform.position - projectile.transform.position;
    float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

    projectile.transform.rotation = Quaternion.AngleAxis(angle, Vector2.up);
}

This would also work perfectly If my main camera where not at an angle. The look and feel that I need is that the camera is at an angle to make 3D elements in my game come to life while still have 2d sprites running around. This means that all sprites, including the projectile need to have a script on them to face the camera.

here is that script:

    public Transform target;

void Start () {
    target = GameObject.Find("MainCamera").GetComponent<Transform>();
}

void Update () {

    if (target != null)

        this.transform.rotation = Camera.main.transform.rotation;
}

Now I am confident that these two scripts are the culprits here as I can see one does a bang up job of making sure things face the camera and the other makes sure to rotate the sprite correctly. but they cannot work together. Removing the latter script from the projectile means it sometimes is not visible or rotated at an angle whereby the viewer can hardly notice it. attaching it means its faces the camera, but gives me the result in the picture I posted above.

I cannot get them to play nice with each other and the problem is so specific I am afraid I need to post a question here =(

hope someone can help!

thank you!


Solution

  • Of course I manage to fix this issue 10 minutes after posting the question.

    the way I fixed it was to change the remove the script to face the camera on projectiles. The compensate for it when instantiating a projectile as so:

        public void OnCastComplete()
    {
        var projectile = Instantiate(fireball, projectileInitialLocation.transform.position, transform.rotation);
    
        projectile.transform.LookAt(currentTarget.transform.position);
    
        projectile.velocity = projectile.transform.forward * projectileSpeed;
    
        Vector2 dir = currentTarget.transform.position - projectile.transform.position;
        float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    
        //projectile.transform.rotation = Quaternion.AngleAxis(angle, Vector2.up);
        projectile.transform.rotation = Quaternion.Euler(-25, 0, angle);
    }
    

    the line I have commented out was the previous one, the line under it fixes the issue. Camera is compensated for by adding the -25 on the x and rotating of the sprite is compensated for by adding the "angle" to the z euler angle.

    Hope this helps someone.