中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【小松教你手游開發】【系統模塊開發】圖文混排 (在label中插入表情)

發布時間:2020-03-08 06:46:16 來源:網絡 閱讀:295 作者:xiaosongfang 欄目:游戲開發

本身ngui是自帶圖文混排的,這個可以在ngui的Example里找到。但是為什么不能用網上已經說得很清楚,比如雨松momo的http://www.xuanyusong.com/archives/2908

最重要的一點就是我們肯定不會選擇一個完整的中文字庫,動態字體無辦法使用ngui的圖文混排

所以還是需要自己寫一個圖文混排。

首先圖文混排的基本邏輯是:

1.定義固定字符串格式作為圖片信息。

2.找到文字中的圖片信息的字符串提取并換成空格

3.根據圖片信息生成uisprite,并放在適當的position

4.輸出文字和圖片

圖文混排有幾個重點是必須解決的:

1.找到圖片應該放的position

2.如果圖片在文字末尾判斷是否放得下是否會被遮擋,是的話要把圖片放到下一行的開頭

3.按照圖片的高度判斷這一行的開頭需要多少個換行符

4.如果一排有多個圖片且尺寸不一,這一排的圖片需要統一高度,不然會出現下面的情況

(如果圖片格式統一的話3,4倒是可以用湊合的辦法省略,但是我們想做一個適用各種大小圖片,每行可能有幾張圖片,適合各種情況的圖文混排)

接下來就是實現。

我的思路是:

有一大段文字且里面有許多圖片信息的前提下

1.首先把所有文字輸入都某個函數,識別出第一個圖片信息的字符串,把這個包含圖片信息的字符串以及前面的文字裁剪下來,和裁剪以后的文字形成兩部分。

2.把裁剪的前面部分(包含圖片信息)分析出圖片信息,各種計算,最后得到圖片的position,生成gameObject并擺放好。保存各種信息。圖片部分用空格留出位置,形成新的字符串,和裁剪的第二部分的文字組合成新文字。

3.輸入到1里的那個函數。遞歸。

4.最終一次過輸出所有文字。

代碼直接寫到UILabel.cs里,也可以寫一個UIEmotionLabel.cs繼承UILabel.cs。

接下來看代碼:(最后會貼出所有代碼)

/// <summary>  
/// label中有表情在顯示前調用進行轉換  
/// </summary>  
public void ShowEmotionLabel()  
{  
    m_newEmotionText = "";  
    string originalText = MyLabel.text;  

    //遞歸找表情并生成文字  
    CutAndShowEmotionLabel(originalText);  

    //輸出文字  
    MyLabel.text = m_newEmotionText;  
    MyLabel.UpdateNGUIText();  

    //每一行的表情重新排序對其  
    SortAllSprite();  
}  

這個是唯一外部調用接口,當要顯示圖片的時候調用這個函數。

通過注釋就可以看懂里面的邏輯,最后的SortAllSprite()最后會再解釋一下。

所以先看CutAndShowEmotionLabel(string str)這個函數。

void CutAndShowEmotionLabel(string str)  
   {  
       EmotionData emoData = GetEmotionData(str);//解析str中的第一個表情字符串  

       if (emoData != null)  
       {  
           m_spriteList.Add(emoData);  

           //把str按第一個表情字符串的最后一個字母分成兩部分  
           string trimString = str.Substring(0, emoData.end_index);  
           string trimLeftString = str.Substring(emoData.end_index);  

           //生成表情和表情前面的文字部分  
           GenEmotionLabel(emoData, trimString);  
           m_newEmotionText = m_newEmotionText + trimLeftString;  

           //遞歸繼續找表情  
           CutAndShowEmotionLabel(m_newEmotionText);  
       }  
       else  
       {  
           //找不到表情返回,最后確定文字輸出  
           m_newEmotionText =str;  
           return;  
       }  

   }  

第一行就是用自己的方法解析。

上面的邏輯就是按思路寫的

唯一有點不一樣的就是多了一個m_spriteList.Add(emoData);

因為最后需要把所有圖片按每行輸出時可能要對其高度,所以都要先保存下來。

這里面最重要的是GenEmotionLabel(emoData, trimString);這個函數

