2D: Child Object does not rotate like parent does

Okay, this is a weird question maybe and it is a really simple problem which could probably be solved in other ways really easily, but I googled a lot of questions now and tried many things and I don’t understand what is going on, so the reason I am asking this question is to understand what is happening.

The perspective and the way the game is supposed to control is like the game “Nuclear Throne” for example. I have a parent “Player”, a child “Pistol”. This is all 2D, so these are sprites. I have a script which sets the rotation of the parent (Player) to 180 degrees on the Y axis when the mouse is on the left half of the screen and to 0 degrees when the mouse is on the right half of the screen with the following code:

void Update ()
{
	if(Input.mousePosition.x < camera.pixelWidth/2)
        {
            transform.rotation = Quaternion.Euler(0, 180, 0);
        }
        else
        {
            transform.rotation = Quaternion.Euler(0, 0, 0);
        }
}

This does basically flip the sprite of the player horizontally, so the player sprite looks either left or right.

My Pistol has a script which makes it rotate always towards the mouse with the following code:

void Update() 
{ 
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position); 
Vector3 dir = Input.mousePosition - pos; 
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg; 
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward); 
}

This works. Since the pistol is a parent of the player, it also gets the 180 degree on the Y axis when I move the mouse to the left half of the screen. But even though it shows that the value for Y is 180, the sprite still looks like it isnt 180. When I am in Editor mode and just manually type in the value 180 for Y, I can see what the result would look like.

I think this might be because the one rotation might be overriding the other somehow? But why does it say 180 for Y rotation then? I first thought it is because “transform.rotation = Quaternion.Euler(0, 0, 0)” sets all rotation values of the child (pistol) to 0 0 0, but the other rotation (which happens on the Z axis btw) does still work.

Thanks in advance.

I think the problem is order of execution. You are running two scripts on two gameobjects, both with an Update function. Unity does not care about any order of those. I’m pretty sure that your pistol updates prior to the player. Since it’s childed to it, it will be rotated a second time along with the player.
You have two options:

  • you go into the ProjectSettings → ScriptExecutionOrder and “tell” Unity in which order you want your scripts to be executed
  • (Better approach) Have just one script first rotating the player, THEN rotating the pistol

What I don’t get though is why the pistol even rotates. I thought it’s just attached to the player which looks towards the mouse automatically moving the pistol with him.

EDIT: I made a video to show what this all is about. What you see in the video is the RIGHT way:

okay, after more research I finally did it…

I changed the code for my pistol like this:

void rotateToMousePosition()
    {
        Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 newMousePos;

        if (Input.mousePosition.x < camera.pixelWidth / 2)
        {
            float x = Input.mousePosition.x + (pos.x - Input.mousePosition.x) * 2;
            float y = Input.mousePosition.y + (pos.y - Input.mousePosition.y) * 2;
            newMousePos = new Vector3(x, y, 0);
            Vector3 dir = newMousePos - pos;
            float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
        }
        else
        {
            Vector3 dir = Input.mousePosition - pos;
            float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            transform.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }
    }

The code for the player stays the same.

What I had to do is the following:

-change the localRotation of the pistol instead of the normal rotation (thanks Dave29483!)

-when the mouse is on the left half of the screen, aim at the opposite coordinates of the mouse

float x = Input.mousePosition.x + (pos.x - Input.mousePosition.x) * 2;
float y = Input.mousePosition.y + (pos.y - Input.mousePosition.y) * 2;
newMousePos = new Vector3(x, y, 0);

-when the mouse is on the left half of the screen, rotate by -angle instead of angle

float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg; // Winkel um den rotiert werden muss
transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward); // Rotation  

seems like a ton of work for such a simple problem… but I guess it’s fine.