天气系统:雨雪

Posted kane0526

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天气系统:雨雪相关的知识,希望对你有一定的参考价值。

实现原理:雨和雪的实现基本类似,天空中飘的雨和雪,地上的水花和雪花,增加一个下落速度和风速,就形成了天气了。

天气雪实现步骤

1、预生成Mesh:随机生成多个空中飘落的雪网格和地面上的雪花网格。

2、预生成雪shader和雪花shader,雪shader支持雪的显示,雪花shader支持序列帧动画显示。

3、新建一个雪相机,该相机只渲染Water层,所有和雪有关的都挂到Water层。

4、创建雪模板gameobj,模板包括MeshRenderer、雪shader创建的材质Material、MeshFilter。

5、创建雪花模板gameobj,模板包括MeshRenderer、雪花shader创建的材质Material、MeshFilter。

6、根据模板创建雪群:按高度分为上中下三层,随着时间下落到一定高度最下层会放到最上层,如此循环。

7、帧循环更新:雪相机跟随主相机偏移(xz变y不变),雪根据下落速度变化高度,根据风速变化水平位移,风速随时间变化,雪花随时间变化显示不同的动画关键帧。

8、雪从最高点重新下落会随机更新MeshFilter中mesh网格。

9、关闭雪的时候不是一下全部消失,得有个缓冲过程,都下落到最低点的时候消失。

 

雪网格:

