Unity3D利用UGUI模擬《海島奇兵》收穫資源的爆炸效果
《海島奇兵》是由芬蘭Supercell Oy公司開發,Supercell Oy及崑崙遊戲發行的一款戰鬥策略類、全球同服的手機遊戲。估計大部分人都玩過,即使沒有玩過也應該知道這款遊戲吧。本人之前就熱衷於這款遊戲,對於熱愛遊戲開發的我來說,看見這款遊戲的效果,實在是歎為觀止,甚至想把所有的效果都模擬過來放入自己的遊戲中。這不,現在就來用Unity模擬它收穫資源產生大量資源圖示飛入到揹包的效果。
我就取名為WeiButEffect
C#指令碼,主要就是這個類實現的所有功能,先上原始碼。
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 模擬《海島奇兵》收穫資源的爆炸效果
/// weibut.com
/// </summary>
public class WeiButEffect : MonoBehaviour {
/// <summary>
/// 移動到的目標
/// </summary>
public Transform target;
/// <summary>
/// 運動時間
/// </summary>
public float factor = 1f;
/// <summary>
/// 生成個數
/// </summary>
public int amount;
/// <summary>
/// 需要生成的物體
/// </summary>
public Transform prefab;
/// <summary>
/// 爆炸範圍
/// </summary>
public float explosionRadius = 200;
public System.Action onFinish;//完成後回撥
float time0 = 0;
List<Vector3> ctrlPoints = new List<Vector3>();
List<Transform> particles = new List<Transform>();
public void PlayEffect()
{
int n = Mathf.Max(1, amount);
for (int i = 0; i < n; i++)
{
if (prefab)
{
GenerateParticle(prefab);
}
}
time0 = Time.time;
}
void GenerateParticle(Transform prefab)
{
var p = Instantiate(prefab, Vector3.zero, Quaternion.identity).gameObject;
p.transform.SetParent(transform, false);
particles.Add(p.transform);
ctrlPoints.Add(Random.insideUnitSphere * explosionRadius);
}
// Update is called once per frame
void Update () {
if (!this.target)
{
OnFinish();
return;
}
float t = (Time.time - time0) / Mathf.Max(0.1f, factor);
if (t > 1)
{
t = 1;
OnFinish();
}
Vector3 target = GetTargetPositionLocal();
for (int i = 0; i < ctrlPoints.Count; i++)
{
Vector3 ctrl = ctrlPoints[i];
Vector3 begin = Vector3.zero;
Vector3 pos = Vector3.Lerp(Vector3.Lerp(begin, ctrl, t), Vector3.Lerp(ctrl, target, t), t);
particles[i].localPosition = pos;
}
}
void OnFinish()
{
Destroy(gameObject);
if (onFinish != null)
{
onFinish();
}
}
Vector3 GetTargetPositionLocal()
{
var screenPoint = target.GetScreenPoint();
Vector2 localPoint = Vector2.zero;
GetComponent<RectTransform>().ScreenPointToLocalPosition(screenPoint, out localPoint);
return localPoint;
}
/// <summary>
/// 模擬《海島奇兵》收穫資源的爆炸效果
/// </summary>
/// <param name="parent">建立在哪</param>
/// <param name="target">移動到哪</param>
/// <param name="prefab">移動物體</param>
/// <param name="amount">個數</param>
/// <param name="explosionRadius">擴散範圍</param>
/// <param name="onFinish">移動完成回撥</param>
/// <returns></returns>
public static WeiButEffect CreateEffect(Transform parent, Transform target, Transform prefab, int amount, float explosionRadius = 200, System.Action onFinish = null)
{
GameObject instance = new GameObject(prefab.name);
instance.transform.SetParent(parent, false);
instance.AddComponent<RectTransform>();
var effect = instance.AddComponent<WeiButEffect>();
effect.prefab = prefab;
effect.amount = amount;
effect.target = target;
effect.onFinish = onFinish;
effect.explosionRadius = explosionRadius;
effect.PlayEffect();
return effect;
}
}
/// <summary>
/// TransForm的擴充套件
/// </summary>
public static class TRE
{
/// <summary>
/// 獲取Canvas裡transform的螢幕座標
/// </summary>
/// <param name="trans"></param>
/// <returns></returns>
public static Vector3 GetScreenPoint(this Transform trans)
{
var canvas = trans.GetComponentInParent<Canvas>();
if (canvas)
{
var uiCamera = canvas.worldCamera ?? Camera.main;
if (canvas.renderMode == RenderMode.WorldSpace)
{
uiCamera.WorldToScreenPoint(trans.position);
}
else if (uiCamera && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
{
return uiCamera.WorldToScreenPoint(trans.position);
}
else
{
return trans.position;
}
}
return Camera.main.WorldToScreenPoint(trans.position);
}
public static bool ScreenPointToLocalPosition(this RectTransform rect, Vector2 screenPoint, out Vector2 localPoint)
{
if (rect)
{
Transform current = rect;
Canvas canvas = null;
for (; current != null; current = current.parent)
{
canvas = current.GetComponent<Canvas>();
if (canvas != null)
{
break;
}
}
var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : (canvas.renderMode == RenderMode.ScreenSpaceCamera ? canvas.worldCamera : canvas.worldCamera ?? Camera.main);
return RectTransformUtility.ScreenPointToLocalPointInRectangle(rect.parent.GetComponent<RectTransform>(), screenPoint, cam, out localPoint);
}
localPoint = Vector2.zero;
return false;
}
}
程式碼這麼多,其實很簡單,就只呼叫CreateEffect
靜態函式就可以了,引數的意思也都有註釋。還有一個靜態類TRE
,主要是transform的擴充套件。
可以這樣
也可以這樣
甚至還可以這樣
當然你想怎樣就怎樣!!!
這個版本是無音效版的,如果需要請自行擴充套件。
相關文章
- UGUI動畫效果UGUI動畫
- unity3d UGUI教程之-UGUI 實現刮刮卡橡皮擦Unity3DUGUI
- 【Unity3D ugui】使用藝術字Unity3DUGUI
- unity3d表格模擬繪製Unity3D
- 純css模擬下雪效果CSS
- JavaScript模擬拋物效果JavaScript
- eMarketer:收穫大資料的果實很難大資料
- 模擬利用MV進行資料遷移
- 昨晚的收穫DB2DB2
- 參加開源專案的一些經驗和收穫
- 驗證append插入資料的額外收穫APP
- 利用WReal加速系統模擬
- js實現的模擬滾動條效果JS
- 【Unity3D】資源管理Unity3D
- 資料治理帶給我了什麼收穫?
- 利用Easy Mock簡單模擬開發資料介面Mock
- JavaScript模擬HashMap類效果程式碼JavaScriptHashMap
- js模擬實現列舉效果JS
- canvas模擬eharts首頁動畫效果Canvas動畫
- iOS粒子效果模擬器—UIEffectDesigneriOSUI
- unity3D 兩點拋物線模擬炮彈Unity3D
- 如何讓網站收穫好的排名?網站
- 利用Python模擬GitHub登入PythonGithub
- 利用類反射模擬內省功能反射
- 資料模擬神器 easy-mock 正式開源Mock
- 實現爆炸後的振動效果 (轉)
- jquery模擬實現的連結title提示效果jQuery
- 模擬實現的星星評分效果詳解
- Flutter實現簡單爆炸效果Flutter
- Unity3d實現的十字路口的模擬(一)Unity3D
- 前端專案重構的些許收穫前端
- 在創業型軟體公司的收穫創業
- 在alter database mount時的一點收穫Database
- 強大的CSS:模擬下雪效果動畫製作教程CSS動畫
- 案例:模擬京東快遞單號的查詢效果
- 利用MySQL日誌模擬恢復資料變化軌跡IIMySql
- Docker資源收錄Docker
- canvas模擬彈幕效果程式碼例項Canvas