실전 Unity3D Engine Programing 과정 4일차 (2013.07.25 (목)) 

남들이 알아 주지 않더라도 나의 일을 묵묵히 하다 보면
결국 남 좋은 일만 하게 된다.



## [폴리곤 줄이는 방법을 배워보자.]  <== 국내에 유일한 팁으로 스크립트를 모두 사용해라


메뉴 > 윈도우 >  Assets Store 계정을 만들어라.

다음 클라우드에서 오늘자 리소스를 받아라.

skybox_objects.unitypackage

shooting2D_resources

skybox_objects

NGUI <== 상용 플러그인다. 출처를 밝히지 말라. 550$ 상당의 가치이다.


뉴프로젝트한다. : 2DShooting

Assets창에서 패키지를 로딩한다: shooting2D_resources

Consol창에서 Error pause를 켜 놓아야 한다. <== 일반적으로 켜 놓고 사용해라. 

콘솔창이 없으면 Menu > Window > Consol을 선택해서 아무곳에 붙이면 된다.


아셋 > 텍스쳐를 봐라.

- 비행기

- 해골

- 미사일

- plane 

있고 이것들의 size가 나온다. 유니티는 스스로 2승수로 바꾼다. 

이것을 변경하는 것을 갔다 사용한다.

인터넷 > unity3d.com에 접속

http://wiki.unity3d.com/index.php/Main_Page 

http://wiki.unity3d.com/index.php/TextureImportSettings

Adds under the menu Custom→Texture a way to change for multiple selected textures the import settings in one step. Idea was to have the same choices for multiple texture files as you would have if you open the import settings of a single texture. Currently the most often used import settings are editable: Texture Format (same amount and order as in Unity), enable/disable MipMap and changing the maximum texture size.

Usage

You must place the script in a folder named Editor in your project's Assets folder for it to work properly.

Select some textures in the project window and select from the Custom→Texture menu the modification you want to apply to the selected textures.

Screenshot

Textureimportsettings.jpg

내용 보면 두개의 스크립트가 있는데 첫번째것이 4버전이고 두번째것이 3버전이다. 




ChangeTextureImportSettings 이 파일명으로 스크립트를 만들어 사용한다.

내용은 아래 것으로 채운다. (상기 인터넷 사이트 것)

using UnityEngine;
using UnityEditor;
 
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Batch Texture import settings modifier.
//
// Modifies all selected textures in the project window and applies the requested modification on the 
// textures. Idea was to have the same choices for multiple files as you would have if you open the 
// import settings of a single texture. Put this into Assets/Editor and once compiled by Unity you find
// the new functionality in Custom -> Texture. Enjoy! :-)
// 
// Based on the great work of benblo in this thread: 
// http://forum.unity3d.com/viewtopic.php?t=16079&start=0&postdays=0&postorder=asc&highlight=textureimporter
// 
// Developed by Martin Schultz, Decane in August 2009
// e-mail: ms@decane.net
//
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
public class ChangeTextureImportSettings : ScriptableObject {
 