void GenEmotionLabel(EmotionData emoData, string tramString)  
{  
    //生成gameobject  
    GameObject go = CreateEmotionSprite(emoData);  
    float spriteWidth = NGUIMath.CalculateRelativeWidgetBounds(gameobject.transform, go.transform, true).size.x / go.transform.localScale.x;  
    float spriteHeight = NGUIMath.CalculateRelativeWidgetBounds(gameobject.transform, go.transform, true).size.y / go.transform.localScale.y;  

    //計算出圖片的位置,判斷文字的轉換和空格  
    Vector3 position = CalcuEmotionSpritePosition(tramString, emoData.start_index, spriteWidth, spriteHeight);  

    //擺放圖片位置  
    PlaceEmotionSprite(go, position);  

    m_spriteList[m_spriteList.Count - 1].go = go;  
}  

CreateEmotionSprite()就是根據分析出來的圖片信息實例化一個GameObject,但是這時候position位置還是不能確定。

在算出圖片的寬高后。把這些數據都輸入到CalcuEmotionSpritePosition();這個函數里算出最后的position。

獲得position數據在PlaceEmotionSprite()函數正確的擺放
所以這里最關鍵的還是CalcuEmotionSpritePosition()。

Vector3 CalcuEmotionSpritePosition(string str, int startIndex, float spriteWidth, float spriteHeight)  
{  
    Vector3 position = GenBlankString(str, startIndex, spriteWidth, spriteHeight);  
    return position;  
}  

這里看GenBlankString()函數。

Vector3 GenBlankString(string str, int startIndex, float spriteWidth, float spriteHeight)  
   {  
       int finalIndex = startIndex;  

       BetterList<Vector3> tempVerts = new BetterList<Vector3>();  
       BetterList<int> tempIndices = new BetterList<int>();  

       //1.把圖片信息換成空格  
       string emontionText = str.Substring(startIndex);  
       int blankNeedCount = CaculateBlankNeed(spriteWidth);  
       str = str.Replace(emontionText, GenBlank(blankNeedCount));  
       //把換好的文字放回label再計算sprite應該放的坐標,  
       UpdateCharacterPosition(str,out tempVerts,out tempIndices);  

       //2.如果在label末尾且圖片放不下,判斷是否換行  
       bool needWrap = NeedWrap(tempVerts, tempIndices, startIndex, startIndex + blankNeedCount);  
       if (needWrap)  
       {  
           str = str.Insert(startIndex, "\n");  
           finalIndex +=1;  

           //重新計算當前所有字符的位置  
           UpdateCharacterPosition(str, out tempVerts, out tempIndices);  
       }  

       //3.按圖片的高,生成回車(換行)  
       int returnCount = GenCarriageReturn(tempVerts, tempIndices, ref str, finalIndex, spriteHeight, needWrap);  
       finalIndex += returnCount;  

       //4.重新賦值要輸出的str  
       m_newEmotionText = str;  

       //重新計算當前所有字符的位置  
       UpdateCharacterPosition(str, out tempVerts, out tempIndices);  

       //保存行數,最后重新排放每行的圖片使用  
       m_spriteList[m_spriteList.Count - 1].line_index = CalcuLineIndex(tempVerts, tempIndices, startIndex) - lastScale;  

       //最終計算圖片該放的位置  
       Vector3 position = new Vector3();  
       if (needWrap)  
       {  
           position = new Vector3(tempVerts[0].x, tempVerts[GetIndexFormIndices(finalIndex, tempIndices)].y, tempVerts[0].z);  
       }  
       else  
       {  
           position = tempVerts[GetIndexFormIndices(finalIndex, tempIndices)];  
       }  

       return position;  
   }  

先介紹一下NGUI提供的計算每個字符在字符串中位置的函數。

NGUIText.PrintCharacterPositions(str, tempVerts, tempIndices);

輸入str,輸出tempVerts,tempIndices。通過這兩個變量獲取每個字符的position信息

這里我封裝了個函數通過字符在字符串中的index來獲取在tempVerts中index_v,繼而通過tempVerts[index_v]獲取vecter3

int GetIndexFormIndices(int index, BetterList<int> list)  
{  
    for (int i = 0; i < list.size; i++)  
        if (list[i] == index)  
            return i;  
    return 0;  
}  

我把NGUIText.PrintCharacterPositions(str, tempVerts, tempIndices)的用法寫成一個接口。

