void makeImage(GameObject img, LRenderElement elem) { Image comImage = img.GetComponent <Image>(); comImage.color = Color.white; if (comImage != null) { Sprite sp = AssetBundleManager.godLoader.Load(GameResType.Emote, PathUtil.GetFileNameWithoutExtension(elem.path), typeof(Sprite)) as Sprite; comImage.sprite = sp; } }
void makeFramAnim(GameObject anim, LRenderElement elem) { LMovieClip comFram = anim.GetComponent <LMovieClip>(); if (comFram != null) { comFram.path = elem.path; comFram.fps = elem.fs; comFram.frameLength = elem.frameCount; comFram.loadTexture(); comFram.play(); } }
void makeLabel(GameObject lab, LRenderElement elem) { Text comText = lab.GetComponent <Text>(); if (comText != null) { comText.text = elem.strChar; comText.font = elem.font; comText.fontSize = elem.fontSize; comText.fontStyle = FontStyle.Normal; comText.color = elem.color; } Outline outline = lab.GetComponent <Outline>(); if (elem.isOutLine) { if (outline == null) { outline = lab.AddComponent <Outline>(); } } else { if (outline) { Destroy(outline); } } if (elem.isUnderLine) { GameObject underLine = getCacheImage(false); Image underImg = underLine.GetComponent <Image>(); underImg.sprite = null; underImg.color = elem.color; underImg.GetComponent <RectTransform>().sizeDelta = new Vector2(comText.preferredWidth, 2); underLine.transform.SetParent(transform); underLine.transform.localPosition = Vector3.zero; RectTransform rect = underLine.transform as RectTransform; rect.anchoredPosition = new Vector2(elem.pos.x, elem.pos.y); rect.localScale = new Vector3(1, 1, 1); //underLine.transform.localPosition = new Vector2(elem.pos.x, elem.pos.y); } }
protected void formarRenderers() { int oneLine = 0; int lines = 1; bool isReplaceInSpace = false; int len = _elemRenderArr.Count; //这里开始根据刚才已经拆解过的单个元素的长宽,以及每行的最大宽度maxLineWidth //从而确定每个元素在每一行的大致相对位置 for (int i = 0; i < len; i++) { isReplaceInSpace = false; LRenderElement elem = _elemRenderArr[i]; if (elem.isNewLine) // new line { oneLine = 0; lines++; elem.width = 10; elem.height = 27; elem.pos = new Vector2(oneLine, -lines * 27); } else //other elements { if (oneLine + elem.width > maxLineWidth) { if (elem.type == RichType.TEXT) { //if (isChinese(elem.strChar) || elem.strChar == " ") //{ oneLine = 0; lines++; elem.pos = new Vector2(oneLine, -lines * 27); oneLine = elem.width; //} //else // en //{ // int spaceIdx = 0; // int idx = i; // while (idx > 0) // { // idx--; // if (_elemRenderArr[idx].strChar == " " && // _elemRenderArr[idx].pos.y == _elemRenderArr[i-1].pos.y ) // just for the same line // { // spaceIdx = idx; // break; // } // } // // can't find space , force new line // if (spaceIdx == 0) // { // oneLine = 0; // lines++; // elem.pos = new Vector2(oneLine, -lines * 27); // oneLine = elem.width; // } // else // { // oneLine = 0; // lines++; // isReplaceInSpace = true; //reset cuting words position // for (int _i = spaceIdx +1; _i <= i; ++_i) // { // LRenderElement _elem = _elemRenderArr[_i]; // _elem.pos = new Vector2(oneLine, -lines * 27); // oneLine += _elem.width; // _elemRenderArr[_i] = _elem; // } // } //} } else if (elem.type == RichType.ANIM || elem.type == RichType.IMAGE) { lines++; elem.pos = new Vector2(0, -lines * 27); oneLine = elem.width; } } else { elem.pos = new Vector2(oneLine, -lines * 27); oneLine += elem.width; } } if (isReplaceInSpace == false) { _elemRenderArr[i] = elem; } } //sort all lines //根据每个元素的大致位置,确定最终的行数以及每一行所包含的所有元素 Dictionary <int, List <LRenderElement> > rendElemLineMap = new Dictionary <int, List <LRenderElement> >(); List <int> lineKeyList = new List <int>(); len = _elemRenderArr.Count; for (int i = 0; i < len; i++) { LRenderElement elem = _elemRenderArr[i]; List <LRenderElement> lineList; if (!rendElemLineMap.ContainsKey((int)elem.pos.y)) { lineList = new List <LRenderElement>(); rendElemLineMap[(int)elem.pos.y] = lineList; } rendElemLineMap[(int)elem.pos.y].Add(elem); } // all lines in arr List <List <LRenderElement> > rendLineArrs = new List <List <LRenderElement> >(); foreach (var item in rendElemLineMap) { lineKeyList.Add(-1 * item.Key); } lineKeyList.Sort(); len = lineKeyList.Count; //这里开始将单个的元素再组装成一个渲染单元(String,Image,Anim等) for (int i = 0; i < len; i++) { int posY = -1 * lineKeyList[i]; string lineString = ""; LRenderElement _lastEleme = rendElemLineMap[posY][0]; LRenderElement _lastDiffStartEleme = rendElemLineMap[posY][0]; if (rendElemLineMap[posY].Count > 0) { List <LRenderElement> lineElemArr = new List <LRenderElement>(); foreach (LRenderElement elem in rendElemLineMap[posY]) { if (_lastEleme.type == RichType.TEXT && elem.type == RichType.TEXT) { if (_lastEleme.color == elem.color && _lastEleme.data == elem.data) { // the same color can mergin one string lineString += elem.strChar; } else // diff color { if (_lastDiffStartEleme.type == RichType.TEXT) { LRenderElement _newElem = _lastDiffStartEleme.Clone(); _newElem.strChar = lineString; lineElemArr.Add(_newElem); _lastDiffStartEleme = elem; lineString = elem.strChar; } } } else if (elem.type == RichType.IMAGE || elem.type == RichType.ANIM || elem.type == RichType.NEWLINE) { //interrupt if (_lastDiffStartEleme.type == RichType.TEXT) { LRenderElement _newEleme = _lastDiffStartEleme.Clone(); _newEleme.strChar = lineString; lineString = ""; lineElemArr.Add(_newEleme); } lineElemArr.Add(elem); } else if (_lastEleme.type != RichType.TEXT) { //interrupt _lastDiffStartEleme = elem; if (elem.type == RichType.TEXT) { lineString = elem.strChar; } } _lastEleme = elem; } // the last elementText if (_lastDiffStartEleme.type == RichType.TEXT) { LRenderElement _newElem = _lastDiffStartEleme.Clone(); _newElem.strChar = lineString; lineElemArr.Add(_newElem); } rendLineArrs.Add(lineElemArr); } } // offset position //确定每个元素的最终y方向位置,并统计出所有行的总高度 int _offsetLineY = 0; realLineHeight = 0; len = rendLineArrs.Count; for (int i = 0; i < len; i++) { List <LRenderElement> _lines = rendLineArrs[i]; int _lineHeight = 0; foreach (LRenderElement elem in _lines) { _lineHeight = Mathf.Max(_lineHeight, elem.height); } _lineHeight += verticalSpace; //加入行间距 realLineHeight += _lineHeight; _offsetLineY += (_lineHeight - 27); int _len = _lines.Count; for (int j = 0; j < _len; j++) { LRenderElement elem = _lines[j]; elem.pos = new Vector2(elem.pos.x, elem.pos.y - _offsetLineY); realLineHeight = Mathf.Max(realLineHeight, (int)Mathf.Abs(elem.pos.y)); _lines[j] = elem; } rendLineArrs[i] = _lines; } // place all position //将每一个的各个组装好的元素转化为实际的gameObject,置为RichText对象的子对象,并统计出最终的宽度 realLineWidth = 0; GameObject obj = null; foreach (List <LRenderElement> _lines in rendLineArrs) { int _lineWidth = 0; foreach (LRenderElement elem in _lines) { if (!elem.isNewLine) { string strComponent = "Text"; if (elem.type == RichType.TEXT) { obj = getCacheLabel(); makeLabel(obj, elem); _lineWidth += (int)obj.GetComponent <Text>().preferredWidth; strComponent = "Text"; } else if (elem.type == RichType.IMAGE) { obj = getCacheImage(true); makeImage(obj, elem); _lineWidth += (int)obj.GetComponent <Image>().preferredWidth; strComponent = "Image"; } else if (elem.type == RichType.ANIM) { obj = getCacheFramAnim(); makeFramAnim(obj, elem); _lineWidth += elem.width; strComponent = "Animation"; } obj.GetComponent <Graphic>().raycastTarget = RaycastTarget;; obj.transform.SetParent(transform); RectTransform rect = obj.transform as RectTransform; rect.anchoredPosition3D = new Vector3(elem.pos.x, elem.pos.y /*+ realLineHeight*/, 0); rect.localScale = new Vector3(1, 1, 1); _objectDataMap[obj] = elem.data; } } realLineWidth = Mathf.Max(_lineWidth, realLineWidth); } //调整RichText对象的宽高 RectTransform rtran = this.GetComponent <RectTransform>(); //align if (alignType == RichAlignType.DESIGN_CENTER) { rtran.sizeDelta = new Vector2(realLineWidth, realLineHeight); } else if (alignType == RichAlignType.LEFT_TOP) { rtran.sizeDelta = new Vector2(realLineWidth, realLineHeight); } }
//public LRichText(InputType inputType):this() //{ // this.inputType = inputType; //} //=================================================================== //解析内部结构并生成相关GameObject的方法 //=================================================================== //将_richElements中的单个元素拆解为每个字符一个元素,这个时候是一字排开的状态 //_elemRenderArr中存放的所有元素的list void reloadData() { this.removeAllElements(); RectTransform rtran = this.GetComponent <RectTransform>(); //align if (alignType == RichAlignType.DESIGN_CENTER) { rtran.GetComponent <RectTransform>().pivot = new Vector2(0.5f, 0.5f); } else if (alignType == RichAlignType.LEFT_TOP) { rtran.GetComponent <RectTransform>().pivot = new Vector2(0f, 1f); } foreach (LRichElement elem in _richElements) { if (elem.type == RichType.TEXT) { LRichElementText elemText = elem as LRichElementText; char[] _charArr = elemText.txt.ToCharArray(); TextGenerator gen = new TextGenerator(); foreach (char strChar in _charArr) { LRenderElement rendElem = new LRenderElement(); rendElem.type = RichType.TEXT; rendElem.strChar = strChar.ToString(); rendElem.isOutLine = elemText.isOutLine; rendElem.isUnderLine = elemText.isUnderLine; rendElem.font = this.font; rendElem.fontSize = elemText.fontSize; rendElem.data = elemText.data; rendElem.color = elemText.color; TextGenerationSettings setting = new TextGenerationSettings(); setting.font = this.font; setting.fontSize = elemText.fontSize; setting.lineSpacing = 1; setting.scaleFactor = 1; setting.verticalOverflow = VerticalWrapMode.Overflow; setting.horizontalOverflow = HorizontalWrapMode.Overflow; rendElem.width = (int)gen.GetPreferredWidth(rendElem.strChar, setting); rendElem.height = (int)gen.GetPreferredHeight(rendElem.strChar, setting); _elemRenderArr.Add(rendElem); } } else if (elem.type == RichType.IMAGE) { LRichElementImage elemImg = elem as LRichElementImage; LRenderElement rendElem = new LRenderElement(); rendElem.type = RichType.IMAGE; rendElem.path = elemImg.path; rendElem.data = elemImg.data; //从配置直接传进来,不用再读取图片大小了 //Sprite sp = Resources.LoadAssetAtPath(AppConst.RawResPath + rendElem.path, typeof(Sprite)) as Sprite; rendElem.width = elemImg.width; rendElem.height = elemImg.height; _elemRenderArr.Add(rendElem); } else if (elem.type == RichType.ANIM) { LRichElementAnim elemAnim = elem as LRichElementAnim; LRenderElement rendElem = new LRenderElement(); rendElem.type = RichType.ANIM; rendElem.path = elemAnim.path; rendElem.data = elemAnim.data; rendElem.frameCount = elemAnim.frameCount; rendElem.fs = elemAnim.fs; //Sprite sp = Resources.LoadAssetAtPath(AppConst.RawResPath + rendElem.path + "/1", typeof(Sprite)) as Sprite; rendElem.width = elemAnim.width; rendElem.height = elemAnim.height; _elemRenderArr.Add(rendElem); } else if (elem.type == RichType.NEWLINE) { LRenderElement rendElem = new LRenderElement(); rendElem.isNewLine = true; _elemRenderArr.Add(rendElem); } } _richElements.Clear(); formarRenderers(); }