	[MenuItem ("Custom/Texture/Change Texture Format/Auto")]
    static void ChangeTextureFormat_Auto() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.Automatic);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGB Compressed DXT1")]
    static void ChangeTextureFormat_RGB_DXT1() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.DXT1);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGB Compressed DXT5")]
    static void ChangeTextureFormat_RGB_DXT5() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.DXT5);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGB 16 bit")]
    static void ChangeTextureFormat_RGB_16bit() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.RGB16);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGB 24 bit")]
    static void ChangeTextureFormat_RGB_24bit() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.RGB24);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/Alpha 8 bit")]
    static void ChangeTextureFormat_Alpha_8bit() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.Alpha8);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGBA 16 bit")]
    static void ChangeTextureFormat_RGBA_16bit() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.ARGB16);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Format/RGBA 32 bit")]
    static void ChangeTextureFormat_RGBA_32bit() { 
		SelectedChangeTextureFormatSettings(TextureImporterFormat.ARGB32);
	}
 
	// ----------------------------------------------------------------------------
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/32")]
    static void ChangeTextureSize_32() { 
		SelectedChangeMaxTextureSize(32);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/64")]
    static void ChangeTextureSize_64() { 
		SelectedChangeMaxTextureSize(64);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/128")]
    static void ChangeTextureSize_128() { 
		SelectedChangeMaxTextureSize(128);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/256")]
    static void ChangeTextureSize_256() { 
		SelectedChangeMaxTextureSize(256);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/512")]
    static void ChangeTextureSize_512() { 
		SelectedChangeMaxTextureSize(512);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/1024")]
    static void ChangeTextureSize_1024() { 
		SelectedChangeMaxTextureSize(1024);
	}
 
	[MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/2048")]
    static void ChangeTextureSize_2048() { 
		SelectedChangeMaxTextureSize(2048);
	}
 
	// ----------------------------------------------------------------------------
 
	[MenuItem ("Custom/Texture/Change MipMap/Enable MipMap")]
    static void ChangeMipMap_On() { 
		SelectedChangeMimMap(true);
	}
 
	[MenuItem ("Custom/Texture/Change MipMap/Disable MipMap")]
    static void ChangeMipMap_Off() { 
		SelectedChangeMimMap(false);
	}
 
	// ----------------------------------------------------------------------------
 
	static void SelectedChangeMimMap(bool enabled) { 
 
		Object[] textures = GetSelectedTextures(); 
		Selection.objects = new Object[0];
		foreach (Texture2D texture in textures)  {
			string path = AssetDatabase.GetAssetPath(texture); 
			TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
			textureImporter.mipmapEnabled = enabled;	
			AssetDatabase.ImportAsset(path); 
		}
	}
 
	static void SelectedChangeMaxTextureSize(int size) { 
 
		Object[] textures = GetSelectedTextures(); 
		Selection.objects = new Object[0];
		foreach (Texture2D texture in textures)  {
			string path = AssetDatabase.GetAssetPath(texture); 
			TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
			textureImporter.maxTextureSize = size;	
			AssetDatabase.ImportAsset(path); 
		}
	}
 
	static void SelectedChangeTextureFormatSettings(TextureImporterFormat newFormat) { 
 
		Object[] textures = GetSelectedTextures(); 
		Selection.objects = new Object[0];
		foreach (Texture2D texture in textures)  {
			string path = AssetDatabase.GetAssetPath(texture); 
			//Debug.Log("path: " + path);
			TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
			textureImporter.textureFormat = newFormat;	
			AssetDatabase.ImportAsset(path); 
		}
	}
 
	static Object[] GetSelectedTextures() 
	{ 
		return Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets); 
	}
}



 menu > assets > refresh 하면 상당 menu에 custom이란 항목이 나오면 성공



텍스쳐를 선택해서 사이즈를 변경한다.

menu > custom > texture > 



성공되면 해당 텍스쳐선택히 우측 하단에... NOPT라고 나오면 된다.



현재까지 한 것은  Game 신으로 저장한다.



[폴리곤을 바꿔 보자]

카메라는 이차원 카메라로 바꾼다.

포지션 0, 0, 0

프로적션은 오도고날 (2차원)

사이즈 3.5

클립핑 -2, 2

라이트 추가



스크립트추가 SpriteBase

using UnityEngine;

using System.Collections;


public class SpriteBase : MonoBehaviour {

 

public Material mat;

void Awake()

{

gameObject.AddComponent("MeshFilter");

gameObject.AddComponent("MeshRenderer");

Mesh mesh = GetComponent<MeshFilter>().mesh;

mesh.Clear(); //remove

// 새로만든자 - xy 좌표에서 사각형좌표를찍었다

mesh.vertices = new Vector3[]

{new Vector3(0,0,0), new Vector3(0,1,0),new Vector3(1,1,0), new Vector3(1,0,0)};

// 밝아지는반경

mesh.uv = new Vector2[] {new Vector2(0,0), new Vector2(0,1), new Vector2(1,1), new Vector2(1,0)}; 

//사각형을두개의삼각형으로붙인다

mesh.triangles = new int[]{0,1,2,0,2,3};


//노말을생성한다 빗의반사색상

mesh.RecalculateNormals();


if(mat != null)

{

gameObject.renderer.material = mat;

}

}

}


위에것으로 하면 컴파일 안된다.
아래처럼 주석에 .을 붙여야 하다.
using UnityEngine;
using System.Collections;

public class SpriteBase : MonoBehaviour {
 
public Material mat;
void Awake()
{
gameObject.AddComponent("MeshFilter");
gameObject.AddComponent("MeshRenderer");
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear(); //remove
// 새로만든자 - xy 좌표에서 사각형좌표를찍었다.
mesh.vertices = new Vector3[]
{new Vector3(0,0,0), new Vector3(0,1,0),new Vector3(1,1,0), new Vector3(1,0,0)};
// 밝아지는반경.
mesh.uv = new Vector2[] {new Vector2(0,0), new Vector2(0,1), new Vector2(1,1), new Vector2(1,0)}; 
//사각형을두개의삼각형으로붙인다.
mesh.triangles = new int[]{0,1,2,0,2,3};
//노말을생성한다 빗의반사색상.
mesh.RecalculateNormals();
if(mat != null)
{
// 대소문자구분 소문자game은자체.
gameObject.renderer.material = mat;
}
}
}






빛과 텍스쳐가 각이 맞다면 색상이 달라진다. 이것을 노말이라고 한다. 

//노말을생성한다 빗의반사색상

mesh.RecalculateNormals();



아셋에서 Material 폴더를 추가한다.

<== 폴더를 구분하는 것은 매우 중요하다. 아셋에 들어갈게 많아서 구분하는게 좋다.

메트리얼 추가한다.

메트리어에 비행기 텍스쳐을 잡소 오른쪽에 붙이다.





엠프티오브젝트를 추가하고 포지션은 0,0,0으로 한다.

아까만든 SpriteBase 스크립트를 엠프티오브젝트에 추가한다.

그리고 메터리어을 스트립트의 mat에 붙인다.


그리고 실행해 보면 4각형의 비행기가 나온다.

실제 비행기 이미지 보다 작게 나온다.



<== 이 스크립트를 사용하면 폴리곤을 수를 업청 줄일 수 있다. 이것이 노하우다 이 스크립트를 사용해라


tris수가 2로 매우 작게 나온다 . 

이렇게 하지 않았을 경우는 200 까지 나온 것이다.



이렇듯 실제 사이즈가 다르면 안되니 이것을 맞추도록 하자.

사이즈 수정하자..

스크립트 아래 내용 추가하자.

using UnityEngine;

using System.Collections;


public class SpriteBase : MonoBehaviour {

 

public Material mat;

void Awake()

{

gameObject.AddComponent("MeshFilter");

gameObject.AddComponent("MeshRenderer");

Mesh mesh = GetComponent<MeshFilter>().mesh;

mesh.Clear(); //remove

// 새로만든자 - xy 좌표에서 사각형좌표를찍었다.

mesh.vertices = new Vector3[]

{new Vector3(0,0,0), new Vector3(0,1,0),new Vector3(1,1,0), new Vector3(1,0,0)};

// 밝아지는반경.

mesh.uv = new Vector2[] {new Vector2(0,0), new Vector2(0,1), new Vector2(1,1), new Vector2(1,0)}; 

//사각형을두개의삼각형으로붙인다.

mesh.triangles = new int[]{0,1,2,0,2,3};

//노말을생성한다 빗의반사색상.

mesh.RecalculateNormals();

if(mat != null)

{

// 대소문자구분 소문자game은자체.

gameObject.renderer.material = mat;

}


//사이즈변경하는것호출한다.

MakePerfectSize();

}

void MakePerfectSize() 

{

Texture tex = mat.mainTexture;

float one_unit = 2.0f / Screen.height;

float x = one_unit * tex.width;

float y = one_unit * tex.height;

Vector3 newScale = new Vector3(x, y, one_unit);

transform.localScale = newScale;

}

}


<== 여기까지가 이제 2D의 시작이다.

이제부터 텍스쳐 다르게 넣으면 다르게 나온다.

계속 이 스크립트는 복제해서 사용하자.



## [드라곤 플라이트 게임 만든자]

새롭게 시작하다. 기존 게임오브젝트는 지운다.

PlayerSprite 스크립트 새로 추가한다.

상속은 1단계만 된다. SpriteBase을 상속한다.


using UnityEngine;

using System.Collections;


public class PlayerSprite : SpriteBase {

public float Speed = 10.0f;

private float LastShootTime;

public float ShootDelay = 0.2f;

// Use this for initialization

void Start () {

LastShootTime = Time.time;

}

// Update is called once per frame

void Update () {

float moveAmt = Input.GetAxis("Horizontal") * Speed  * Time.deltaTime;

transform.Translate(Vector3.right * moveAmt);

}

}



엠프티오브젝트추가
이름 player
포지션 0, -3, 0
스크립트 추가
메트리얼 추가



비행기의 기준점이 없어 불편하다. 디버그 포인트를 추가하자.

모눈종이 모양의 선을 그려보다.


PlayerBase에 추가하자.

using UnityEngine;

using System.Collections;


public class SpriteBase : MonoBehaviour {

 

public Material mat;

void Awake()

{

gameObject.AddComponent("MeshFilter");

gameObject.AddComponent("MeshRenderer");

Mesh mesh = GetComponent<MeshFilter>().mesh;

mesh.Clear(); //remove

// 새로만든자 - xy 좌표에서 사각형좌표를찍었다.

mesh.vertices = new Vector3[]

{new Vector3(0,0,0), new Vector3(0,1,0),new Vector3(1,1,0), new Vector3(1,0,0)};

// 밝아지는반경.

mesh.uv = new Vector2[] {new Vector2(0,0), new Vector2(0,1), new Vector2(1,1), new Vector2(1,0)}; 

//사각형을두개의삼각형으로붙인다.

mesh.triangles = new int[]{0,1,2,0,2,3};

//노말을생성한다 빗의반사색상.

mesh.RecalculateNormals();

if(mat != null)

{

// 대소문자구분 소문자game은자체.

gameObject.renderer.material = mat;

}


//사이즈변경하는것호출한다.

MakePerfectSize();

}

void MakePerfectSize() 

{

Texture tex = mat.mainTexture;

float one_unit = 2.0f / Screen.height;

float x = one_unit * tex.width;

float y = one_unit * tex.height;

Vector3 newScale = new Vector3(x, y, one_unit);

transform.localScale = newScale;

}

void OnDrawGizmosSelected()

{

Gizmos.color = Color.white;

Gizmos.DrawWireSphere(transform.position, 1.0f);

}

void OnDrawGizmos()

{

Gizmos.color = Color.red;

Gizmos.DrawWireCube(transform.position, Vector3.one);

}

}


신을 보라..


이렇게 위치가 빨갔게 나오고 스프라이트가 선택되면 힌색이 나온다.

스프라이트로만 처리하면 신화면에 나오지 않으니 디버깅용으로 사용할 수 있다.

실제 화면에서는 나오지 않으니 디버깅용으로 매우 좋다.


## [총탄을 만들자]

메트리얼 만들자.  그리고 미사일 텍스쳐를 붙인다.


그리고 BulletSprite 스프라이트 만든다.

리니즈바디 추가 그라비티 를 언체크하는 것을 스크립트로 제어한다.


using UnityEngine;

using System.Collections;


public class BulletSprite : SpriteBase {

public float Speed = 15.0f;

// Use this for initialization

void Start () {

//리니즈바디 추가 그라비티 를 언체크하는 것을 스크립트로 제어한다.

gameObject.AddComponent<Rigidbody>();

gameObject.rigidbody.useGravity = false;

gameObject.AddComponent<BoxCollider>();

gameObject.collider.isTrigger = true;

}

// Update is called once per frame

void Update () {

float moveAmt = Speed * Time.deltaTime;

transform.Translate(Vector3.up *moveAmt);

if(transform.position.y > 10.0f)

{

Destroy(gameObject);

}

}

}


아셋에 Prefab 폴더 만들고  BulletPrefab을  만든다.


엠프티오브젝트 만들고

 블랫스프라이트 추가

 블랫메트리얼 추가

 Tag  bullet으로 선언




그리고 BulletPrefab에 만든 엠프티오브젝트를 추가한다. 지운다.

(정상적으로 추가되면 아래 BulletPrefab 처럼 아이콘이 유색으로 변한다. 추가되지 않았을 때에는 회색)






## [ 플레이어의 총알이 자동발사하는 것을 만들자.]


1. 플레이 경과 시간파악

2. 지금 시간이 마지막 총을 쏜 시간  지연되어으면 ......

//Time.time은play 버튼이누른이후계속재시는시간이다 42일max까지이다.

if(Time.time > LastShootTime + ShootDelay)

{

LastShootTime = Time.time;

Instantiate(bullet, transform.position, transform.rotation);

}

<= 이것 많이 사용한다. 


Player  오브젝트에 보면 bullet이 추가되어 있다. 여기에 BulletPrefab을 추가 한다. 



Player오브젝트를 열어보면 리니지바디 중력은 언체크되어 있고 박스콜라이더는 트리거체크되어 화면에 녹색네모가 보이게 된다.

이렇게 코드로 추가 가능하다. 이렇게 해야 충돌 체크가 가능해진다.


[팁] 스크립트로 오브젝트를 add하면 메모리 누스를 줄일 수 있다.

[팁] 부모 함수를 자식이 호출 할 수 있다. base.. 그러나 호출 순서는 장담할 수 없다고 합니다. 스크립트라서... 



##[적군만들자]

EnemySprite 스프라이트 만들자

using UnityEngine;

using System.Collections;


public class EnemySprite : MonoBehaviour {

public float Speed  = 10.0f;

public GameObject expolosion;

// Use this for initialization

void Start () {

gameObject.AddComponent<BoxCollider>();

}

// Update is called once per frame

void Update () {

float moveAmt = Speed * Time.deltaTime;

transform.Translate(Vector3.down * moveAmt);

//많이 떨어지면파괴한다.

if(transform.position.y < -4.0f)

{

InitPosition();

}

}

    void InitPosition()

{

transform.position = new Vector3(Random.Range(-3.0f, 3.0f), 5,0f, 0.0f);

}

}


신 저장


에너미 오브젝트를 만들고

스크립트추가

이팩트를 추가


이팩트는 추가한 다이나믹을 추가한다.




##[배경을 흐르는 것을 만들자]

스카이박스 패키지를 추가한다.  <== 출처는 비밀

sky_box_ring을선택해서 히어아키창에 둔다.  (아셋 > 오브젝트 > 스카이 )

이것을 Y값을 1000으로 둔다. 노출되지 않게

배경을 줄이자...



카메라를 추가한다.

포지션 0, 1670, 0

필더뷰 : 35

클립 0.3, 5000

Depth : -2 (낮은 값이 먼저 찍는다.)


엠프트오브젝트 Main

스크립트 MainScript 

추가..

using UnityEngine;

using System.Collections;


public class MainScript : MonoBehaviour {

public GameObject SkyGamera;

public float CameraRotateSpeed = 0.1f;


// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

//카메라를Y축으로돌리자. 축을 중심으로회전한다.

SkyGamera.transform.RotateAround(Vector3.up, Time.deltaTime * CameraRotateSpeed);

}

}



메인카메라에서 Clear Flags를 Depth only로 한다. 
= 뒷배경 그리도 덥어 쒸운다는 것.



아까만든 Main 오브제트에 스크립트 추가한다.

스크립트에 카메라는 하이어라키의 카메라를 붙인다.



카메라의 Rotation 0, 0, 2780 으로 변경한다.

그리고 Field of View 25로 한다





배경 이미지를 바꿔보자.



가로 형태는 카메라 축을 변경하면 충분히 처리한다.


내일은 GUI를 붙인다..