void UpdateCharacterPosition(string str,out BetterList<Vector3> verts,out BetterList<int> indices)  
{  
    //把換好的文字放回label再計算sprite應該放的坐標,  
    //計算當前所有字符的位置  
    MyLabel.text = str;  
    MyLabel.UpdateNGUIText();  
    BetterList<Vector3> tempVerts = new BetterList<Vector3>();  
    BetterList<int> tempIndices = new BetterList<int>();  
    NGUIText.PrintCharacterPositions(str, tempVerts, tempIndices);  

    verts = tempVerts;  
    indices = tempIndices;  
}  

這個接口的意思就是把str放到label里,讓NGUI重新擺放一下文字,之后調用PrintCharacterPositions,返回這兩個變量,就更新了位置信息。這時候就可以取得每個字符的位置信息,也就是圖片將要擺放的位置。(在每次改變文字后都要重新調用才能確定位置準確)

回到上面的GenBlankString().

1.首先根據圖片寬度計算需要多少個空格來預留出位置。調用UpdateCharacterPosition()更新,重新獲得位置信息(這部分我暫時是估算哈,比如5像素1空格)

2.判斷是否需要換行。調用UpdateCharacterPosition()更新,重新獲得位置信息(判斷圖片信息字符串(已換成空格)的第一個字符和最后一個字符是否在同一行,如果不同行證明要換行)
3.按圖片的高,生成換行符。調用UpdateCharacterPosition()更新,重新獲得位置信息
4.這時文字已經確定不會再添加任何符號,所以重新復制最終要輸出的文字m_newEmotionText = str;

步驟3需要特別講一下:

int lastScale = 1;  
   int lastIndex = 0;  
   int GenCarriageReturn(BetterList<Vector3> vectList, BetterList<int> indexList, ref string str, int startIndex, float spriteHeight, bool isWrap)  
   {  
       float fontSize = MyLabel.fontSize * gameobject.transform.localScale.x;  

       int scale = Mathf.CeilToInt(spriteHeight / fontSize) - 1;  

       if (CheckIfSameLine(vectList, indexList, startIndex, lastIndex))  
       {  
           if (lastScale < scale)  
           {  
               scale = scale - lastScale;  
               lastScale = scale + lastScale;  
           }  
           else  
           {  
               scale = 0;  
           }  
       }  
       else  
       {  
           lastScale = scale;  
       }  
       lastIndex = startIndex;  

       string CarriageReturn = "";  
       for (int i = 0; i < scale; i++)  
       {  
           CarriageReturn = CarriageReturn + '\n';  
           lastIndex += 1;  
       }  

       //if(CheckIfIsLineFirstCharacter(vectList, indexList, startIndex))  
       //{  
       //    CarriageReturn = CarriageReturn + '\n';  
       //    scale += 1;  
       //}  

       if (!isWrap && scale > 0)  
       {  
           CarriageReturn = CarriageReturn + '\n';  
           scale += 1;  
           lastIndex += 1;  
           lastScale += 1;  
       }  

       str = str.Insert(FindLineFirstIndex(vectList, indexList, startIndex) - 1, CarriageReturn);  

       return scale;  
   }  

可以看到在scale就是我需要多少個換行符。

接著下面的邏輯是如果這次判斷的startIndex(這個圖片的第一個字符)和上次lastIndex(上一個圖片的第一個字符)如果是同一行的話,需要判斷后面的圖片有沒有比前面的更大,如果更大需要判斷大多少,還需要多少個回車。

因為如果同一行內多個圖片的大小不一,只取最大的圖片的大小生成換行符。

再后面是判斷,有種情況是本身文字放到label剛好處于文字末尾(就是本身就需要一個換行符),所以如果是這種情況需要再插入一個換行符。

接著就把換行符插入到這一行的第一個字符前(還是通過位置信息去判斷這行的第一個字符)

這個就是判斷圖片位置的邏輯,然后就一遍遍的遞歸把所有圖片找出來放置好。

最后還需要把每一行的圖片檢索一下,同一行有多個圖片時,所有圖片的y軸都跟最后一個對齊(因為最后一個的y軸肯定是最低的,要跟最低的對齊)

void SortAllSprite()  
{  
    for (int i = m_spriteList.Count - 1; i > 0; i--)  
    {  
        if (m_spriteList[i].line_index == m_spriteList[i - 1].line_index)  
        {  
            m_spriteList[i - 1].pos.y = m_spriteList[i].pos.y;  
            m_spriteList[i - 1].go.transform.localPosition = m_spriteList[i - 1].pos;  
        } 
    }  
}  

