|
仿海岛奇兵中金币收取的效果,简单的粒子实现。 注:由于场景和UI相机是分离的,所以代码中增加了一次坐标转换的操作,防止场景拖动造成金币整体便宜的问题。
1using UnityEngine; 2using System.Collections; 3 4public class CoinsAnimation : MonoBehaviour 5{ 6 7 public GameObject[] mCoinPrefab; 8 public float mRate = 0.25f; 9 public float mMoveSpeed = 2; 10 public AnimationCurve mMoveSpeedCurve; 11 public float mRotateSpeed = 3; 12 13 private static CoinsAnimation Instance; 14 15 private class Coin 16 { 17 public float mMoveTime; 18 public Transform mTransform; 19 public Vector3 mRotateSpeed; 20 } 21 22 private void Start() 23 { 24 Instance = this; 25 } 26 27 private void OnDestroy() 28 { 29 Instance = null; 30 } 31 32 private IEnumerator OnAnimation(float flyTime, int type, Vector3 sourceIn, Vector3 targetIn, int count) 33 { 34 Camera sceneCamera = Camera.main; 35 Camera uiCamera = Global.Instance().GetUIManager().UICamera; 36 37 Vector3 source, target; 38 if (null != uiCamera) 39 { 40 source = sourceIn; 41 target = targetIn; 42 43 // 将UI起点坐标转换为场景起点坐标并保存 44 sourceIn = sceneCamera.ViewportToWorldPoint(uiCamera.WorldToViewportPoint(sourceIn)); 45 } 46 else 47 { 48 source = sourceIn; 49 target = targetIn; 50 } 51 52 System.Collections.Generic.List<Coin> coins = new System.Collections.Generic.List<Coin>(); 53 float generateTime = 0; 54 float generateCount = 0; 55 float moveSpeed = 1 / flyTime; 56 57 while (true) 58 { 59 if (generateCount < count && generateTime <= 0) 60 { 61 Coin coin = new Coin(); 62 63 coin.mRotateSpeed = new Vector3( 64 Mathf.Lerp(0, 360, Random.Range(0, 1.0f)), 65 Mathf.Lerp(0, 360, Random.Range(0, 1.0f)), 66 Mathf.Lerp(0, 360, Random.Range(0, 1.0f))) * mRotateSpeed; 67 68 GameObject go = Instantiate(mCoinPrefab[type], source, Random.rotationUniform) as GameObject; 69 coin.mTransform = go.transform; 70 71 coins.Add(coin); 72 generateTime = mRate; 73 generateCount++; 74 } 75 else 76 { 77 generateTime -= Time.deltaTime; 78 } 79 80 if (null != uiCamera) 81 { 82 // 将场景起点坐标转换为UI起点坐标,因为场景可以拖动,不然会造成效果分离的问题,所以必须转换一次 83 source = uiCamera.ViewportToWorldPoint(sceneCamera.WorldToViewportPoint(sourceIn)); 84 } 85 86 for (int i = coins.Count - 1; i >= 0; --i) 87 { 88 Coin coin = coins[i]; 89 coin.mTransform.position = Vector3.Lerp(source, target, coins[i].mMoveTime); 90 coin.mTransform.Rotate(coin.mRotateSpeed.x * Time.deltaTime, coin.mRotateSpeed.y * Time.deltaTime, coin.mRotateSpeed.z * Time.deltaTime); 91 coin.mMoveTime = coin.mMoveTime + Mathf.Max(mMoveSpeedCurve.Evaluate(coin.mMoveTime), 0.1f) * moveSpeed * Time.deltaTime; 92 93 if (coin.mMoveTime >= 1) 94 { 95 coins.RemoveAt(i); 96 Destroy(coin.mTransform.gameObject); 97 } 98 } 99 100 if (generateCount >= count && coins.Count == 0) 101 { 102 break; 103 } 104 105 yield return null; 106 } 107 } 108 109 public float BeginAnimation(int type, Vector3 source, Vector3 target, int count) 110 { 111 // 飞行时长 112 float flyTime = (target - source).magnitude / mMoveSpeed; 113 StartCoroutine(OnAnimation(flyTime, type, source, target, Mathf.Clamp(count, 1, 20))); 114 return flyTime; 115 } 116 117 /**//// <summary> 118 /// 播放特效 119 /// </summary> 120 /// <param name="type">类型</param> 121 /// <param name="source">UI相机中的起点坐标</param> 122 /// <param name="target">UI相机中的终点坐标</param> 123 /// <param name="count">粒子数量</param> 124 /// <returns>播放时长</returns> 125 public static float Play(int type, Vector3 source, Vector3 target, int count) 126 { 127 if (null != Instance) 128 { 129 return Instance.BeginAnimation(type, source, target, count); 130 } 131 return 0; 132 } 133 134} 135
|