天气系统:雨、雪
实现原理:雨和雪的实现基本类似,天空中飘的雨和雪,地上的水花和雪花,增加一个下落速度和风速,就形成了天气了。
天气雪实现步骤:
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 }
天气雪:
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 }