天天看點

Unity 彈幕(NGUI)

多說無益,直接上代碼

彈幕控制類,建立空GameObject,添加以下腳本:

public class DlgBarrage : MonoBehaviour
{

    [Tooltip("文字最大速度")]
    public float LabelMaxSpeed = ;
    [Tooltip("文字最小速度")]
    public float LabelMinSpeed = ;

    [Tooltip("文字最大字号")]
    public int LabelMaxScoal = ;
    [Tooltip("文字最小字号")]
    public int LabelMinScoal = ;

    [Tooltip("同屏最大顯示")]
    public int MaxLabelNum = ;

    [Tooltip("Debug測試模式")]
    public bool IsDebug = false;

    [Tooltip("文字間隔時間")]
    public float BarrageInterval = f;

    //顔色随機數組
    [Tooltip("顔色數組")]
    public Color[] ColorRang;

    [Tooltip("彈幕文字GameObject")]
    public GameObject barrageLabelObj = null;

    //label緩存池
    [HideInInspector]
    [SerializeField]
    Queue<BarrageLabel> _mLablePool = new Queue<BarrageLabel>();

    [HideInInspector]
    [SerializeField]
    Queue<string> _mStringPool = new Queue<string>();

    // Use this for initialization
    void Start()
    {
        this.InitLabelPool();
        this.BarrageDebug();

        StartCoroutine(UpdateBarrage());
    }


    // Update is called once per frame
    void Update()
    {

    }

    void OnDestroy()
    {
        _mLablePool.Clear();
        _mLablePool = null;
        _mStringPool.Clear();
        _mStringPool = null;
    }

    public void OnMoveFinish(BarrageLabel barrageLabel)
    {
        _mLablePool.Enqueue(barrageLabel);
    }

    void InitLabelPool()
    {

        GameObject parent = barrageLabelObj.transform.parent.gameObject;
        GameObject Lable = null;
        for (int i = ; i < MaxLabelNum; ++i)
        {
            Lable = NGUITools.AddChild(parent, barrageLabelObj);
            BarrageLabel barrageLabel = Lable.GetComponent<BarrageLabel>();
            _mLablePool.Enqueue(barrageLabel);
            Lable.SetActive(false);
        }

        barrageLabelObj.SetActive(false);
    }

    IEnumerator UpdateBarrage()
    {
        while (true)
        {
            this.StartLabelBarrageLabel();
            yield return new WaitForSeconds(BarrageInterval);
        }
    }


    void StartLabelBarrageLabel()
    {
        if (_mLablePool.Count == )
        {
            return;
        }

        BarrageLabel barrageLabel = _mLablePool.Dequeue();
        string text = this.GetString();
        if (barrageLabel == null || text == null)
        {
            return;
        }

        int ColorIndex = UnityEngine.Random.Range(, ColorRang.Length - );
        barrageLabel.StatBarrage(text, ColorRang[ColorIndex],
            UnityEngine.Random.Range(LabelMinSpeed, LabelMaxSpeed),
            UnityEngine.Random.Range(LabelMinScoal, LabelMaxScoal));
    }

    string GetString()
    {
        string text = _mStringPool.Dequeue();
        if (IsDebug && _mStringPool.Count == )
        {
            this.BarrageDebug();
        }

        return text;
    }

    //插入顯示的文字  Lua調用
    public void InsertString(string text)
    {
        _mStringPool.Enqueue(text);
    }

    private void BarrageDebug()
    {
        if (IsDebug && _mStringPool.Count == )
        {
            string[] TestString = { "前方高能", "在這停頓", "狂暴的歡愉必将有狂暴的結局", "凍住,不許走", "吾王美如畫", "MIKU賽高" };
            for (int i = ; i < MaxLabelNum; ++i)
            {
                this.InsertString(TestString[i % TestString.Length]);
            }
        }
    }

    [ContextMenu("Execute")]
    public void Excute()
    {
        BroadcastMessage("DestoryLabel");

        _mLablePool.Clear();
        _mStringPool.Clear();
        this.InitLabelPool();
        this.BarrageDebug();
    }
}
           

彈幕文字代碼,在上邊的gameObject下建立一個gameObject,添加以下腳本。

public class BarrageLabel: MonoBehaviour
{
    [HideInInspector][SerializeField]UILabel _mLable;
    [HideInInspector][SerializeField]TweenPosition _mTweenPos;

    float ScreenWidth = ;
    float ScreenHeigh = ;
    float length = ;

    private void Awake()
    {
        _mLable = gameObject.GetComponent<UILabel>();
        _mTweenPos = gameObject.GetComponent<TweenPosition>();
        //this.transform.parent.gameObject.SetActive(false);

        UIRoot root = GameObject.FindObjectOfType<UIRoot>();
        if(root != null)
        {
            float s = (float)root.activeHeight / Screen.height;
            ScreenWidth = Mathf.CeilToInt(Screen.width * s);
            ScreenHeigh = Mathf.CeilToInt(Screen.height * s);
        }
    }

    public void PlayerTweenPos(float speed,float size)
    {
        float heigh = UnityEngine.Random.Range(-ScreenHeigh/ + size, ScreenHeigh/ - size);
        Vector3 from = new Vector3(ScreenWidth, heigh, );
        Vector3 to = new Vector3( -length - , heigh, );


        _mTweenPos.from = from;
        _mTweenPos.to = to;

        _mTweenPos.duration = ((from-to).magnitude)/(speed * );
        _mTweenPos.enabled = true;
        _mTweenPos.PlayForward();

        _mTweenPos.AddOnFinished(() =>
        {
            this.transform.gameObject.SetActive(false);
            this.SendMessageUpwards("OnMoveFinish",this);
            _mTweenPos.enabled = false;
            _mTweenPos.ResetToBeginning();
        });
    } 

    public void StatBarrage(string text,Color c,float speed,int fontSize)
    {
        _mLable.text = text;
        _mLable.color = c;
        _mLable.fontSize = fontSize;

        _mLable.width = fontSize * text.Length;
        _mLable.height = fontSize;

        this.transform.gameObject.SetActive(true);
        length = text.Length;
        this.PlayerTweenPos(speed, fontSize);
    }

    public void DestoryLabel()
    {
        Destroy(gameObject);
    }
}