Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question The texture2D would not update immediately after making changes in edit mode?

Discussion in 'Editor & General Support' started by someonebt, May 22, 2024.

  1. someonebt

    someonebt

    Joined:
    Dec 15, 2023
    Posts:
    9
    I‘m trying to write a custom map edit tool in edit mode,the map is a texture2D which cvoer a mesh.
    When I want to edit the map,I will call this function to change Meshrenderer.sharedMaterial and the manTexture will set as the map which i want to edit.
    Code (CSharp):
    1. public void UpdateDisplayDetailMap(bool isDisplayDetailMap)
    2.     {
    3.  
    4.  
    5.         if (TryGetComponent<MeshRenderer>(out var renderer))
    6.         {
    7.             if (originalMaterial == null)
    8.             {
    9.  
    10.                 originalMaterial = renderer.sharedMaterial;
    11.  
    12.             }
    13.  
    14.             if (displayDetailMapMaterial == null)
    15.             {
    16.                 return;
    17.             }
    18.  
    19.             if (isDisplayDetailMap)
    20.             {
    21.                 //displayDetailMapMaterial.SetTexture("_MainTex", detailMap);
    22.                 displayDetailMapMaterial.mainTexture = detailMap;
    23.                 renderer.sharedMaterial = displayDetailMapMaterial;
    24.                
    25.             }
    26.             else
    27.             {
    28.                 renderer.sharedMaterial = originalMaterial;
    29.             }
    30.         }
    31.  
    32.        
    33.     }
    And I call Texture2D.GetPixels() to get all pixels of the map,then call Texture2D.SetPixels() and Texture2D.Apply() to apply change after editing.
    However, the MeshRenderer did not update the mainTexture,I logout all the pixels of the map,and make sure the Texture.Apply API works.I even have a try to set the map Dirty by EditorUtility.SetDirty(),and found the texture2D resource of the map did changed, but the MeshRenderer still not Update the mainTexture.
    Code (CSharp):
    1. public class CTSToolInspector : Editor
    2. {
    3.     private CustomTerrainSystemTool targetScript;
    4.     private bool mouseLeftDown = false;
    5.     private bool shouldeUpdateDetailMap;
    6.  
    7.     private Texture2D targetDetailMap;
    8.  
    9.     private Color[] detailMapColors;
    10.  
    11.     Vector2 pointPos;
    12.  
    13.  
    14.     public override VisualElement CreateInspectorGUI()
    15. {
    16.         targetScript = (CustomTerrainSystemTool)target;
    17.  
    18.         targetDetailMap = targetScript.DetailMap;
    19.         detailMapColors = targetDetailMap.GetPixels();
    20.  
    21.         shouldeUpdateDetailMap = false;
    22.         var root = new CTSToolVE(targetScript);
    23.         return root;
    24.     }
    25.    
    26.     private void OnSceneGUI()
    27.     {
    28.         if (targetScript.IsEditing && !Application.isPlaying)
    29.         {
    30.             if (targetScript.IsBrushing)
    31.             {
    32.                 Brushing();
    33.             }
    34.             else if (targetScript.IsErasing)
    35.             {
    36.                 Erasing();
    37.             }
    38.            
    39.         }
    40.     }
    41.  
    42.     private void Brushing()
    43.     {
    44.         HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
    45.  
    46.         if(Event.current.type==EventType.MouseDown && Event.current.button == 0)
    47.         {
    48.             mouseLeftDown = true;
    49.         }
    50.         else if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
    51.         {
    52.             mouseLeftDown = false;
    53.         }
    54.  
    55.         Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
    56.  
    57.         if (Physics.Raycast(ray, out RaycastHit hit))
    58.         {
    59.  
    60.             if (hit.transform.name == targetScript.gameObject.name)
    61.             {
    62.                 Handles.color = Color.white;
    63.                 var circelRadius = targetScript.BrushSize == 0f ? 1 : (float)targetScript.BrushSize;
    64.                 Handles.DrawWireDisc(hit.point, hit.normal, circelRadius * 0.1f);
    65.                 if (mouseLeftDown)
    66.                 {
    67.                     pointPos = new Vector2(hit.point.x, hit.point.z);
    68.                     pointPos -= targetScript.BoundsMinPos;
    69.                     pointPos *= 10;
    70.                     int w = (int)pointPos.x;
    71.                     int h = (int)pointPos.y;
    72.  
    73.                     ChangeDetialMap(w, h, targetScript.BrushSize, detailMapColors, targetScript.DetailMapWidth, targetScript.DetailMapHeight, targetScript.BrushColor, targetScript.BrushType == CustomEnums.BrushType.Cover);
    74.                     shouldeUpdateDetailMap = true;
    75.                 }
    76.             }
    77.  
    78.         }
    79.  
    80.         if (!mouseLeftDown && shouldeUpdateDetailMap)
    81.         {
    82.             targetDetailMap.SetPixels(detailMapColors);
    83.  
    84.             targetDetailMap.Apply(false);
    85.  
    86.             shouldeUpdateDetailMap = false;
    87.         }
    88.  
    89.         SceneView.RepaintAll();
    90.     }
    And I just want to konw how should I do to make MeshRenderer update texture immediately after I call Texture2D.Apply() in edit mode?