技术分享图片
  1 using UnityEngine;
  2 using UnityEditor;
  3 using System.IO;
  4 using System.Collections;
  5 
  6 public class GenSnowMesh
  7 {
  8 
  9     public const int numberOfParticles = 60;   //雪的粒子数
 10     public const float areaSize = 80.0f;    //范围 因为雪的下落速度比较慢,所以范围要大一点,防止人物移动太快造成穿帮
 11     public const float areaHeight = 15.0f;  
 12     public const float particleSize = 0.3f;
 13     public const float flakeRandom = 0.1f;
 14     public const float flakeWidth = 0.15f;
 15     public static Vector3 cameraRight = new Vector3(-1, 0, 0);
 16     [MenuItem("GameEditor/scene/Weather/Snow/GenMesh")]
 17     static public void GenMesh()
 18     {
 19         for (int i = 0; i < 10; i++)
 20         {
 21             Mesh m1 = CreateMesh();
 22             AssetDatabase.CreateAsset(m1, "Assets/_Resource/model/prefab/weather/snow/SnowFx/snow_LQ" + i + ".asset");
 23         }
 24     }
 25 
 26     public static Mesh CreateMesh()
 27     {
 28         //Vector3 cameraRight1 = cameraRight * Random.Range(0.1f, 2.0f) + cameraRight * Random.Range(0.1f, 2.0f);// Vector3.forward;//Camera.main.transform.right;
 29         //cameraRight1 = Vector3.Normalize(cameraRight1);
 30         Vector3 cameraUp = new Vector3(0, 0.7f, 0.7f);
 31         Mesh mesh = new Mesh();
 32         int particleNum = numberOfParticles;
 33         Vector3[] verts = new Vector3[4 * particleNum];
 34         Vector2[] uvs = new Vector2[4 * particleNum];
 35 
 36         int[] tris = new int[2 * 3 * particleNum];
 37 
 38         Vector3 position;
 39         for (int i = 0; i < particleNum; i++)
 40         {
 41             int i4 = i * 4;
 42             int i6 = i * 6;
 43 
 44             position.x = areaSize * (Random.value - 0.5f);
 45             position.y = areaHeight * Random.value;
 46             position.z = areaSize * (Random.value - 0.5f);
 47 
 48             //float rand = Random.value;
 49             float widthWithRandom = particleSize  + Random.Range(-flakeRandom, flakeRandom);
 50             float heightWithRandom = widthWithRandom;//particleSize + rand * flakeRandom;
 51 
 52             verts[i4 + 0] = position - cameraRight * widthWithRandom;// - 0.0 * heightWithRandom;
 53             verts[i4 + 1] = position + cameraRight * widthWithRandom;// - 0.0 * heightWithRandom;
 54             verts[i4 + 2] = position + cameraRight * widthWithRandom + cameraUp * 2.0f * heightWithRandom;
 55             verts[i4 + 3] = position - cameraRight * widthWithRandom + cameraUp * 2.0f * heightWithRandom;
 56 
 57 
 58             uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
 59             uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
 60             uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
 61             uvs[i4 + 3] = new Vector2(0.0f, 1.0f);
 62 
 63 
 64             tris[i6 + 0] = i4 + 0;
 65             tris[i6 + 1] = i4 + 1;
 66             tris[i6 + 2] = i4 + 2;
 67             tris[i6 + 3] = i4 + 0;
 68             tris[i6 + 4] = i4 + 2;
 69             tris[i6 + 5] = i4 + 3;
 70         }
 71 
 72         mesh.vertices = verts;
 73         mesh.triangles = tris;
 74         mesh.uv = uvs;
 75         mesh.RecalculateBounds();
 76 
 77         return mesh;
 78     }
 79 
 80     [MenuItem("GameEditor/scene/Weather/Snow/GenSnowLieMesh")]
 81     static public void GenSnowlieMesh()
 82     {
 83         //#if UNITY_EDITOR    
 84         //    if (generateNewAssetsOnStart) {
 85         //        // create & save 3 meshes
 86         for (int i = 0; i < 10; i++)
 87         {
 88             Mesh m1 = CreateSplashMesh();
 89             AssetDatabase.CreateAsset(m1, "Assets/_Resource/model/prefab/weather/snow/SnowFx/snowlie_LQ" + i+".asset");
 90         }
 91         //AssetDatabase.CreateAsset(m2, "Assets/Objects/RainFx/" + gameObject.name + "_LQ1.asset");
 92         //AssetDatabase.CreateAsset(m3, "Assets/Objects/RainFx/" + gameObject.name + "_LQ2.asset");
 93         //Debug.Log ("Created new rain meshes in Assets/Objects/RainFx/");
 94         //    }        
 95         //#endif
 96     }
 97 
 98     static private Mesh CreateSplashMesh()
 99     {
100         Mesh mesh = new Mesh();
101         Vector3 cameraRight1 = cameraRight * Random.Range(0.1f, 2.0f) + cameraRight * Random.Range(0.1f, 2.0f);// Vector3.forward;//Camera.main.transform.right;
102         cameraRight1 = Vector3.Normalize(cameraRight1);
103         Vector3 cameraUp = Vector3.Cross(cameraRight1, Vector3.up);
104         cameraUp = Vector3.Normalize(cameraUp);
105 
106         //int particleNum = QualityManager.quality > Quality.Medium ? numberOfParticles : numberOfParticles / 2;
107         int particleNum = numberOfParticles;
108 
109         Vector3[] verts = new Vector3[4 * particleNum];
110         Vector2[] uvs = new Vector2[4 * particleNum];
111         Vector2[] uvs2 = new Vector2[4 * particleNum];
112         Vector3[] normals = new Vector3[4 * particleNum];
113 
114         int[] tris = new int[2 * 3 * particleNum];
115 
116         Vector3 position;
117         for (int i = 0; i < particleNum; i++)
118         {
119             int i4 = i * 4;
120             int i6 = i * 6;
121 
122             position.x = areaSize * (Random.value - 0.5f);
123             position.y = 0.0f;
124             position.z = areaSize * (Random.value - 0.5f);
125 
126             float rand = Random.value;
127             float widthWithRandom = flakeWidth + Random.Range(-flakeRandom, flakeRandom);
128             float heightWithRandom = widthWithRandom;//particleSize + rand * flakeRandom;
129 
130             verts[i4 + 0] = position - cameraRight1 * widthWithRandom;// - 0.0 * heightWithRandom;
131             verts[i4 + 1] = position + cameraRight1 * widthWithRandom;// - 0.0 * heightWithRandom;
132             verts[i4 + 2] = position + cameraRight1 * widthWithRandom + cameraUp * 2.0f * heightWithRandom;
133             verts[i4 + 3] = position - cameraRight1 * widthWithRandom + cameraUp * 2.0f * heightWithRandom;
134 
135             uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
136             uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
137             uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
138             uvs[i4 + 3] = new Vector2(0.0f, 1.0f);
139 
140             Vector2 tc1 = new Vector2(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f));
141             uvs2[i4 + 0] = new Vector2(tc1.x, tc1.y);
142             uvs2[i4 + 1] = new Vector2(tc1.x, tc1.y);
143             uvs2[i4 + 2] = new Vector2(tc1.x, tc1.y);
144             uvs2[i4 + 3] = new Vector2(tc1.x, tc1.y);
145 
146             tris[i6 + 0] = i4 + 0;
147             tris[i6 + 1] = i4 + 1;
148             tris[i6 + 2] = i4 + 2;
149             tris[i6 + 3] = i4 + 0;
150             tris[i6 + 4] = i4 + 2;
151             tris[i6 + 5] = i4 + 3;
152         }
153 
154         mesh.vertices = verts;
155         mesh.triangles = tris;
156         mesh.uv = uvs;
157         mesh.uv2 = uvs2;
158         mesh.RecalculateBounds();
159         return mesh;
160     }
161 }
View Code

