Skip to content

SkinRepeater.cs

Jeppe Zapp edited this page Mar 26, 2014 · 4 revisions

Allows for repeated/tiled edges around widgets

NOTE: This script is redundant since v0.9-beta-5, but still very, very cool nonetheless

using UnityEngine;
using System.Collections;

//Instead of strecth an object, adding this script will make the skin repeat, using the border system provided
//just work for slicedSprites (Backgrounds)
public class SkinRepeater : MonoBehaviour{

	OGSkin skin;
	OGSlicedSprite slicedSprite;

	public void Start(){
		//get the actual background
		slicedSprite = this.GetComponent<OGSlicedSprite>();
		//get the old style
		OGStyle style = slicedSprite.styles.GetStyle(OGStyleType.Basic);
		//get the skin
		skin = GameObject.FindObjectOfType<OGRoot>().skin;

		//create 9 new styles if they are not created, these represent the center and the borders
		//of the old style
		addNewStyles(style.name,skin);
		//generate many objects and apply the proper skin(center or border)
		//return the ratio between the old and the new scale
		Vector2 newScale = generateObjects(style);

		//calculate the new pivot
		double pivoX = this.transform.localPosition.x;
		double pivoY = this.transform.localPosition.y;
		if(slicedSprite.pivot.x == RelativeX.Center)
			pivoX -= this.transform.localScale.x/2.0;
		else if(slicedSprite.pivot.x == RelativeX.Right)
			pivoX -= this.transform.localScale.x;
		
		if(slicedSprite.pivot.y == RelativeY.Center)
			pivoY -= this.transform.localScale.y/2.0;
		else if(slicedSprite.pivot.y == RelativeY.Bottom)
			pivoY -= this.transform.localScale.y;

		//destroy the old background
		GameObject.Destroy(this.GetComponent<OGSlicedSprite>());
		//apply a new scale and position, to adjust
		this.transform.localScale = new Vector3(newScale.x,newScale.y,1);
		this.transform.localPosition = new Vector3((float)pivoX,(float)pivoY,this.transform.localPosition.z);
	}

