Search Unity

Resolved Transform.Rotate() doesn't seems to work in editor

Discussion in 'Scripting' started by Draad, May 15, 2023.

  1. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Hello,

    I have an EditorWindow that create a PreviewScene, and use
    EditorSceneManager.MoveGameObjectToScene to move in it a new Camera and an empty GameObject that server as container.

    Then, I create a few cubes and add them as children to the container.

    Now, I listen for the Key R to be pressed, and try to apply container.transform.Rotate(new Vector3(0, 90, 0)); but it seems like it does not rotate my object. I am missing something ?

    This is some sample code :

    Code (CSharp):
    1.  
    2.     void AddGameObjectToScene(GameObject o)
    3.     {
    4.       EditorSceneManager.MoveGameObjectToScene(o, scene);
    5.     }
    6.  
    7.     void AddGameObjectToMainContainer(GameObject o)
    8.     {
    9.       o.transform.parent = container.transform;
    10.     }
    11.  
    12.     void Init()
    13.     {
    14.         scene = EditorSceneManager.NewPreviewScene();
    15.  
    16.         container = new GameObject();
    17.         AddGameObjectToScene(container);
    18.  
    19.         camera = new GameObject().AddComponent<Camera>();
    20.         camera.scene = scene;
    21.  
    22.         renderTexture = new RenderTexture(1, 1, 24);
    23.         camera.targetTexture = renderTexture;
    24.         AddGameObjectToScene(camera.gameObject);
    25.  
    26.         // That viewerEditor display few cubes
    27.         GameObject e = new GameObject();
    28.         viewerEditor = e.AddComponent<ViewerEditor>();
    29.         AddGameObjectToMainContainer(e);
    30.     }
    31.  
    32.     void OnGUI()
    33.     {
    34.       if (Event.current.type == EventType.Repaint)
    35.         Render();
    36.  
    37.      
    38.       if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.R)
    39.       {
    40.         Debug.Log("Before Rotate " + container.transform.rotation);
    41.         container.transform.Rotate(new Vector3(0, 30, 0));
    42.         Debug.Log("After Rotate " + container.transform.rotation);
    43.         Repaint();
    44.       }
    45.     }
    The console correctly logs "Rotate" when I press R, but the viewerEditor won't be rotated.
    Any clue ?
     
    Last edited: May 15, 2023
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    When you say the cube doesn't rotate, do you mean the values in their transform remain the same, or do you mean visually? Because cubes are pretty much the same when you rotate them by 90 degrees.

    Confirm whether the transform values are changing, and please try some other values so you can double-check with more clarity.
     
  3. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Hello @orionsyndrome

    The 3 cubes draw a rectangle, so I should see them rotating visually. This is a screenshot, I hope it will help you understand :

    Screenshot 2023-05-14 at 10.44.36 PM.png

    The transform.rotation values seems to be updated, but visually it does not change even if I call Repaint(); as explained in my first message
     
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    Yeah but can you visually confirm it in the Transform component? If you don't see that modified, then that's the first part to your answer. You should be able to select that object and see its transform in the inspector.

    Btw those numbers look like your container was already rotated on Y. That's not an absolute 90 degree rotation. It should look like this (0, 0.707, 0, 0.707)
     
  5. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    I can't see the Transform component visually cause objects are added into a PreviewScene, so they do no appear in the inspector ˆˆ
     
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    Ah, ok. Well, in that case, there are two scenarios I can think of:
    1) you're targeting the wrong object,
    2) you need to update and refresh the scene
     
  7. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    You might want to try and print isDirty on the scene itself. See if it's true. edit: nvm you already do Repaint, something's weird.
     
    Last edited: May 15, 2023
  8. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    Man, documentation on this featureset is horrendous. I dunno, I can only advise you to try doing this again but in small steps. Or share some small working code with me, I am willing to try crack this.
     
    Draad likes this.
  9. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,993
    Well, first of all you should never use
    [URL='http://www.google.com/search?q=new+msdn.microsoft.com']new[/URL] GameObject()
    in editor code as it will automatically mark the scene as dirty. When you create helper objects that are only relevant to the editor, you should use EditorUtility.CreateGameObjectWithHideFlags which allows you to specify the hideflags right at the creation of the object.

    Apart from that you said you're rendering inside an EditorWindow. We can see that you correctly create a RenderTexture, but we don't see where and when you actually render your camera and where you show that render texture. Have you actually inspected your RenderTexture to see the current content? You can simply add an ObjectField with your renderTexture reference in it so you can double click the object field to select the texture (or create a button that uses the Selection class to directly select your render texture)

    I never used the preview scene mechanic in Unity. So maybe it has some additional quirks I don't know about :)
     
    Draad and orionsyndrome like this.
  10. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    So, I was creating a repro script for @orionsyndrome and what a surprise... It was actually working correctly in the repro script :eek:

    So I digged into my code, and I finally found the reason why rotation was not applied as I expected ! There was a break in my child tree ! :oops:

    viewerEditor was actually creating another container, and cubes were children of this container, but container was not a child of viewerEditor...

    And to respond @Bunny83 , this is how I do render the scene :

    Code (CSharp):
    1. void Render()
    2.     {
    3.       // Rendering zone
    4.       var rect = position;
    5.       rect.position = Vector2.zero;
    6.  
    7.       // Update render texture if required
    8.       if (rect.width != renderTexture.width || rect.height != renderTexture.height)
    9.       {
    10.         renderTexture.Release();
    11.         renderTexture.width = (int)rect.width;
    12.         renderTexture.height = (int)rect.height;
    13.       }
    14.  
    15.       camera.pixelRect = rect;
    16.       camera.Render();
    17.  
    18.       Graphics.DrawTexture(rect, renderTexture);
    19.     }

    Thanks for your help :)
     
    orionsyndrome and Bunny83 like this.
  11. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    I feel so dumb, every step is a new challenge in this adventure haha.
    When I do rotate my object, the result add up to previous renders. I tried many ways to clear the renderTexture, but I cannot find how.


    Screenshot 2023-05-15 at 5.07.38 PM.png

    This is my camera setup :
    Code (CSharp):
    1.  
    2.         camera = new GameObject().AddComponent<Camera>();
    3.         camera.clearFlags = CameraClearFlags.SolidColor;
    4.         camera.backgroundColor = new Color(0.25f, 0.25f, 0.25f, 1);
    5.         camera.nearClipPlane = 0.3f;
    6.         camera.farClipPlane = 5000f;
    7.         camera.transform.position = new Vector3(-5, 10, -5);
    8.         camera.transform.Rotate(new Vector3(45, 45, 0));
    9.         camera.orthographic = true;
    10.         camera.scene = scene;
    11.  
    12.         renderTexture = new RenderTexture(1, 1, 24);
    13.         camera.targetTexture = renderTexture;
    14.         camera.forceIntoRenderTexture = true;
    15.  
    This is how I render

    Code (CSharp):
    1.    
    2.       // Rendering zone
    3.       var rect = position;
    4.       rect.position = Vector2.zero;
    5.  
    6.       // Update render texture if required
    7.       if (rect.width != renderTexture.width || rect.height != renderTexture.height)
    8.       {
    9.         renderTexture.Release();
    10.         renderTexture.width = (int)rect.width;
    11.         renderTexture.height = (int)rect.height;
    12.       }
    13.  
    14.       camera.pixelRect = rect;
    15.       camera.Render();
    16.  
    17.       Graphics.DrawTexture(rect, renderTexture);
    18.  

    It seems like there is a lot of possible sources for this problem based on my search, but I can't manage to find the one fitting my needs. I don't really understand what's going on in the background when I create draw that texture, thus it's very hard for me to dig for a solution.

    From what I understood, Camera.ClearFalgs should be enough to reset the render on camera side.

    Fun fact, If I do rotate the Camera instead of my object in the scene, then the rendering is fine.
     
    Last edited: May 15, 2023
  12. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    Hm that's odd, can you debug that camera clearFlags, see if it's truly set properly?
    You may also try GL.Clear to force this manually, but it should really work on its own.

    Oh and please make sure that you're not producing actual instances. (GL.Clear would remove this from the list of suspects, if it works.)

    I mean, I can almost bet this is the case because of this
     
    Draad likes this.
  13. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    orionsyndrome likes this.