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; } }