	//generate the objects to apply the proper skin
	Vector2 generateObjects(OGStyle style){

		//son of main object, will store all tile objects
		GameObject divided = new GameObject();
		divided.name = "SkinRepeated";
		divided.transform.parent = this.transform;
		divided.transform.localPosition = new Vector3(0,0,0);
		divided.transform.localScale = new Vector3(1,1,1);

		OGStyle centerStyle = skin.GetStyle(style.name+"C");
		//son of SkinRepeated, will store center tiles
		GameObject centers = new GameObject();
		centers.name = "Centers";
		centers.transform.parent = divided.transform;
		centers.transform.localPosition = new Vector3(0,0,0);
		centers.transform.localScale = new Vector3(1,1,1);

		//generate center tiles based on the scale, store the new scale
		float lastX=0,lastY=0;
		for(float i=style.border.left;i<this.transform.localScale.x - style.border.right - style.border.left - centerStyle.coordinates.width;i+=centerStyle.coordinates.width ){
			if(i+centerStyle.coordinates.width>lastX)
				lastX=i+centerStyle.coordinates.width;
			for(float j=style.border.bottom;j<this.transform.localScale.y - style.border.top - style.border.bottom - centerStyle.coordinates.height;j+=centerStyle.coordinates.height ){
				createObject(centerStyle,new Vector3(i,j,0),new Vector3(centerStyle.coordinates.width,centerStyle.coordinates.height,1),centers);
				if(j+centerStyle.coordinates.height>lastY)
					lastY=j+centerStyle.coordinates.height;
			}
		}

		//son of SkinRepeated, will store corners tiles
		GameObject corners = new GameObject();
		corners.name = "Corners";
		corners.transform.parent = divided.transform;
		corners.transform.localPosition = new Vector3(0,0,0);
		corners.transform.localScale = new Vector3(1,1,1);

		//generate the 4 corners
		OGStyle leftTopStyle = skin.GetStyle(style.name+"LT");
		createObject(leftTopStyle,new Vector3(0,0,0),new Vector3(leftTopStyle.coordinates.width,leftTopStyle.coordinates.height,1),corners);
		OGStyle leftBottomStyle = skin.GetStyle(style.name+"LB");
		createObject(leftBottomStyle,new Vector3(0,lastY,0),new Vector3(leftBottomStyle.coordinates.width,leftBottomStyle.coordinates.height,1),corners);
		OGStyle rightTopStyle = skin.GetStyle(style.name+"RT");
		createObject(rightTopStyle,new Vector3(lastX,0,0),new Vector3(rightTopStyle.coordinates.width,rightTopStyle.coordinates.height,1),corners);
		OGStyle rightBottomStyle = skin.GetStyle(style.name+"RB");
		createObject(rightBottomStyle,new Vector3(lastX,lastY,0),new Vector3(rightBottomStyle.coordinates.width,rightBottomStyle.coordinates.height,1),corners);
	

		//son of SkinRepeated, will store left border tiles
		GameObject lborder = new GameObject();
		lborder.name = "LeftBorder";
		lborder.transform.parent = divided.transform;
		lborder.transform.localPosition = new Vector3(0,0,0);
		lborder.transform.localScale = new Vector3(1,1,1);
		OGStyle leftStyle = skin.GetStyle(style.name+"L");
		//generating border
		for(float i=style.border.top;i<this.transform.localScale.y - style.border.bottom - style.border.top - leftStyle.coordinates.height;i+=leftStyle.coordinates.height ){
			createObject(leftStyle,new Vector3(0,i,0),new Vector3(leftStyle.coordinates.width,leftStyle.coordinates.height,1),lborder);
		}

		//son of SkinRepeated, will store top border tiles
		GameObject tborder = new GameObject();
		tborder.name = "TopBorder";
		tborder.transform.parent = divided.transform;
		tborder.transform.localPosition = new Vector3(0,0,0);
		tborder.transform.localScale = new Vector3(1,1,1);
		OGStyle topStyle = skin.GetStyle(style.name+"T");
		//generating border
		for(float i=style.border.left;i<this.transform.localScale.x - style.border.left - style.border.right - topStyle.coordinates.width;i+=topStyle.coordinates.width ){
			createObject(topStyle,new Vector3(i,0,0),new Vector3(topStyle.coordinates.width,topStyle.coordinates.height,1),tborder);
		}

		//son of SkinRepeated, will store right border tiles
		GameObject rborder = new GameObject();
		rborder.name = "RightBorder";
		rborder.transform.parent = divided.transform;
		rborder.transform.localPosition = new Vector3(0,0,0);
		rborder.transform.localScale = new Vector3(1,1,1);
		OGStyle rightStyle = skin.GetStyle(style.name+"R");
		//generating border
		for(float i=style.border.top;i<this.transform.localScale.y - style.border.bottom - style.border.top - rightStyle.coordinates.height;i+=rightStyle.coordinates.height ){
			createObject(rightStyle,new Vector3(lastX,i,0),new Vector3(rightStyle.coordinates.width,rightStyle.coordinates.height,1),rborder);
		}

		//son of SkinRepeated, will store bottom border tiles
		GameObject bborder = new GameObject();
		bborder.name = "BottomBorder";
		bborder.transform.parent = divided.transform;
		bborder.transform.localPosition = new Vector3(0,0,0);
		bborder.transform.localScale = new Vector3(1,1,1);
		OGStyle bottomStyle = skin.GetStyle(style.name+"B");
		//generating border
		for(float i=style.border.left;i<this.transform.localScale.x - style.border.left - style.border.right - bottomStyle.coordinates.width;i+=bottomStyle.coordinates.width ){
			createObject(bottomStyle,new Vector3(i,lastY,0),new Vector3(bottomStyle.coordinates.width,bottomStyle.coordinates.height,1),bborder);
		}

		//calculating the bottom right
		lastX += style.border.right;
		lastY += style.border.bottom;

		//returning the ratio
		return new Vector2(this.transform.localScale.x/lastX,this.transform.localScale.y/lastY);
	}

	//create a single tile
	void createObject(OGStyle style,Vector3 pos,Vector3 scale,GameObject parent){

		GameObject go = new GameObject();
		go.name = style.name;
		go.transform.parent = parent.transform;
		OGSlicedSprite ss = go.AddComponent<OGSlicedSprite>();
		ss.styles.SetStyle(OGStyleType.Basic,style);
		go.transform.localPosition = pos;
		go.transform.localScale = scale;


	}

