How to save material to asset with script?

when running the game it’s changing the material but when i close stop the game it’s changing the material back to it’s original. and i want to save it keep it.

in this script i change the material but i want that when i exit the game stop the game that the material i changed to will stay.

i have in the assets a folder name My Materials with already created two materials. outputMaterial and grayscaleMaterial.

this is the method i use to try to save it.

void SaveMaterial(Material material, string path)
    {
        #if UNITY_EDITOR
        AssetDatabase.CreateAsset(material, path);
        AssetDatabase.SaveAssets();
        #endif
    }

but i’m getting two errors in the editor when running the game.

Couldn’t add object to asset file because the Material ‘GrayscaleMaterial’ is already an asset at ‘Assets/My Materials/GrayscaleMaterial.mat’!
UnityEngine.StackTraceUtility:ExtractStackTrace ()
OutlineDetector:SaveMaterial (UnityEngine.Material,string) (at Assets/My Scripts/OutlineDetector.cs:44)
OutlineDetector:Start () (at Assets/My Scripts/OutlineDetector.cs:25)

and

UnityException: Creating asset at path Assets/GrayscaleMaterial.mat failed.
OutlineDetector.SaveMaterial (UnityEngine.Material material, System.String path) (at Assets/My Scripts/OutlineDetector.cs:44)
OutlineDetector.Start () (at Assets/My Scripts/OutlineDetector.cs:25)

i tried to change then the method to this

void SaveMaterial(Material material, string path)
{
    #if UNITY_EDITOR
    // Check if the asset already exists at the specified path
    Material existingMaterial = AssetDatabase.LoadAssetAtPath<Material>(path);
    if (existingMaterial == null)
    {
        // If it doesn't exist, create a new asset
        AssetDatabase.CreateAsset(material, path);
    }
    else
    {
        // If it does exist, update the existing asset with new material properties
        EditorUtility.CopySerialized(material, existingMaterial);
        AssetDatabase.SaveAssets();
    }
    #endif
}

but still getting the same two errors.

this is the full script:

using UnityEngine;
using OpenCvSharp;
using UnityEditor; // Add this to access AssetDatabase

public class ChangeMaterial : MonoBehaviour
{
    public Texture2D sourceImage;
    public Material outputMaterial; // Material used to display the edge detection result
    public Material grayscaleMaterial; // Material used to display the grayscale result

    void Start()
    {
        // Convert Texture2D to Mat
        Mat imgMat = OpenCvSharp.Unity.TextureToMat(sourceImage);

        // Convert to grayscale
        Mat grayMat = new Mat();
        Cv2.CvtColor(imgMat, grayMat, ColorConversionCodes.BGR2GRAY);

        // Convert the grayscale Mat to a Texture2D and display
        Texture2D grayTexture = OpenCvSharp.Unity.MatToTexture(grayMat);
        grayscaleMaterial.mainTexture = grayTexture;

        // Save the new grayscale material in the Assets folder (Editor-only)
        SaveMaterial(grayscaleMaterial, "Assets/GrayscaleMaterial.mat");

        // Detect edges using Canny Edge Detection
        Mat edges = new Mat();
        Cv2.Canny(grayMat, edges, 100, 200); // Adjust threshold values as needed

        // Convert edges Mat to Texture2D and display
        Texture2D edgesTexture = OpenCvSharp.Unity.MatToTexture(edges);
        outputMaterial.mainTexture = edgesTexture;
    }

    void SaveMaterial(Material material, string path)
    {
#if UNITY_EDITOR
        // Check if the asset already exists at the specified path
        Material existingMaterial = AssetDatabase.LoadAssetAtPath<Material>(path);
        if (existingMaterial == null)
        {
            // If it doesn't exist, create a new asset
            AssetDatabase.CreateAsset(material, path);
        }
        else
        {
            // If it does exist, update the existing asset with new material properties
            EditorUtility.CopySerialized(material, existingMaterial);
            AssetDatabase.SaveAssets();
        }
#endif
    }
}

this is image of my assets of the materials. and the ui image with the script attached to it.

If you’re changing a Renderer.sharedMaterial the changes will persist as you’re modifying the actual asset on disk. Renderer.material gives you an instance, so changing it doesn’t causes changes between play mode sessions (and should be disposed of when no longer needed, otherwise that causes a memory leak).

So just, modify a .sharedMaterial?