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.
public void UpdateDisplayDetailMap(bool isDisplayDetailMap)
{
if (TryGetComponent<MeshRenderer>(out var renderer))
{
if (originalMaterial == null)
{
originalMaterial = renderer.sharedMaterial;
}
if (displayDetailMapMaterial == null)
{
return;
}
if (isDisplayDetailMap)
{
//displayDetailMapMaterial.SetTexture("_MainTex", detailMap);
displayDetailMapMaterial.mainTexture = detailMap;
renderer.sharedMaterial = displayDetailMapMaterial;
}
else
{
renderer.sharedMaterial = originalMaterial;
}
}
}
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.
public class CTSToolInspector : Editor
{
private CustomTerrainSystemTool targetScript;
private bool mouseLeftDown = false;
private bool shouldeUpdateDetailMap;
private Texture2D targetDetailMap;
private Color[] detailMapColors;
Vector2 pointPos;
public override VisualElement CreateInspectorGUI()
{
targetScript = (CustomTerrainSystemTool)target;
targetDetailMap = targetScript.DetailMap;
detailMapColors = targetDetailMap.GetPixels();
shouldeUpdateDetailMap = false;
var root = new CTSToolVE(targetScript);
return root;
}
private void OnSceneGUI()
{
if (targetScript.IsEditing && !Application.isPlaying)
{
if (targetScript.IsBrushing)
{
Brushing();
}
else if (targetScript.IsErasing)
{
Erasing();
}
}
}
private void Brushing()
{
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
if(Event.current.type==EventType.MouseDown && Event.current.button == 0)
{
mouseLeftDown = true;
}
else if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
mouseLeftDown = false;
}
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (hit.transform.name == targetScript.gameObject.name)
{
Handles.color = Color.white;
var circelRadius = targetScript.BrushSize == 0f ? 1 : (float)targetScript.BrushSize;
Handles.DrawWireDisc(hit.point, hit.normal, circelRadius * 0.1f);
if (mouseLeftDown)
{
pointPos = new Vector2(hit.point.x, hit.point.z);
pointPos -= targetScript.BoundsMinPos;
pointPos *= 10;
int w = (int)pointPos.x;
int h = (int)pointPos.y;
ChangeDetialMap(w, h, targetScript.BrushSize, detailMapColors, targetScript.DetailMapWidth, targetScript.DetailMapHeight, targetScript.BrushColor, targetScript.BrushType == CustomEnums.BrushType.Cover);
shouldeUpdateDetailMap = true;
}
}
}
if (!mouseLeftDown && shouldeUpdateDetailMap)
{
targetDetailMap.SetPixels(detailMapColors);
targetDetailMap.Apply(false);
shouldeUpdateDetailMap = false;
}
SceneView.RepaintAll();
}
And I just want to konw how should I do to make MeshRenderer update texture immediately after I call Texture2D.Apply() in edit mode?