赞
踩
通过刷新修改SpriteRender组建来实现一个翻广告牌的效果,一般的资源原图最好是能两张或更多,实现起来就能类似广告牌那样展现,或者只有一张也可以单独作为一个显示图片的动画来用:
首先是游戏场景中对象的节点层次,这里的fatherObj分别为每张广告牌的父节点,有多少个广告牌就有多少个父节点,父节点的SpriteRender要直接引用图片资源,我以一张广告牌垂直分割为四张为例,如图为图片分割的效果示意图:
需要做的:场景中的节点如图
SpriteRender中引用到的广告牌格式:
本文只贴一下比较关键的代码,既然翻广告牌的对象节点要求已经挫成这样了,代码结构也要继续挫下去,有点搞复杂了。我单独加了个类来存这样的结构:
public class AdCardItem { //对应途中的广告牌节点fatherObj public GameObject father; //存放广告牌碎片,对于fahterObj这个而言,需要把childObj1-childObj4都村进来,SubCardItem结构后面详写。 public List<SubCardItem> cardSubList = new List<SubCardItem>(); //维护多张图的时候才需要,其实单张图距用不到这个了,文本中暂不使用 public int order =0; //多此一举了,其实是fatherObj的SpriteRender组件 public SpriteRender fatherRender; public AdCardItem(GameObject father, List<SubCardItem> cardSubList,int order,SpriteRender fathRender) { this.father = father; this.cardSubList = cardSubList; this.order = order; this.fathRender = fathRender; } } //存储广告牌子块的结构 public class SubCardItem { public SpriteRender spriteRender; /*这个字典其实是用来做缓存优化的,把广告牌的每张小图在不同比例时的显示都缓存了,其实也不会太多。即所有的广告牌翻过一次之后,所有的小碎片都能被缓存到,避免每次用小碎片都直接实例化的尴尬*/ public Dictionary<int,Sprite> sprDic; //实例化的时候只需要传入碎片对象引用的SpriteRender组件 public SubCardItem(SpriteRender spriteRender1) { this.spriteRender = spriteRender1; sprDic = new Dictionary<int,Sprite>(); } }
接下来简单的写一行实例化的代码,以一张广告牌的为例:
public class AdCardUpdate:MonoBehaviour { List<AdCardItem> adCardList; //暂定只有2张广告牌,对象示意图中的命名为场景的对象摆放分别为fatherObj0,fatherObj1 int CARD_COUNT = 2; GameObject fathObj;//广告牌父节点 //假定大广告牌的总宽度为100 float SUB_WIDE = 100/4; //此算法水平分割,因此所有子块和大图的显示高度一致,假定图片高100 float SUB_HEIGHT =50; void Start() { adCardList = new List<AdCardItem>(); int subCount =4;//为碎片个数,此处的把广告牌分成了四块 for(int index = 0; index < CARD_COUNT; index ++) { List<SubCardItem> subList = new List<SubCardItem>(); for(int subIndex=0;subIndex<subCount;subIndex++) { string path = "fatherObj/"+"childObj"+(index+1).ToString(); if(GameObject.Find(path)!=null) { subList.Add(new SubCardItem(GameObject.Find(path).GetComponent<SpriteRender>)); Transform father = GameObject.Find("fatherObj"+index); if(father!=null) { adCardList.Add(new AdCardItem(father.gameObject, subList,0,father.gameObject.GetComponet<SpriteRender>())); } } } } } //描述填充的百分比(%100后使用,当showRate=100表示碎片全部显示) int showRate = 0; int fullRate=100; int forehandIndex { get { int temp = (bgIndex-1)<0? (adCardList.Count-1):(bgIndex-1)); return temp<=0?0:temp; } set{} } int bgIndex=0; void Update() { showRate++; UpdateCard(forehandIndx,shoRate); if(showRate>fullRate) { showRate =0; //该翻下一张广告牌了 bgIndex++; if(bgIndex>=adCardList.Count) { bgIndex=0; } //完全翻牌子了 ResetLayer(); } } ///以下是刷新某张广告牌的详细实现 ///其中,adIndex为adCardList中前景图的索引(慢慢消失的那张广告牌),后面的(bgIndex位置)慢慢全部显示出来 void UpdateCard(int adIndex,float scale,bool needReturn=false) { if(needRetunr) //希望传入scale=0,即前景图全不显示直接隐藏该广告牌父节点 { adCardList[adIndex].father.SetActive(false); return; } Rect fathRect =adCardList[adIndex].fathRender.sprite.textureRect; Texture2D texture2D = adCardList[adIndex].fatherRender.sprite.texture; float leftX = fathRect.x; float topY = fathRect.y; flot curWide = SUB_WIDE*scale*0.01f;//实际显示的碎片宽度 int scaleIndex=(int)scale; for(int index=0;index<adCardList[adIndex].cardSubList.Count;index++) { SpriteRender render = adCardList[adIndex].cardSubList[index].spriteRender; //尚未缓存的 if(!adCardList[adIndex].cardSubList[index].sprDic.ContainsKey(scaleInt)) { //最关键的两行 Rect rect = new Rect(index*SUB_WIDE+leftX,topY,curWide,SUB_HEIGHT); render.sprite=Sprite.Create(texture2D,rect,Vector2.zero); adCardList[adIndex].cardSubList[index].sprDic.Add(scaleInt,render.sprite); } else { render.sprite =adCardList[adIndex].cardSubList[index].sprDic[scaleInt]; } } ///每次翻了新的广告牌,重置层次 void ResetLayer() { adCardListp[bgIndex].father.SetActive(true); adCardListp[bgIndex].father.transform.localPosition= new Vector3(0,0,-0.1); adCardListp[forehandIndex].father.SetActive(true); adCardListp[forehandIndex].father.transform.localPosition= new Vector3(0,0,-0.12); //被翻的牌子forehandIndex放到前面 //前后图片都按100%比例填充 UpdateCard(forehandIndex,fullRate); UpdateCard(bIndex,fullRate); } } }
其实,这个实现只是一个思路,纯手打,不能保证不报错,部分空对象报错的保护代码没有加上,实际运行中某些对报错的时候还是需要额外加限制保护的
最后附上一张2个fatherObj(即只有两个广告牌,就是后面的广告慢慢显示出来,前面的慢慢完全消失:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。