小小小---最近项目需求做了一个小功能
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class CoinAnimation : MonoBehaviour
{
//货币预制体
public GameObject[] mCoinPrefab;
public float mRate = 0.03f;
//移动速度
public float mMoveSpeed = 10;
public AnimationCurve mMoveSpeedCurve;
public float mRotateSpeed = 3;
//随机位置
public float startRangeOffect = 1f;
//点击播放动画
public Button btnClick;
private static CoinAnimation Instance;
//货币属性
private class Coin
{
//移动时间
public float mMoveProgress;
//货币对象
public Transform mTransform;
public Vector3 mRotateSpeed;
//起始位置
public Vector3 startIn;
//目标
public Vector3 targetIn;
}
private void Start()
{
btnClick.onClick.AddListener(BtnPlay);
Instance = this;
}
private void OnDestroy()
{
Instance = null;
}
public void BtnPlay()
{
Play(0, btnClick.transform.position, new Vector3(4, 4), 10);
}
private IEnumerator OnAnimation(float flyTime, int type, Vector3 startIn, Vector3 targetIn, int count)
{
Camera sceneCamera = Camera.main;
Camera uiCamera = null;
Vector3 start, target;
if (null != uiCamera)
{
start = startIn;
target = targetIn;
// 将UI起点坐标转换为场景起点坐标并保存
startIn = sceneCamera.ViewportToWorldPoint(uiCamera.WorldToViewportPoint(startIn));
}
else
{
start = startIn;
target = targetIn;
}
System.Collections.Generic.List coins = new System.Collections.Generic.List();
float generateTime = 0;
float generateCount = 0;
float moveSpeed = flyTime;
while (true)
{
if (generateCount < count && generateTime <= 0)
{
//计算实例化数量(创建数量依次增多 count / 2 时依次减少)
int instantiateCount = (int)(generateCount >= count / 2 ? count / 2 - (generateCount - count / 2) : generateCount);
//实例化对象
for (int i = 0; i <= instantiateCount; ++i)
{
Coin coin = new Coin();
coin.mRotateSpeed = new Vector3(
Mathf.Lerp(0, 360, Random.Range(0, 1f)),
Mathf.Lerp(0, 360, Random.Range(0, 1f)),
Mathf.Lerp(0, 360, Random.Range(0, 1f))) * mRotateSpeed;
//实例化的对象可从列表中根据自己需求来
GameObject go = Instantiate(mCoinPrefab[type], start, Random.rotationUniform) as GameObject;
go.SetActive(true);
go.transform.SetParent(transform);
go.transform.localScale = Vector3.one;
//将实例化的货币初始化
coin.mTransform = go.transform;
coin.startIn = new Vector3(Random.Range(startIn.x - startRangeOffect, startIn.x + startRangeOffect), Random.Range(startIn.y - startRangeOffect, startIn.y + startRangeOffect), Random.Range(startIn.z - startRangeOffect, startIn.z + startRangeOffect));
coin.targetIn = targetIn;
coins.Add(coin);
}
generateTime = mRate;
//创建次数
generateCount++;
}
else
{//实例化间隔时间
generateTime -= Time.deltaTime;
}
if (null != uiCamera)
{
// 将场景起点坐标转换为UI起点坐标,因为场景可以拖动,不然会造成效果分离的问题,所以必须转换一次
start = uiCamera.ViewportToWorldPoint(sceneCamera.WorldToViewportPoint(startIn));
}
for (int i = coins.Count - 1; i >= 0; --i)
{
Coin coin = coins[i];
coin.mTransform.position = Vector3.Lerp(coin.startIn, coin.targetIn, coins[i].mMoveProgress);
coin.mTransform.Rotate(coin.mRotateSpeed.x * Time.deltaTime, coin.mRotateSpeed.y * Time.deltaTime, coin.mRotateSpeed.z * Time.deltaTime);
//现在的移动进度
coin.mMoveProgress = coin.mMoveProgress + Mathf.Max(mMoveSpeedCurve.Evaluate(coin.mMoveProgress), 0.1f) * moveSpeed * Time.deltaTime;
if (coin.mMoveProgress >= 1)
{//移动结束之后删除预制体
coins.RemoveAt(i);
Destroy(coin.mTransform.gameObject);
}
}
//播放结束退出
if (generateCount >= count && coins.Count == 0)
break;
yield return null;
}
}
public float BeginAnimation(int type, Vector3 source, Vector3 target, int count)
{
// 飞行时长
float flyTime = (target - source).magnitude / mMoveSpeed;
StartCoroutine(OnAnimation(flyTime, type, source, target, Mathf.Clamp(count, 1, 20)));
return flyTime;
}
///
/// 播放特效
///
/// 类型
/// UI相机中的起点坐标
/// UI相机中的终点坐标
/// 粒子数量
/// 播放时长
public static float Play(int type, Vector3 source, Vector3 target, int count)
{
if (null != Instance)
{
return Instance.BeginAnimation(type, source, target, count);
}
return 0;
}
}