Newer
Older
Hierarchical-Task-Network-Unity-3D / Assets / Scripts / Environment / Grass.cs
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

[System.Serializable]
public struct GrassWindData
{
    public string childPath; // Changed from Transform to string
    public float windStrength;
    public float windSpeed;
}

public class Grass : MonoBehaviour
{
    [Header("Grass Size Settings: ")]
    [SerializeField][Range(0f, 1.5f)] private float minGrassSize;
    [SerializeField][Range(0f, 1.5f)] private float maxGrassSize;

    [Header("Wind Effect Settings: ")]
    [SerializeField][Range(0f, 2f)] private float minWindStrength = 0.5f;
    [SerializeField][Range(0f, 2f)] private float maxWindStrength = 1.5f;
    [SerializeField][Range(0f, 3f)] private float minWindSpeed = 0.5f;
    [SerializeField][Range(0f, 3f)] private float maxWindSpeed = 1.5f;

    [SerializeField] private List<GrassWindData> windDataList = new List<GrassWindData>();
    private string savePath
    {
        get
        {
#if UNITY_EDITOR
            // In Editor: Save to Assets/Data/ for easy access
            return "Assets/Data/Grass/GrassWindSettings.json";
#else
        // In Build: Save to persistentDataPath (works everywhere)
        return Path.Combine(Application.persistentDataPath, "GrassWindSettings.json");
#endif
        }
    }
    public float MinGrassSize => minGrassSize;
    public float MaxGrassSize => maxGrassSize;
    public float MinWindStrength => minWindStrength;
    public float MaxWindStrength => maxWindStrength;
    public float MinWindSpeed => minWindSpeed;
    public float MaxWindSpeed => maxWindSpeed;

    void OnEnable()
    {
        LoadAndApplyWindSettings();
    }

    public void SaveWindSettings(List<GrassWindData> data)
    {
        string directory = Path.GetDirectoryName(savePath);
        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }

        string json = JsonUtility.ToJson(new WindDataWrapper { data = data }, true);
        File.WriteAllText(savePath, json);

#if UNITY_EDITOR
        AssetDatabase.Refresh(); // Only works in Editor
#endif
        Debug.Log($"Wind settings saved to: {savePath}");
    }

    public List<GrassWindData> LoadWindSettings()
    {
        if (File.Exists(savePath))
        {
            string json = File.ReadAllText(savePath);
            return JsonUtility.FromJson<WindDataWrapper>(json).data;
        }
        return new List<GrassWindData>();
    }


    public void LoadAndApplyWindSettings()
    {
        windDataList = LoadWindSettings();
        ApplyStoredWindSettings();
    }

    [System.Serializable]
    private class WindDataWrapper
    {
        public List<GrassWindData> data;
    }

    public void ApplyStoredWindSettings()
    {
        foreach (var data in windDataList)
        {
            Transform child = FindChildByPath(data.childPath);
            if (child == null) continue;

            var renderer = child.GetComponent<MeshRenderer>();
            if (!renderer) continue;

            var block = new MaterialPropertyBlock();
            block.SetFloat("_Wind_Strength", data.windStrength);
            block.SetFloat("_Wind_Speed", data.windSpeed);
            renderer.SetPropertyBlock(block);
        }
    }

    private Transform FindChildByPath(string path)
    {
        string[] parts = path.Split('/');
        Transform current = transform;

        foreach (string part in parts)
        {
            current = current.Find(part);
            if (current == null) return null;
        }
        return current;
    }


    public void SetWindData(List<GrassWindData> newData)
    {
        windDataList = newData;
    }
}