天气雪:

技术分享图片
  1 using UnityEngine;
  2 using System.Collections.Generic;
  3 
  4 public class SnowManager : MonoBehaviour
  5 {
  6     private static Vector3 SNOW_CAMERA_POS = new Vector3(-4000.0f, 0.0f, 0.0f);
  7     private const float SNOW_MESH_HEIGHT = 15;
  8     private const float SNOW_OFFSET = 35.0f;
  9 
 10     private enum eSnowRunState
 11     {
 12         None = 0,
 13         Load = 2,
 14         Update = 3,
 15         Release = 4,
 16     }
 17     private eSnowRunState m_state = eSnowRunState.None;
 18 
 19     private static GameObject GlobaSnowManagerObject;
 20 
 21     //摄像机相关
 22     private Transform m_mainCam;            //主摄像机
 23     private Transform m_snowCam;          //雪的相机
 24     private Vector3 m_lastMainCamPos = Vector3.zero;
 25 
 26     class SnowInfo  //雪丝相关参数 
 27     {
 28         public int groupCount = 3;
 29         public int groupChildCount = 2;
 30         public float speed = 10.0f;
 31         public float startHeight = 15.0f;
 32         public float hideHeight = -20.0f;
 33         public int meshCount = 10;
 34         public Mesh[] snowMeshs;
 35         public GameObject snowObject;
 36         public List<Transform> groupList = new List<Transform>();
 37     }
 38     private SnowInfo m_snow = new SnowInfo();
 39 
 40 
 41     class GroundSnowInfo  //地面上的雪相关参数
 42     {
 43         public bool open = true;
 44         public int groundSnowCount = 4;
 45         public int meshCount = 10;
 46         public Mesh[] meshes;
 47         public List<Transform> list = new List<Transform>();
 48         public float[] times;
 49         public float intervalChangeMesh = 10.0f;
 50         public GameObject groundSnowObject;
 51     }
 52     private GroundSnowInfo m_groundSnow = new GroundSnowInfo();
 53 
 54 
 55     class WindInfo //风的参数
 56     {
 57         public enum SpeedState
 58         {
 59             Calm = 0,  //平静
 60             Add = 1,    //加速
 61             Max = 2,    //最大速度
 62             Weaken = 3, //风速减弱
 63         }
 64         public bool open = true;
 65         public float maxSpeed = 6.0f;
 66         public float curSpeed = 0.0f;
 67         public float beginSpeed = 0;
 68         public float intervalTime = 15.0f;
 69         public float passTime = 0.0f;
 70         public float totalExistTime = 5.0f;
 71         public float curExistTime = 0.0f;
 72         public SpeedState state = SpeedState.Calm;
 73 
 74         public void reset()
 75         {
 76             curSpeed = 0.0f;
 77             passTime = 0.0f;
 78             curExistTime = 0.0f;
 79             state = SpeedState.Calm;
 80         }
 81     }
 82     private WindInfo m_wind = new WindInfo();
 83     /// <summary>
 84     /// 创建一个全局雪控制器对象
 85     /// </summary>
 86     /// <returns> 全局雪控制器对象</returns>
 87     public static SnowManager GetInstance()
 88     {
 89         SnowManager rm = null;
 90         if (GlobaSnowManagerObject == null)
 91         {
 92             GlobaSnowManagerObject = new GameObject("GlobaSnowManagerObject");
 93             UnityEngine.Object.DontDestroyOnLoad(GlobaSnowManagerObject);
 94             rm = GlobaSnowManagerObject.AddComponent(typeof(SnowManager)) as SnowManager;
 95         }
 96         else
 97         {
 98             rm = GlobaSnowManagerObject.GetComponent("SnowManager") as SnowManager;
 99         }
100         return rm;
101     }
102 
103 
104     public void OpenSnow()  //开始下雪
105     {
106         QLog.Log("OpenSnow");
107 
108         if (m_state == eSnowRunState.None)
109         {
110             m_wind.reset();
111             LoadSnowResource("map/weather/weather_snow.unity3d");
112         }
113         return;
114     }
115 
116     private void DestroySnowImmediately()
117     {
118         DestroyAllObject();
119         SetState(eSnowRunState.None);
120     }
121     private void DestroyAllObject()
122     {
123         int count = m_snow.groupList.Count;
124         for (int i = 0; i < count; i++)
125         {
126             Destroy(m_snow.groupList[i].gameObject);
127         }
128         m_snow.groupList.Clear();
129 
130         count = m_groundSnow.list.Count;
131         for (int i = 0; i < count; i++)
132         {
133             Destroy(m_groundSnow.list[i].gameObject);
134         }
135         m_groundSnow.list.Clear();
136 
137         if (m_snowCam != null)
138             Destroy(m_snowCam.gameObject);
139     }
140 
141     public void CloseSnow()
142     {
143         QLog.Log("ColseSnow");
144         SetState(eSnowRunState.Release);
145     }
146     public static void ForceCloseSnow()
147     {
148         if (GlobaSnowManagerObject != null)
149         {
150             SnowManager rm = GlobaSnowManagerObject.GetComponent("SnowManager") as SnowManager;
151             if (rm != null)
152             {
153                 rm.DestroySnowImmediately();
154             }
155         }
156     }
157     public void SetSnowArg(int groupChildCount, float speed)
158     {
159         m_snow.groupChildCount = groupChildCount;
160         m_snow.speed = speed;
161     }
162 
163     public void SetGroundSnowArg(bool open, int groundSnow_count)
164     {
165         m_groundSnow.open = open;
166         m_groundSnow.groundSnowCount = groundSnow_count;
167     }
168 
169     public void SetWindArg(bool open, float max_speed, float intervalTime, float totalExistTime)
170     {
171         m_wind.open = open;
172         m_wind.beginSpeed = 0;
173         m_wind.maxSpeed = max_speed;
174         m_wind.intervalTime = intervalTime;
175         m_wind.totalExistTime = totalExistTime;
176     }
177 
178     public void CreateSnowCamera(float fieldOfView, float nearClipPlane, float farClipPlane, float height, float rotationX, float rotationY, float rotationZ)
179     {
180         //雪的专用摄像头
181         if (m_snowCam == null)
182         {
183             GameObject snow_cam = new GameObject("SnowCamera");
184             Camera cam = snow_cam.AddComponent<Camera>();
185             cam.clearFlags = CameraClearFlags.Depth;
186             cam.fieldOfView = fieldOfView;
187             cam.depth = (float)CommonConst.SnowCameraDepth;
188             cam.nearClipPlane = nearClipPlane;
189             cam.farClipPlane = farClipPlane;
190             cam.cullingMask = 1 << LayerMask.NameToLayer("Water");
191             m_snowCam = snow_cam.transform;
192             m_snowCam.position = SNOW_CAMERA_POS + Vector3.up * height;
193             m_snowCam.eulerAngles = new Vector3(rotationX, rotationY, rotationZ);
194         }
195     }
196 
197 
198     private void LoadSnowResource(string path)
199     {
200         string assetPath = CommonProxy.GetAssetPath(path);
201         WWWLoaderBatch wWWLoaderBatch = BatchManager.instance.CreateBatchLoader(new WWWLoaderBatch.BatchComplete(this.LoadSnowCompleted), null);
202         wWWLoaderBatch.SetBatchName("snowObject");
203         BatchManager.instance.AddDependentLoaderToBatch(wWWLoaderBatch, assetPath, null, null, AssetPRI.DownloadPRI_Common, false);
204         wWWLoaderBatch.CmpInsertElementToBatch();
205     }
206 
207     private void LoadSnowCompleted(WWWLoaderBatch batch)
208     {
209         if (!WWWLoaderBatch.CheckBatchValid(batch))
210         {
211             return;
212         }
213         else
214         {
215             WWWLoader dependentWWWAssetLoader = batch.dependentLoaderQueue[0];
216             if (dependentWWWAssetLoader != null)
217             {
218                 InitInfo(dependentWWWAssetLoader);
219             }
220             batch.BatchRefCount--;
221         }
222     }
223 
224     private void InitInfo(WWWLoader loader)
225     {
226 
227         if (this.m_state != SnowManager.eSnowRunState.None)
228         {
229             return;
230         }
231         if (ImageEffectManager.GetMainCamera() == null)
232         {
233             this.DestroySnowImmediately();
234             return;
235         }
236         if (this.m_snowCam == null)
237         {
238             GameObject gameObject = new GameObject("SnowCamera");
239             Camera camera = gameObject.AddComponent<Camera>();
240             camera.clearFlags = CameraClearFlags.Depth;
241             camera.fieldOfView = 45f;
242             camera.depth = (float)CommonConst.SnowCameraDepth;
243             camera.nearClipPlane = 5f;
244             camera.farClipPlane = 80f;
245             camera.cullingMask  = 1 << LayerMask.NameToLayer("Water");
246             this.m_snowCam = gameObject.transform;
247             this.m_snowCam.position = SnowManager.SNOW_CAMERA_POS;
248             this.m_snowCam.eulerAngles = new Vector3(30f, 0f, 0f);
249         }
250 
251         Material mat;
252 
253 
254         //雪网格
255         m_snow.snowMeshs = new Mesh[m_snow.meshCount];
256         for (int i = 0; i < m_snow.meshCount; i++)
257         {
258             m_snow.snowMeshs[i] = loader.Load("snow_LQ" + i) as Mesh;
259         }
260 
261         //地面上的雪网格
262         m_groundSnow.meshes = new Mesh[m_groundSnow.meshCount];
263         for (int i = 0; i < m_groundSnow.meshCount; i++)
264         {
265             m_groundSnow.meshes[i] = loader.Load("snowlie_LQ" + i) as Mesh;
266         }
267 
268         //创建雪的模板
269         GameObject snowObject = new GameObject("snow");
270         snowObject.layer = LayerMask.NameToLayer("Water");
271         MeshRenderer renderer = snowObject.AddComponent<MeshRenderer>();
272         mat = new Material(ShaderManager.GetInstance().FindShader("xj/Scene/Rain"));
273         mat.mainTexture = loader.Load("snow") as Texture2D;
274         renderer.sharedMaterial = mat;
275         snowObject.AddComponent<MeshFilter>().mesh = m_snow.snowMeshs[0];
276         m_snow.snowObject = snowObject;
277 
278         //创建地面上的雪模板
279         GameObject groundSnowObject = new GameObject("groundSnow");
280         groundSnowObject.layer = LayerMask.NameToLayer("Water");
281         renderer = groundSnowObject.AddComponent<MeshRenderer>();
282         mat = new Material(ShaderManager.GetInstance().FindShader("xj/Scene/SnowLie"));
283         mat.mainTexture = loader.Load("snowlie") as Texture2D;
284         renderer.sharedMaterial = mat;
285         groundSnowObject.AddComponent<MeshFilter>().mesh = m_groundSnow.meshes[0];
286         m_groundSnow.groundSnowObject = groundSnowObject;
287 
288         m_mainCam = Camera.main.transform;
289         m_lastMainCamPos = m_mainCam.position;
290 
291         SetState(eSnowRunState.Load);
292     }
293 
294     private void Update()
295     {
296 #if ENABLE_PROFILER
297         StatHelper.Instance().BeginSample("SnowManager.Update");
298 #endif
299         if (m_state != eSnowRunState.None)
300         {
301             switch (m_state)
302             {
303                 case eSnowRunState.Load: Load(); break;
304                 case eSnowRunState.Update: ForUpdate(); break;
305                 case eSnowRunState.Release: ReleaseSnow(); break;
306             }
307         }
308 #if ENABLE_PROFILER
309         StatHelper.Instance().EndSample();
310 #endif
311     }
312 
313     private void Load()
314     {
315         Transform tmpTran = null;
316 
317         //创建雪群
318         GameObject templateObject = m_snow.snowObject;
319         for (int i = 0; i < m_snow.groupCount; i++)
320         {
321             tmpTran = new GameObject("SnowGroup").transform;
322             tmpTran.parent = transform;
323             tmpTran.localPosition = Vector3.up * (i * SNOW_MESH_HEIGHT);
324             m_snow.groupList.Add(tmpTran);
325         }
326 
327         for (int i = 0; i < m_snow.groupCount * m_snow.groupChildCount; i++)
328         {
329             if (i == 0)
330             {
331                 tmpTran = templateObject.transform;
332             }
333             else
334             {
335                 tmpTran = (Object.Instantiate(templateObject) as GameObject).transform;
336             }
337             tmpTran.GetComponent<MeshFilter>().mesh = m_snow.snowMeshs[i % m_snow.meshCount];
338 
339             tmpTran.parent = m_snow.groupList[i % m_snow.groupCount];
340             tmpTran.localPosition = Vector3.zero;
341             tmpTran.localRotation = Quaternion.identity;
342         }
343 
344         //创建地面上的雪群
345         if (m_groundSnow.open)
346         {
347             templateObject = m_groundSnow.groundSnowObject;
348             Transform groundSnow_root = new GameObject("groundSnow_root").transform;
349             groundSnow_root.position = Vector3.zero;
350             groundSnow_root.parent = transform;
351             m_groundSnow.times = new float[m_groundSnow.groundSnowCount];
352             for (int i = 0; i < m_groundSnow.groundSnowCount; i++)
353             {
354                 if (i == 0)  //fix
355                 {
356                     tmpTran = templateObject.transform;
357                 }
358                 else
359                 {
360                     tmpTran = (Object.Instantiate(templateObject) as GameObject).transform;
361                 }
362                 tmpTran.GetComponent<MeshFilter>().mesh = m_groundSnow.meshes[i % m_groundSnow.meshCount];
363 
364                 tmpTran.parent = groundSnow_root;
365                 tmpTran.localPosition = new Vector3(m_mainCam.position.x, 1, m_mainCam.position.z);
366                 m_groundSnow.list.Add(tmpTran);
367                 m_groundSnow.times[i] = i;
368             }
369         }
370 
371         SetState(eSnowRunState.Update);
372     }
373 
374     private void ForUpdate()
375     {
376 
377         if (m_snowCam == null || m_mainCam == null)
378         {
379             DestroySnowImmediately();
380             return;
381         }
382 
383         Vector3 cam_offset = m_mainCam.position - m_lastMainCamPos;
384         cam_offset.y = 0;
385         m_snowCam.position += cam_offset;
386         m_lastMainCamPos = m_mainCam.position;
387 
388         Transform m_tempTran;
389         for (int i = 0; i < m_snow.groupList.Count; i++)
390         {
391             m_tempTran = m_snow.groupList[i];
392             m_tempTran.position -= m_tempTran.up * m_snow.speed * Time.deltaTime;
393             m_tempTran.position += m_tempTran.right * m_wind.curSpeed * Time.deltaTime;
394             m_tempTran.eulerAngles = new Vector3(0, 0, Mathf.Atan(m_wind.curSpeed / m_snow.speed) * Mathf.Rad2Deg);
395             if (m_tempTran.position.y < m_snow.hideHeight)
396             {
397                 Vector3 followPos = m_snowCam.position + new Vector3(0, 0, SNOW_OFFSET);
398                 followPos.y = m_snow.startHeight - (m_snow.hideHeight - m_tempTran.position.y);//之所以减去这个值是为了防止卡帧,导致雪集中从起点出现,造成断层 
399                 m_tempTran.position = followPos;
400                 for (int c = 0; c < m_tempTran.childCount; c++)
401                 {
402                     m_tempTran.GetChild(c).GetComponent<MeshFilter>().mesh = m_snow.snowMeshs[Random.Range(0, m_snow.meshCount - 1)];
403                 }
404             }
405         }
406 
407         if (m_groundSnow.open)
408         {
409             float[] groundSnow_times = m_groundSnow.times;
410             for (int i = 0; i < groundSnow_times.Length; i++)
411             {
412                 groundSnow_times[i] -= Time.deltaTime;
413                 if (groundSnow_times[i] < 0)
414                 {
415                     m_groundSnow.list[i].position = new Vector3(m_mainCam.position.x, 0, m_mainCam.position.z);
416                     m_groundSnow.list[i].GetComponent<MeshFilter>().mesh = m_groundSnow.meshes[Random.Range(0, m_groundSnow.meshCount)];
417                     groundSnow_times[i] = m_groundSnow.intervalChangeMesh;
418                 }
419             }
420         }
421         TryChangeWindSpeed();
422     }
423 
424     private void TryChangeWindSpeed()
425     {
426         if (m_wind.open)
427         {
428             switch (m_wind.state)
429             {
430                 case WindInfo.SpeedState.Calm:
431                     m_wind.passTime += Time.deltaTime;
432                     if (m_wind.passTime > m_wind.intervalTime)
433                     {
434                         soundManager.GetInstance().PlaySound("scene/wind", false);
435                         m_wind.passTime = 0;
436                         m_wind.state = WindInfo.SpeedState.Add;
437                     }
438                     break;
439                 case WindInfo.SpeedState.Add:
440                     m_wind.curSpeed += m_wind.maxSpeed * Time.deltaTime;
441                     if (m_wind.curSpeed >= m_wind.maxSpeed)
442                     {
443                         m_wind.curSpeed = m_wind.maxSpeed;
444                         m_wind.state = WindInfo.SpeedState.Max;
445                     }
446                     break;
447                 case WindInfo.SpeedState.Max:
448                     m_wind.curExistTime += Time.deltaTime;
449                     if (m_wind.curExistTime > m_wind.totalExistTime)
450                     {
451                         m_wind.curExistTime = 0;
452                         m_wind.state = WindInfo.SpeedState.Weaken;
453                     }
454                     break;
455                 case WindInfo.SpeedState.Weaken:
456                     m_wind.curSpeed -= m_wind.maxSpeed * Time.deltaTime * 0.1f;
457                     if (m_wind.curSpeed < m_wind.beginSpeed)
458                     {
459                         m_wind.curSpeed = m_wind.beginSpeed;
460                         m_wind.state = WindInfo.SpeedState.Calm;
461                     }
462                     break;
463             }
464         }
465     }
466 
467     private void ReleaseSnow()
468     {
469         //关闭雪天,有个缓冲过程,雪不要一下子全部消失
470         int countShow = m_snow.groupList.Count;
471         if (countShow == 0)
472         {
473             DestroySnowImmediately();
474             return;
475         }
476         Transform m_tempTran;
477         for (int i = countShow - 1; i >= 0; i--)
478         {
479             m_tempTran = m_snow.groupList[i];
480             m_tempTran.position -= m_tempTran.up * m_snow.speed * Time.deltaTime;
481             m_tempTran.position += m_tempTran.right * m_wind.curSpeed * Time.deltaTime;
482             m_tempTran.eulerAngles = new Vector3(0, 0, Mathf.Atan(m_wind.curSpeed / m_snow.speed) * Mathf.Rad2Deg);
483             if (m_tempTran.position.y < m_snow.hideHeight)
484             {
485                 Destroy(m_tempTran.gameObject);
486                 m_snow.groupList.RemoveAt(i);
487             }
488         }
489 
490         if (m_groundSnow.open)
491         {
492             float[] groundSnow_times = m_groundSnow.times;
493             for (int i = groundSnow_times.Length - 1; i >= 0; i--)
494             {
495                 groundSnow_times[i] -= Time.deltaTime;
496                 if (groundSnow_times[i] < 0)
497                 {
498                     m_groundSnow.list[i].gameObject.SetActive(false);
499                     groundSnow_times[i] = 100;
500                 }
501             }
502         }
503     }
504 
505     private void SetState(eSnowRunState state)
506     {
507         m_state = state;
508     }
509 
510 }
View Code

 

以上是关于天气系统:雨雪的主要内容,如果未能解决你的问题,请参考以下文章

『Flutter-绘制篇』实现炫酷的雨雪特效

行人识别预警系统真的有效吗?

利用Python网络爬虫采集天气网的实时信息—BeautifulSoup选择器

利用Python网络爬虫采集天气网的实时信息—BeautifulSoup选择器

华为:5G助推自动驾驶进入新时代

纯CSS实现动态晴阴雨雪