最近看了泰斗破壞神的視頻,自己寫了個生成雲的腳本。我把雲這個sprite做成了預製。
上面有個Cloud腳本,Cloud腳本主要控制雲的透明度變化,移動方向,尺寸和速度,
雲在漂浮的時候會隨機發生透明度變化。當雲運動到了某一位置或者到了規
定的生存時間就會透明度逐漸減小,看不見的時候自動消失。
然後在UIRoot上面放了個CreateCloud腳本,用來控制雲的數量和生成速度。
看下CreateCloud參數:
一二項是最大最小速度,每朵雲中間取隨機值,
三四項是雲的預製,
五六項是製作雲的最大和最小間隔,每次製作完
取其中的隨機時間等待然後再次製作,
七八項是每次雲的alpha值變化的時間,
九十項是消失的最長和最短時間,每朵雲取中間的
隨機值作爲消失時間,
十一項爲畫面中最多的雲的數量,
十二十三項是雲存在的最長和最短時間,每朵雲的生存時間
取其中的隨機值,
十四十五項是雲的最大和最小Y值,每朵雲的Y值取其中的隨機值,
十六十七項是雲的最大和最小X值,每朵雲的最大和最小X值在其中取,
每朵雲在所取的X值中運動,當到達邊界X值時,雲自動消失,
十八十九項是每次雲的alpha值變化完成後到下一次變化
的時間。
CreateCloud腳本:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CreateCloud : MonoBehaviour {
static CreateCloud _instance;
public static CreateCloud Instance
{
get { return _instance; }
}
public float minCloudSpd;
public float maxCloudSpd;
public GameObject cloud1;
public GameObject cloud2;
public float maxCreateInterval;
public float minCreateInterval;
public float minAlphaInterval;
public float maxAlphaInterval;
public float minDestroyDur;
public float maxDestroyDur;
public int maxCloudCount;
public float minCloudExistTime;
public float maxCloudExistTime;
public float maxCloudFlyingY;
public float minCloudFlyingY;
public float maxCloudFlyingX;
public float minCloudFlyingX;
/// <summary>
/// 雲層漸變之間休息的最大時間
/// </summary>
public float maxCloudRestTime;
public float minCloudRestTime;
public List<Cloud> clouds=new List<Cloud>();
void Awake()
{
_instance = this;
}
// Use this for initialization
void Start () {
StartCoroutine(SpawnCloud());
}
IEnumerator SpawnCloud()
{
while (true)
{
if (clouds.Count<maxCloudCount)
{
RandomCloudCreate();
}
yield return new WaitForSeconds(Random.Range(minCreateInterval, maxCreateInterval));
}
}
void RandomCloudCreate()
{
GameObject go;
Cloud cloud;
int category = Random.Range(0, 2);
if (category == 0)
{
go=NGUITools.AddChild(gameObject,cloud1);
cloud = go.GetComponent<Cloud>();
}
else
{
go = NGUITools.AddChild(gameObject,cloud2);
cloud = go.GetComponent<Cloud>();
}
SetCloudProperty(cloud);
clouds.Add(cloud);
}
void SetCloudProperty(Cloud cloud)
{
cloud.cloudExistTime = Random.Range(minCloudExistTime, maxCloudExistTime);
cloud.destoyDur = Random.Range(minDestroyDur, maxDestroyDur);
cloud.minAlphaInterval = Random.Range(minAlphaInterval, maxAlphaInterval);
cloud.maxAlphaInterval = Random.Range(cloud.minAlphaInterval, maxAlphaInterval);
cloud.minPosX = Random.Range(minCloudFlyingX, maxCloudFlyingX);
cloud.maxPosX = Random.Range(cloud.minPosX, maxCloudFlyingX);
cloud.PosY = Random.Range(minCloudFlyingY, maxCloudFlyingY);
cloud.moveSpeed = Random.Range(minCloudSpd, maxCloudSpd);
cloud.minCloudRestTime = Random.Range(minCloudRestTime, maxCloudRestTime);
cloud.maxCloudRestTime = Random.Range(cloud.minCloudRestTime, maxCloudRestTime);
}
// Update is called once per frame
void Update () {
}
}
Cloud腳本:
using UnityEngine;
using System.Collections;
public class Cloud : MonoBehaviour
{
UISprite myCloudSprite;
public float cloudExistTime;
public float destoyDur;
float remainAlpha;
int myFlyingDir;
/// <summary>
/// 轉變狀態的最短時間
/// </summary>
public float minAlphaInterval;
/// <summary>
/// 轉變狀態的最長時間
/// </summary>
public float maxAlphaInterval;
public float maxCloudRestTime;
public float minCloudRestTime;
public float maxPosX;
public float minPosX;
public float PosY;
public float moveSpeed;
// Use this for initialization
void Start()
{
float x = Random.Range(0.8f, 2f);
float y = Random.Range(0.8f, 2f);
transform.localScale = new Vector3(x,y,1);
transform.localPosition = new Vector3(Random.Range(minPosX,maxPosX),PosY);
myCloudSprite = GetComponent<UISprite>();
myCloudSprite.alpha = 0;
int i = Random.Range(0, 2);
if (i==0)
{
myFlyingDir = -1;
}
else
{
myFlyingDir = 1;
}
StartCoroutine(AlphaGradientStart());
InvokeRepeating("DetectPos", 0.2f, 0.2f);
}
void DetectPos()
{
if (transform.localPosition.x > maxPosX)
{
Destroy();
}
if (transform.localPosition.x < minPosX)
{
Destroy();
}
}
IEnumerator AlphaGradientStart()
{
float alphaGradientDur = Random.Range(minAlphaInterval, maxAlphaInterval);
float alpha=Random.Range(0f,1f);
if (myCloudSprite.alpha >= alpha)
{
while (myCloudSprite.alpha >= alpha)
{
myCloudSprite.alpha -= Time.deltaTime / alphaGradientDur;
yield return null;
}
}else if (myCloudSprite.alpha <= alpha)
{
while (myCloudSprite.alpha <= 1)
{
myCloudSprite.alpha += Time.deltaTime / alphaGradientDur;
yield return null;
}
}
Invoke("Destroy", cloudExistTime);
StartCoroutine(AlphaGradientRest());
}
IEnumerator AlphaGradientRest()
{
float timeToRest = Random.Range(minCloudRestTime, maxCloudRestTime);
yield return new WaitForSeconds(timeToRest);
StartCoroutine(AlphaGradientStart());
}
void Destroy()
{
StopAllCoroutines();
StartCoroutine(Miss());
}
IEnumerator Miss()
{
remainAlpha = myCloudSprite.alpha;
while (myCloudSprite.alpha >=0.03f)
{
myCloudSprite.alpha -= remainAlpha*Time.deltaTime / destoyDur;
yield return 0;
}
Destroy(gameObject);
}
// Update is called once per frame
void Update()
{
transform.Translate(new Vector3(myFlyingDir * Time.deltaTime * moveSpeed, 0, 0));
}
void OnDestroy()
{
CreateCloud.Instance.clouds.Remove(this);
}
}