這樣就完成了圖文混排。

下面是所有代碼(掛在UILabel.cs上, UILabel的代碼不顯示)

string m_newEmotionText = "";  
List<EmotionData> m_spriteList = new List<EmotionData>();  

/// <summary>  
/// label中有表情在顯示前調用進行轉換  
/// </summary>  
public void ShowEmotionLabel()  
{  
    m_newEmotionText = "";  
    string originalText = MyLabel.text;  

    //遞歸找表情并生成文字  
    CutAndShowEmotionLabel(originalText);  

    //輸出文字  
    MyLabel.text = m_newEmotionText;  
    MyLabel.UpdateNGUIText();  

    //每一行的表情重新排序對其  
    SortAllSprite();  
}  

#region 圖文混排輔助函數  
void CutAndShowEmotionLabel(string str)  
{  
    EmotionData emoData = GetEmotionData(str);//解析str中的第一個表情字符串  

    if (emoData != null)  
    {  
        m_spriteList.Add(emoData);  

        //把str按第一個表情字符串的最后一個字母分成兩部分  
        string trimString = str.Substring(0, emoData.end_index);  
        string trimLeftString = str.Substring(emoData.end_index);  

        //生成表情和表情前面的文字部分  
        GenEmotionLabel(emoData, trimString);  
        m_newEmotionText = m_newEmotionText + trimLeftString;  

        //遞歸繼續找表情  
        CutAndShowEmotionLabel(m_newEmotionText);  
    }  
    else  
    {  
        //找不到表情返回,最后確定文字輸出  
        m_newEmotionText =str;  
        return;  
    }  

}  

void GenEmotionLabel(EmotionData emoData, string tramString)  
{  
    //生成gameobject  
    GameObject go = CreateEmotionSprite(emoData);  
    float spriteWidth = NGUIMath.CalculateRelativeWidgetBounds(gameobject.transform, go.transform, true).size.x / go.transform.localScale.x;  
    float spriteHeight = NGUIMath.CalculateRelativeWidgetBounds(gameobject.transform, go.transform, true).size.y / go.transform.localScale.y;  

    //計算出圖片的位置,判斷文字的轉換和空格  
    Vector3 position = CalcuEmotionSpritePosition(tramString, emoData.start_index, spriteWidth, spriteHeight);  

    //擺放圖片位置  
    PlaceEmotionSprite(go, position);  

    m_spriteList[m_spriteList.Count - 1].go = go;  
}  

int lastScale = 1;  
int lastIndex = 0;  
int GenCarriageReturn(BetterList<Vector3> vectList, BetterList<int> indexList, ref string str, int startIndex, float spriteHeight, bool isWrap)  
{  
    float fontSize = MyLabel.fontSize * gameobject.transform.localScale.x;  

    int scale = Mathf.CeilToInt(spriteHeight / fontSize) - 1;  

    if (CheckIfSameLine(vectList, indexList, startIndex, lastIndex))  
    {  
        if (lastScale < scale)  
        {  
            scale = scale - lastScale;  
            lastScale = scale + lastScale;  
        }  
        else  
        {  
            scale = 0;  
        }  
    }  
    else  
    {  
        lastScale = scale;  
    }  
    lastIndex = startIndex;  

    string CarriageReturn = "";  
    for (int i = 0; i < scale; i++)  
    {  
        CarriageReturn = CarriageReturn + '\n';  
        lastIndex += 1;  
    }  

    //if(CheckIfIsLineFirstCharacter(vectList, indexList, startIndex))  
    //{  
    //    CarriageReturn = CarriageReturn + '\n';  
    //    scale += 1;  
    //}  

    if (!isWrap && scale > 0)  
    {  
        CarriageReturn = CarriageReturn + '\n';  
        scale += 1;  
        lastIndex += 1;  
        lastScale += 1;  
    }  

    str = str.Insert(FindLineFirstIndex(vectList, indexList, startIndex) - 1, CarriageReturn);  

    return scale;  
}  

Vector3 CalcuEmotionSpritePosition(string str, int startIndex, float spriteWidth, float spriteHeight)  
{  
    Vector3 position = GenBlankString(str, startIndex, spriteWidth, spriteHeight);  
    return position;  
}  