	//generate 9 styles based on a single style with border
	public OGStyle[] generateStyles(string mainStyle, OGSkin skin){
		OGStyle[] styles = new OGStyle[9];
		styles[0] = getLeftTopBorder(skin.GetStyle(mainStyle));
		styles[1] = getTopBorder(skin.GetStyle(mainStyle));
		styles[2] = getRightTopBorder(skin.GetStyle(mainStyle));
		styles[3] = getLeftBorder(skin.GetStyle(mainStyle));
		styles[4] = getCenter(skin.GetStyle(mainStyle));
		styles[5] = getRightBorder(skin.GetStyle(mainStyle));
		styles[6] = getLeftBottomBorder(skin.GetStyle(mainStyle));
		styles[7] = getBottomBorder(skin.GetStyle(mainStyle));
		styles[8] = getRightBottomBorder(skin.GetStyle(mainStyle));
		return styles;

	}

	//add the generated styles to the skin
	public void addNewStyles(string mainStyle,OGSkin skin){
		OGStyle [] stylesGenerated = generateStyles(mainStyle,skin);
		//backup
		OGStyle [] skinStyles = skin.styles;

		int countNonRepetitiveStyles=9;
		//verify if already have some of them
		for(int j=0;j<stylesGenerated.Length;j++){
			for(int i=0;i<skin.styles.Length;i++){
				if(skin.styles[i].name == stylesGenerated[j].name){
					countNonRepetitiveStyles--;
					stylesGenerated[j].name = "";
					break;
				}
			}
		}
		//resizing and copying the old ones
		skin.styles = new OGStyle[skinStyles.Length+countNonRepetitiveStyles];
		for(int i=0;i<skinStyles.Length;i++){
			skin.styles[i] = skinStyles[i];
		}
		int count=0;
		//adding styles
		for(int i=0;i<9;i++){
			if(stylesGenerated[9-1-i].name != ""){
				skin.styles[ skin.styles.Length-1-count] = stylesGenerated[9-1-i];
				count++;
			}
		}
	}

	//copy an style
	OGStyle copy(OGStyle style){
		OGStyle st = new OGStyle();
		st.name = style.name;
		st.coordinates  = new Rect ( style.coordinates.x, style.coordinates.y, style.coordinates.width, style.coordinates.height );
		st.border = new OGSlicedSpriteOffset ( 0, 0, 0, 0 );
		st.color =style.color;
		st.text =style.text;

		return st;
	}

	//functions that get the proper border and center
	//of an style and create a new one
	//


	public OGStyle getLeftTopBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x;
		float y = st.coordinates.y+st.coordinates.height-st.border.bottom;
		float width = st.border.left;
		float height = st.border.bottom;
		
		style.name += "LT";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getTopBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.border.left;
		float y = st.coordinates.y+st.coordinates.width-st.border.top;
		float width = st.coordinates.width-st.border.right-st.border.left;
		float height = st.border.top;
		
		style.name += "T";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getRightTopBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.coordinates.width-st.border.right;
		float y = st.coordinates.y+st.coordinates.width-st.border.top;
		float width = st.border.right;
		float height = st.border.top;
		
		style.name += "RT";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}
	
	public OGStyle getLeftBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x;
		float y = st.coordinates.y+st.border.bottom;
		float width = st.border.left;
		float height = st.coordinates.height-st.border.bottom-st.border.top;

		style.name += "L";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getCenter(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.border.left;
		float y = st.coordinates.y+st.border.top;
		float width = st.coordinates.width-st.border.right-st.border.left;
		float height = st.coordinates.height-st.border.bottom-st.border.top;

		style.name += "C";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getRightBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.coordinates.width-st.border.right;
		float y = st.coordinates.y+st.border.bottom;
		float width = st.border.right;
		float height = st.coordinates.height-st.border.bottom-st.border.top;
		
		style.name += "R";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getLeftBottomBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x;
		float y = st.coordinates.y;
		float width = st.border.left;
		float height = st.border.top;
		
		style.name += "LB";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getBottomBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.border.left;
		float y = st.coordinates.y;
		float width = st.coordinates.width-st.border.left-st.border.right;
		float height = st.border.bottom;
		
		style.name += "B";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

	public OGStyle getRightBottomBorder(OGStyle st){
		OGStyle style = copy(st);
		float x = st.coordinates.x+st.coordinates.width-st.border.right;
		float y = st.coordinates.y;
		float width = st.border.right;
		float height = st.border.bottom;
		
		style.name += "RB";
		style.coordinates = new Rect(x,y,width,height);
		return style;
	}

}
Clone this wiki locally