仿海岛奇兵中金币收取的效果,简单的粒子实现。
注:由于场景和UI相机是分离的,所以代码中增加了一次坐标转换的操作,防止场景拖动造成金币整体便宜的问题。
注:由于场景和UI相机是分离的,所以代码中增加了一次坐标转换的操作,防止场景拖动造成金币整体便宜的问题。
1
using
UnityEngine;
2 using System.Collections;
3
4 public 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
2 using System.Collections;
3
4 public 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