Vector3 GenBlankString(string str, int startIndex, float spriteWidth, float spriteHeight)  
{  
    int finalIndex = startIndex;  

    BetterList<Vector3> tempVerts = new BetterList<Vector3>();  
    BetterList<int> tempIndices = new BetterList<int>();  

    //1.把圖片信息換成空格  
    string emontionText = str.Substring(startIndex);  
    int blankNeedCount = CaculateBlankNeed(spriteWidth);  
    str = str.Replace(emontionText, GenBlank(blankNeedCount));  
    //把換好的文字放回label再計算sprite應該放的坐標,  
    UpdateCharacterPosition(str,out tempVerts,out tempIndices);  

    //2.如果在label末尾且圖片放不下,判斷是否換行  
    bool needWrap = NeedWrap(tempVerts, tempIndices, startIndex, startIndex + blankNeedCount);  
    if (needWrap)  
    {  
        str = str.Insert(startIndex, "\n");  
        finalIndex +=1;  

        //重新計算當前所有字符的位置  
        UpdateCharacterPosition(str, out tempVerts, out tempIndices);  
    }  

    //3.按圖片的高,生成回車(換行)  
    int returnCount = GenCarriageReturn(tempVerts, tempIndices, ref str, finalIndex, spriteHeight, needWrap);  
    finalIndex += returnCount;  

    //4.重新賦值要輸出的str  
    m_newEmotionText = str;  

    //重新計算當前所有字符的位置  
    UpdateCharacterPosition(str, out tempVerts, out tempIndices);  

    //保存行數,最后重新排放每行的圖片使用  
    m_spriteList[m_spriteList.Count - 1].line_index = CalcuLineIndex(tempVerts, tempIndices, startIndex) - lastScale;  

    //最終計算圖片該放的位置  
    Vector3 position = new Vector3();  
    if (needWrap)  
    {  
        position = new Vector3(tempVerts[0].x, tempVerts[GetIndexFormIndices(finalIndex, tempIndices)].y, tempVerts[0].z);  
    }  
    else  
    {  
        position = tempVerts[GetIndexFormIndices(finalIndex, tempIndices)];  
    }  

    return position;  
}  

GameObject CreateEmotionSprite(EmotionData data)  
{  
    GameObject go = new GameObject("(clone)emotion_sprite");  
    go.transform.parent = gameobject.transform;  

    UISprite sprite = go.AddComponent<UISprite>();  
    sprite.atlas = CResourceManager.Instance.GetAtlas(data.atlas_name);  
    sprite.spriteName = data.sprite_name;  
    sprite.MakePixelPerfect();  
    sprite.pivot = UIWidget.Pivot.BottomLeft;  

    float scaleFactor = 1 / gameobject.transform.localScale.x;  
    go.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);//字體可能縮小了0.5,所以掛在字體下要放大2倍  

    go.transform.localPosition = new Vector3(5000, 5000, 0);//先把它放到看不見的地方  

    return go;  
}  

void PlaceEmotionSprite(GameObject go, Vector3 position)  
{  
    float fontSize = MyLabel.fontSize * gameobject.transform.localScale.x;  

    float div = fontSize * go.transform.localScale.x / 2;  

    Vector3 newPosition = new Vector3(position.x, position.y - div, position.z);  
    //Vector3 newPosition = position;  
    go.transform.localPosition = newPosition;  

    m_spriteList[m_spriteList.Count - 1].pos = newPosition;  
}  

EmotionData GetEmotionData(string text)  
{  
    EmotionData tempData = null;  
    int index = text.IndexOf("%p");  
    if (index != -1)  
    {  
        tempData = new EmotionData();  
        tempData.start_index = index;  

        int altasEndIndex = text.IndexOf("$", index);  
        tempData.atlas_name = text.Substring(index + 2, altasEndIndex - (index + 2));  

        int spriteEndIndex = text.IndexOf("$", altasEndIndex + 1);  
        tempData.sprite_name = text.Substring(altasEndIndex + 1, spriteEndIndex - (altasEndIndex + 1));  

        tempData.end_index = spriteEndIndex + 1;  
    }  
    return tempData;  
}  

int GetIndexFormIndices(int index, BetterList<int> list)  
{  
    for (int i = 0; i < list.size; i++)  
        if (list[i] == index)  
            return i;  
    return 0;  
}  

int CaculateBlankNeed(float spriteWidth)  
{  
    int count = Mathf.CeilToInt(spriteWidth / (float)6);  
    return count;  
}  

