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的擴充套件。
可以這樣
也可以這樣
甚至還可以這樣
當然你想怎樣就怎樣!!!
這個版本是無音效版的,如果需要請自行擴充套件。
相關文章
- 【Unity】UGUI模擬NGUI的UISprite-->LImageUnityUGUINGUI
- 海軍的 2021年終總結, 跳槽後,我收穫了什麼
- 【Unity3D】資源管理Unity3D
- 純css模擬下雪效果CSS
- JavaScript模擬拋物效果JavaScript
- 每次的挫敗,都是收穫
- Flutter實現簡單爆炸效果Flutter
- unity3D 兩點拋物線模擬炮彈Unity3D
- 有點收穫了。
- 利用WReal加速系統模擬
- 利用Python模擬GitHub登入PythonGithub
- 2019 年的收穫與成長
- 利用Easy Mock簡單模擬開發資料介面Mock
- 坐擁海島修身養性 休閒養成《海島故事》正式發售
- 資料治理帶給我了什麼收穫?
- canvas模擬eharts首頁動畫效果Canvas動畫
- 如何讓網站收穫好的排名?網站
- android p 模擬器開啟劉海模式Android模式
- 利用 VModule webpack plugin 建立虛擬模組WebPlugin
- 利用cache特性檢測Android模擬器Android
- 2024.9.28 程式碼源模擬賽
- 案例:模擬京東快遞單號的查詢效果
- 強大的CSS:模擬下雪效果動畫製作教程CSS動畫
- 這幾年來我建站的3大收穫
- 基於AFDPF主動頻率偏移法的孤島檢測Simulink模擬
- 網易《海島紀元》海外上線 這款“海島冒險MMO”是如何打造品類差異化的?
- 20241101 資料結構與演算法期中機試收穫資料結構演算法
- 利用IT++搭建通訊模擬平臺(C++)C++
- 利用canvas生成海報Canvas
- 浪起來!使用 drawBitmapMesh 實現模擬水波紋效果
- 2017-07-13今天研究jquery原始碼的收穫jQuery原始碼
- 工作間隙整理學習內容的意外收穫
- 關於2021年的一些收穫和思考
- 《珊瑚島》:在愜意的農場模擬中重新定義遊戲體裁遊戲
- Flink - 合理利用 cpu 資源
- 模擬經營類遊戲《島與工廠》商店頁面上線steam遊戲
- 如何利用Ptrace攔截和模擬Linux系統呼叫Linux
- jtalk第七期前端場–收穫分享前端
- 堅持就有收穫,厲害,贊一個