string GenBlank(int count)  
{  
    string blank = "";  
    for (int i = 0; i < count; i++)  
    {  
        blank = blank + " ";  
    }  
    return blank;  
}  

bool NeedWrap(BetterList<Vector3> vecList, BetterList<int> indicList, int startIndex, int endIndex)  
{  
    int startIndic = GetIndexFormIndices(startIndex, indicList);  
    int endIndic = GetIndexFormIndices(endIndex, indicList);  

    if (vecList[startIndic].y == vecList[endIndic].y)  
        return false;  
    else  
        return true;  
}  

bool CheckIfSameLine(BetterList<Vector3> vecList, BetterList<int> indicList, int firstIndex, int SecondIndex)  
{  
    int firstIndic = GetIndexFormIndices(firstIndex, indicList);  
    int secondIndic = GetIndexFormIndices(SecondIndex, indicList);  

    if (vecList[firstIndic].y == vecList[secondIndic].y)  
        return true;  
    else  
        return false;  
}  

int FindLineFirstIndex(BetterList<Vector3> vecList, BetterList<int> indicList, int index)  
{  
    int startIndic = GetIndexFormIndices(index, indicList);  
    if (startIndic > 1)  
    {  
        if (vecList[startIndic].y == vecList[startIndic - 1].y)  
            index = FindLineFirstIndex(vecList, indicList, index - 1);  
        else  
            return index;  
    }  
    else  
    {  
        return 1;  
    }  
    return index;  
}  

int CalcuLineIndex(BetterList<Vector3> vecList, BetterList<int> indicList, int index)  
{  
    int startIndic = GetIndexFormIndices(index, indicList);  
    int count = 0;  
    float lastVecY = 0;  
    for (int i = 0; i < vecList.size; i++)  
    //for (int i =0;i< startIndic; i++)  
    {  
        if (lastVecY != vecList[i].y)  
        {  
            count++;  
            lastVecY = vecList[i].y;  
        }  
    }  
    return count;  
}  

bool CheckIfIsLineFirstCharacter(BetterList<Vector3> vecList, BetterList<int> indicList, int index)  
{  
    int startIndic = GetIndexFormIndices(index, indicList);  
    if (startIndic > 1)  
    {  
        if (vecList[startIndic].y == vecList[startIndic - 1].y)  
            return false;  
        else  
            return true;  
    }  
    else  
    {  
        return false;  
    }  
}  

void SortAllSprite()  
{  
    for (int i = m_spriteList.Count - 1; i > 0; i--)  
    {  
        if (m_spriteList[i].line_index == m_spriteList[i - 1].line_index)  
        {  
            m_spriteList[i - 1].pos.y = m_spriteList[i].pos.y;  
            m_spriteList[i - 1].go.transform.localPosition = m_spriteList[i - 1].pos;  
        }  

    }  
}  

void UpdateCharacterPosition(string str,out BetterList<Vector3> verts,out BetterList<int> indices)  
{  
    //把換好的文字放回label再計算sprite應該放的坐標,  
    //計算當前所有字符的位置  
    MyLabel.text = str;  
    MyLabel.UpdateNGUIText();  
    BetterList<Vector3> tempVerts = new BetterList<Vector3>();  
    BetterList<int> tempIndices = new BetterList<int>();  
    NGUIText.PrintCharacterPositions(str, tempVerts, tempIndices);  

    verts = tempVerts;  
    indices = tempIndices;  
}  
#endregion  

補上EmotionData類


public class EmotionData  
{  
    public int start_index;  
    public int end_index;  
    public string atlas_name;  
    public string sprite_name;  
    public float sprite_width;  

    public int line_index;  
    public Vector3 pos;  
    public GameObject go;  
}  
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长沙县| 任丘市| 三江| 平昌县| 巫溪县| 日照市| 奉贤区| 桐梓县| 马山县| 仪征市| 池州市| 海丰县| 二连浩特市| 大田县| 桐庐县| 监利县| 阿巴嘎旗| 宁津县| 理塘县| 永胜县| 迭部县| 阿拉善右旗| 霍邱县| 满洲里市| 西乌珠穆沁旗| 沅江市| 武义县| 全州县| 凤山市| 河西区| 长丰县| 张掖市| 汉阴县| 自治县| 秭归县| 寻甸| 阿克苏市| 延津县| 镇宁| 胶州市| 抚宁县|