Blend Trees


사람이 뛸때 왼쪽방향으로 돌면서 뛸때(왼쪽으로 조금 숙인다 던지)와 오른쪽 방향으로 돌면서 뛸때 다르다.

유니티에서도 . 디테일한 애니메이션을 주기 위해 사용한다.



애니메이터 창에서 Create State -> From New Blend Tree를 생성한다.

이렇게 생성하면 모션으로서 단일한 애니메이션이 아니라 Blend Tree를 가지게 된다.


생성한 Blend Tree를 클릭해서 들어간다.

인스펙터 창에 Blend Type이 1D라는것은 일차원으로 파라미터(현재는 speed)로 각각의 모션을 얼만큼 재생할지 제어하는 것이다.


모션추가

Add Motition Field를 추가해서 Run 애니메이션을 추가한다.



Threshold : 온전히 이  애니메이션만을 사용하는 블랜드를 나타내는 파라미터 값이다.

ex) speed 값이 걷기가 5이고 달리기가 10이다. speed가 10이 되면 달리기 모션을 취하고 7.5가 되면 걷기와 달리기가  50:50으로 혼합되어 실행 된다.

Time Scale(시계모양) : 애니메이션의 속도를 정한다.

사람모양 : 애니메이션의 반전 여부를 지정한다.



Automate Thresholds를 체크하면 각 애니메이션 임계값 변경이 안된다.

Adjust Time Scale : 각 애니메이션의 속도를 균일하게 만들 수 있다.(루트 모션의 속도와 같아진다)


Blend Type

2D Simple Directional : 방향 파라미터에 기초하여 모션을 블렌딩 각 방향에 애니메이션이 하나 일때 사용한다. ex) 앞으로 걷기, 뒤로 걷기, 왼쪽으로 걷기 등

2D Freeform Directional : 같은 방향에 대해 두 개 이상의 애니메이션을 가질 수 있다.

ex) 앞으로 걷기와 앞으로 달리기 등

2D Freeform Cartesian : 파라미터가 방향과 무관할 때 사용  ex) 속도, 각속


x축을 나타낼 애니메이터 파라미터

y축을 나타낼 애니메이터 파라미터를 각각 생성해서 할당해준다.




빨간점으로 임계값을 주고 밑에 미리보기를 통해 어떻게 반응하는지 알 수 있다.

(빨간점을 마우스로 끌어서 움직이면 방향에 맞는 에니메이션을 취한다)


출처 : https://www.youtube.com/watch?v=HeHvlEYpRbM


반응형


코루틴 Coroutine 


유니티 Update( )함수는 게임의 지속적인 변화를 주거나 게임의 진행되는 매순간 체크(사용자의 입력 등)해야할 경우 사용하게 된다.

하지만 특정행동을 5초 동안 취해야 할 경우,  초당60~80(프레임)번 호출 되는 Update함수 안에서는 제어 하기가 힘들다. 

그리고 플레이하는 디바이스마다 각각 다른 프레임이 나오기 때문에 구현 자체가 더더욱 힘들다.


그래서 C#과 유니티에서는 코루틴이라는 것을 제공한다.

유니티에서 사용할 것이기 때문에 유니티 코루틴을 알아보도록 하자


사용법 

StartCoroutine

void 함수명( ) //Update안에 있는

{

     StartCoroutine( 코루틴 함수 이름( ) );  

}

IEnumerator

    public IEnumerator 코루틴 함수 이름( ) //코루틴 사용

    {

            Debug.log(코루틴 대기);   

 yield return new WaitForFixedUpdate();

            Debug.log(코루틴 완료);

    }

 코드분석

우선 StartCoroutine( ) 괄호안에 코루틴으로 IEnumerator 개채명, 지정한 함수이름을 써준다.

yield라는 것은 반복자의 IEnumerator객체에 값을 전달하거나, 반복의 종료를 알리기 위해 사용한다.

WaitForFixedUpdate( );  다음 FixedUpdate 물리 프레임 전까지 대기

(코루틴 예외 :  함수안에서 만 사용, 알수 없는 이름의 함수(람다)에서는 에러)

코루틴용 데이터엔진이 수행하는 기능
yield return null다음 프레임까지 대기
yield return new WaitForSeconds(float)지정된 초 만큼 대기
yield return new WaitForFixedUpdate()다음 물리 프레임까지 대기
yield return new WaitForEndOfFrame()모든 렌더링작업이 끝날 때까지 대기
yield return StartCoRoutine(string)다른 코루틴이 끝날 때까지 대기
yield return new WWW(string)웹 통신 작업이 끝날 때까지 대기
yield return new AsyncOperation

비동기 작업이 끝날 때까지 대기




참고 : https://docs.unity3d.com/kr/530/Manual/Coroutines.html





반응형

TrailRenderer





Description

trail 렌더러는 오브젝트 뒤에서 씬에서 오브젝트가 움직일 때, 해당 오브젝트 뒤를 따라 움직이도록 할 때에 사용됩니다.


TrailRenderer은 유니티에서 제공하는 기본컴포넌트이다.


TrailRenderer 컴포넌트 추가하기

우선 발사체(오브젝트)에 TrailRenderer컴포넌트를 추가한다.


테스트1

총알을 발사해보면 발사체가 이동했던 경로를 그린다.



Material생성

총알처럼 효과를 주기 위해


material을 생성하고 이미지를 Albedo에 넣어준다.

Shader모드를 변경한다. 그래야 더 발사체 효과같기 때문에 변경해준다.


생성한 Material 추가

그런 다음 TrailRenderer컴포넌트에 효과이미지를 추가한 메테리얼을 넣어준다.

Materials 트레일을 렌더링하는 데 사용하는 Material의 배열

size: 배열의 요소 수

Time : 트레일의 길이(단위 초)


Width

곡선의 기울기에 따라 트레일을 넓이를 조절 할 수있다.

Width가 굵을 수록 실제 보여지는 발사체효과도 굵어진다고 보면 된다.

 

그래프에서 왼쪽부분이 발사체 종료부분(=끝나는 부분)

그래프에서 오른쪽부분이 발사체 시작부분(=발사부분에 가까운 부분)


참고: https://docs.unity3d.com/kr/530/Manual/class-TrailRenderer.html

반응형

Vector3.Distance


두 위치 사이의 거리를 반환한다.


일정거리 안에 플레이어가 접근하면 반응하도록 하기위해 Vector3.Distance를 이용한다.


Vector3.Distance() 사용법

float distance = Vector3.Distance(코인의 위치, 플레이어의 위치);


적용하기

Coin 스크립트

public void CoinMove()

{

dir= (playerpos.position - transform.position).normalized;

acceleration= 0.2f;

velocity = (velocity + acceleration* Time.deltaTime);

float distance = Vector3.Distance(playerpos.position, transform.position);

if (distance <= 3.0f)

{

transform.position = new Vector3(transform.position.x + (dir.x * velocity),

   transform.position.y,

transform.position.z+(dir.z * velocity));

}

else

{

velocity = 0.0f;

}

}

코드해석

direction = (playerpos.position - transform.position).normalized; : 코인위치와 플레이어의 위치를 뺀 값을 단위 백터화 한다.

acceleration= 0.2f;  : 가속도

velocity = (velocity + acceleration* Time.deltaTime); :  한 프레임으로 가속도 계산


간단하게 구현하기에는 Distance를 사용하면 좋긴하지만, 좀 더 최적화된 퍼포먼스를 위해서는 밑에 있는 것들을 이용하는것을 추천한다.ㅎㅎ

1) Vector3.Distance

2) Vector3.magnitude

3) Vector3.sqrMagnitude


참고 : https://docs.unity3d.com/kr/530/ScriptReference/Vector3.Distance.html


반응형

Animator Controller Layers

애니메이터 컨트롤러의 상태 머신들은 레이어로 나눌 수 있다.

예를들어 다른 신체 부위의 움직임을 나타낼때 사용 된다.


IK Pass :  Inverse Kinematics 를 체크 하게 되면 그 레이어에 맞는 인덱스와 함께 OnAnimatorIk 함수가 호출된다.

Base Layer는 0이고 그다음에 추가되는 레이어들은 1부터 증가하는 자연수 인덱스를 가지게된다.


추가 되는 레이어들은 이전 레이어에 반응하는 방식과 관련된 추가 옵션이 있다.

Weight : 레이어가 가지는 가중치 값이 ‘0’이면 애니메이션의 전혀 영향을 주지 않는다.

(애니메이션 우선순위)

Mask : 애니메이션에서 신체의 어떤 부분만 제어할 것인지 AvatorMask 를 등록해 정할 수 있다.

Blending :1) Override : 가중치 낮게 지정된 레이어의 애니메이션을 대체한다.

       2) Additive : 기존 애니메이션의 혼합되거나 더해지는 연산을 취한다.



ex) 캐릭터가 숨을 가쁘게 몰아쉬면서 점점 피곤해지는 레이어를 생각해보자

이 예에서, 숨을 가쁘게 쉬는 애니메이션이 더 낮은 레이어에 할당된 애니메이션에 추가된다. 레이어의 가중치를 높이면 피곤한 애니메이션이 더 뚜렷하게 보일 것이다.


Sync : 동기화 할 레이어를 선택할 수 있다. 그러면 선택한 레이어의 애니메이션과 동일한 상태 머신이 생성되지만 움직임이 없다. 이것은 부상당한 행동 같은 것을 표현 할 때

캐릭터가 건강한 상태와 체력을 잃어가는 과정에 이들을 혼합할 수 있다.


Timing : 동기화된 레이어에 있는 각 애니메이션의 지속 시간을 가중치를 기준으로 결정할 수 있다.


기본있는 BaseLayer에는 Walk 애니메이션을 추가한다.


Walk

(팔과 다리를 움직이게 했다.)


handWave 레이어


wavehand


추가 한 handWave 레이어 설정 값

Weight값은 0.5로 주고

Bleding은 Override로 설정했다.


파라미터 hand를 실행할때 손을 흔드는 모습을 볼 수 있다.

그런데 좌우로만 움직이는게 아니라 앞뒤로도 움직인다.

앞뒤로 움직이는 Base Layer와 좌우로 움직이는 Wavehand 레이어가 섞인 모습을 볼 수 있다.



다음은 Avatar를 통해 걷는 애니메이션과 인사하는 애니메이션 상,하체 따로 진행시키는 방법을 알아보자

반응형

The Animation View






하이라키창에서 움직일 오브젝트를 선택하고



애니메이션 창에서  AddProperty를 필요한 속성을 추가한다.



왼쪽에는 속성과 값을 설정할 수있고 오른쪽에는 원하는 시간대에 설정값을 넣어 애니메이션 만들 수 있다.



첫 번째는 원하는 시간대로 이동

두 번째는 프레임 설정(숫자가 낮으면 느려짐)



  

녹화 버튼을 누르면 빨갛게 변한다. 추가 하고싶은 요소를 추가한다.

현재는 위치와 회전값만 프로퍼티로 추가 했기 때문에 Position과 Rotation만 색이 변한 걸 볼 수 있다.

(녹화 버튼을 누른 상태에 값을 주어야함)


게임신에서 움직여도 되지만 정확한 값을 넣기 위해 인스펙창을 통해 설정한다.






The Animator Component




Controlle : 유니티가 생성한 에셋으로 하나 이상의 상태 머신이 포함되어있다.

상태머신? 씬이 실행될 때 어느 애니메이션이 재생될 것인지 결정한다.

Avater : 3D휴머노이드를 임포트할 때 유니티가 생성하는 에셋이다.

모델과 애니메이터를 이어주는 접착제? 같은 역할이라고 생각하면 된다.


Apply RootMotion : 애니메이션이 게임 오브젝트의 트랜스폼에 영향을 줄 수 있는지 여부를 결정한다.

UnCheck하게 되면 애니메이션은 작동하지만 이동하지는 않는다.



Culling Mode : 렌더링 상태가 아닐때 애니메이션이 재생될 것인지 아닌지를 정할 수 있다.

(비용절약) 화면에 보이지 않으면 애니메이션은 작동하지 않는다.



The Animator Controller


Parameters옆의 + 아이콘을 클릭하면

Float, Int, Bool,Trigger

애니메이션의 퀄리티나 조건을 나타낸다.


Animator Window 살펴보기

애니메이터 창에서 애니메이터컨트롤러 상태를 설정할 수가 있다.


처음 생성된 상태는 기본상태(주황색)로 된다.

(기본을 변경하고 싶으면 원하는 상태에서 마우스 오른쪽 -> Set As Default)


상태 편집은 클릭하면 인스펙터창에서 할 수 있다.

맨위 는 이름과 태그로 코드로 참조 가능하며 어떤 상태에 있는 동안 원하는 동작을 수행하게 할 수 있다.


speed  : 일반 애니메이션 속도의 비해 얼마나 빠르게 재생되는지를 참조

Mirror : 애니메이션의 좌우가 반전

Foot IK : 체크하면 애니메이션이 발 미끄러짐이 감소하거나 제거 된다.

Transitions : 다른 상태로 트랜지션할 수있는 상태를 표시,설정


트랜지션 상태 (흰 화살표)

마우스 오른쪽 -> Make Transitions으로 설정



style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;">트랜지션 상태 설정하기

디버그용

Mute : 현재 상태에 연결된 트랜지션을 비활성화 한다.

Solo : 같은 상태에 연결된 모든 트랜지션을 고려하여 그 중에서 Solo가 표기 되지 않은 모든 트랜지션을 비활성화한다.

Conditions : 설정한 파라미터(bool,Int,flat)를 통해 다른 상태로 이동하는 조건을 설정 할 수 있다.


예를 들어 일정 속도값이 생기면 걷는 동작을 취하도록 하려면

void Update()

{

float h = Input.GetAxis("Horizontal");

anim.SetFloat("speed", v);

}

스크립트 작성후 컴포넌트 해주고


애니메이터윈도우에

파라미터 speed를 생성하고


Idle -> Walk

(스크립트로 제어할것이기 때문에 Has Exit Time 언체크!)

speed값이 0.1이 넘으면 걷기 애니메이션이 작동하도록 설정해준다.  



Walk -> Idle

speed값이 0이면 다시 Idle 상태로 돌아 가기 위해 Less는 ‘0’으로 설정한다.



니메이터 윈도우에 Base Layer를 보면 현재 어떤 상태인지 볼 수있다.

Parameters에서는 키보드 위 방향을 누르면 speed 값이 올라가는 걸 볼 수 있다.

반응형

gPlayerPrefs(플레이어프렙스)



키-벨류 방식으로 유니티안에서 간단하게 저장하고 데이터를 불러올수 있다.

getter을 통해 저장하고 setter을 통해 불러온다. 저장가능 용량은 1MB이다.

간단하게 저장할 때 사용한다.(보안x)


사용법 먼저 알아보자


저장하기

PlayerPrefs.SetInt("score", getcoin);

매개 변수안에 key,value를 넣면 된다. 

Setfloat,Setint,Setstring 3가지가있다. 저장하려는 형식의 맞게 사용하면 된다

"score"라는 키값으로  벨류인 getcoin의 값을 저장하고 있다.

(아이템을 먹으면 1씩 증가하는 getcoin)



불러오기 

score = PlayerPrefs.GetInt("score");

불러 올때는 Getter을 사용하는데 score라는 키값으로 getcoin을 불러오는것이다.



적용하기

void Start() {

score = PlayerPrefs.GetInt("score");

getCoin();

}


void OnApplicationQuit() //종료 콜백함수

{

PlayerPrefs.SetInt("score", getcoin);

}

이런식으로 시작할 때 저장한 값을 불러오고 종료할때 값을 저장했다.


삭제하기

유니티를 꺼도 삭제되지 않는다 그렇기 때문에 키워드를 통해 지워줘야한다.

PlayerPrefs.DeleteAll

PlayerPrefs.DeleteKey("키이름")


https://docs.unity3d.com/kr/530/ScriptReference/PlayerPrefs.html




반응형

인터페이스 interface


 클래스를 만들 때 사용하는 규약?



기본구조

interface [인터페이스 이름]

{

}



생성위치

인터페이스는 클래스와 동급의 카테고리이다. 그렇기 때문에 클래스를 생성하는 위치라면 어디든지 만들 수 있다.



예제를 보면서 이해하자



1) 인터페이스 생성

interface IBasic

{

int TestInstanceMethod( );

int TestProperty{  get; set ;}

}

메서드에 내부 구현을 입력할 수 없다.

속성에도 마찬가지로 내부 구현을 입력할 수 없다.


2) 인터페이스 상속

class TestClass : IBasic

{


}

static void Main(string[] args)

{

}


3) 인터페이스 구현

'Ctrl' + '.' 누르면 자동완성 

class TestClass : IBasic

{

public int TestInstanceMethod( )

{

throw new NotImplementedException( );

}

public int TestProperty

{

get

{

throw new NotImplementedException( );

}

set

{

throw new NotImplementedException( );

}

}

}

클래스에서 이후에 구현해준다.



4) 인터페이스 다중 상속

class Program

{


class Parent{ }

class Child : Parent, IDisposable, IComparable

{

public void Dispose( )

{

throw new NotImplementedException( );

}


public int CompareTo(object obj)

{

throw new NotImplementedException( );

}

}

//한 개의 클래스와 두 개의 인터페이스를 상속받는다.


이렇게 상속되면 다음과 같이 세종류로 자료형 변환이 가능해진다.

Child child = new Child( );

Parent ChildAsParent = new Child( );

IDisposable childAsDisposable = new Child( );

IComparable childAsComparable = new Child( );






반응형

Camera.ScreenPointToRay


카메라로 부터의 스크린의 점을 통해 레이를 반환합니다.

스크린공간은 픽셀로 정의되며.

픽셀단위

1번 : 왼쪽 하단의 화면이 (0,0)

2번: 오른쪽 상단이 (pixelWidth,pixelHeight)


if (Input.GetButtonDown("0"))

{


Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

RaycastHit hit;

if (Physics.Raycast(ray, out hit, Mathf.Infinity))

{

print("raycast hit!");

Debug.DrawRay(ray.origin, ray.direction * 20, Color.red, 5f);

Debug.Log(hit.point);

}

}




Debug.Ray를 통해 어느부분을 클릭했는지 씬뷰에서 확인이 가능하다.

hit.point를 통해 스크린상 좌표값을 얻어 올 수 있다.

반응형

Raycast


Physics.Raycast

어떤 콜라이더와 레이가 충돌했으면 true, 아니면 false.


Debug.DrawRay 체크 : 거리와 위치를 디버깅 할 수 있다.(유니티 씬장면에서만 나옴)

Debug.DrawRay(transform.position, transform.forward * 8, Color.red);


(위 scene, 아래 game)


충돌한 오브젝트 반환하기

       RaycastHit hit;

       if (Physics.Raycast(transform.position, transform.forward, out hit, 8))

       { //광선을 쏴서 충돌한 게임 오브젝트를 레이캐스트 변수에 저장처리한다.

           Debug.Log(hit.collider.gameObject.name);

       } //광선이 충동한 게임 오브젝트의 이름을 콘솔창에 출력한다.

콘솔창을 보면 ray에 닿은 오브젝트를 확인 할 수 있다.



중첩되는 오브젝트일경우 Physics.RaycastAll

RaycastHit[] hits; //Raycast데이터 저장용 배열 설정

       hits = Physics.RaycastAll(transform.position, transform.forward, 8.0f);


       for(int i=0; i<hits.Length; i++)

       {

           RaycastHit hit = hits[i];

           Debug.Log(hit.collider.gameObject.name);

       }


Raycast데이터 저장용 배열을 사용한다.

정해진 길이만큼 통과한 오브젝트들의 이름을 반환한다.

반응형

Random.Range 


컴퓨터 프로그래밍 언어에서는 난수라고도 한다.

사실 컴퓨터는 랜덤이란게 있을 수 없기 때문에 일정 범위에 숫자값을 집어넣고

그중에 윈도우나 유니티상에서 시간값을 가지고 숫자를 뽑아내는 것을 난수라고 한다.


유니티에서는 Random.Range가 존재한다.


사용법

Random.Range(min,max ) //min [inclusive]과 max [inclusive]사이의 랜덤 float 수를 반환


주의할점을 값이 int일 경우 max값은[exclusive] 나오지 않는다. 


public class ItemDrop : MonoBehaviour {


    public GameObject Item;


void Start () {

        InvokeRepeating("Spawnitem", 1, 1); //1초에 1번씩 Spawnitem()를 호출한다.

    }


    void Spawnitem()

    {

        

        float randomX = Random.Range(-23f, 19f); 

        if(true)

        {

            Debug.Log("생성");

            GameObject item = (GameObject)Instantiate(Item, new Vector3(randomX, 1.1f,0f), Quaternion.identity);

        }

    }

}


InvokeRepeating : time 초에 /methodName/메서드를 호출한 후, 매 /repeatRate/초 마다 반복적으로 호출

Instantiate(Item, new Vector3(randomX, 1.1f,0f), Quaternion.identity); Item이라는 프리팹을 생성한다.

Quaternion.identity : 회전없음



생성될 아이템 프리팹을 설정한다.



아이템이 랜덤으로 생성되는것을 볼 수 있다.

위 코드는 X위치만 랜덤 생성해 주었지만 Z값도 랜덤 설정하면 사방에서 스폰 될 것이다.



반응형

카메라 시점 바꾸기



Left Shift 버튼을 눌렀을 때 시점을 바꿔준다.

시점이 3개이기 때문에 카메라도 3개가 필요하다

메인카메라 프로젝트 생성시 존재하는 카메라


시점카메라(1인칭)

캐릭터가 움직일때 같이 따라 와야하기 때문에 카메라는 캐릭터 오브젝트 자식으로 넣어둔다.




캐릭터 정면에서 바라보는 카메라


메인카메라를 제외하고 모두 비활성화 해준다.

PlayerController스크립트


public class PlayerController : MonoBehaviour

{

public Camera[] arrCam; //카메라 요소들을 추가한다.

int nCamCount = 3;

int nNowCam = 0;

// 필드값 세팅

Camera[] arrCam : 카메라 활성화/비활성화를 해주기 위한 배열

nNowCam : 현재 활성화 된 카메라의 번호

nCamCount : 카메라 갯수


void Update ()

{

if( Input.GetButtonUp("Fire3"))

{

++nNowCam;


if (nNowCam >= nCamCount)

{

nNowCam = 0;

}


for ( int i=0; i<arrCam.Length; ++i )

{

arrCam[i].enabled = (i == nNowCam);

}

}

}

if( Input.GetButtonUp("Fire3"))...

버튼이 눌리면 nNowCam값을 1증가 시킨다.

if (nNowCam >= nCamCount) ...

세 번째 카메라까지 순서대로 보여주고 다시 첫 번째 카메라로 돌아가게 해주는 코드이다.

for ( int i=0; i<arrCam.Length; ++i )...

NowCam(0번카메라)이면 enabled=true 해주고 나머지 1,2번은 false해준다.

또 NowCam(1번카메라)값이 1이면 카메라 컴포넌트를 enabled=true 해주고 나머지 0,2번은 false해준다.

2번 카메라 일때도 마찬가지 나머지 요소는 enabled를 false시킴


*Fire3가 무엇이냐? InputManager



반응형

오브젝트 찾기



이름으로 찾기



이름으로 오브젝트를 찾는법

GameObject.Find("찾고자 하는 오브젝 이름");


그런데 오브젝트가 비활성화 되어있다면 이방법이 불가능합니다.

부모오브젝트를 찾은 다음에 자식오브젝트를 찾아야합니다.


비활성화 된 오브젝트 찾는법


GameObject.Find("부모 오브젝트 이름").transform.Find("자식 오브젝트이름").gameObject;



인덱서로 찾는법(첫 번째가 0) 

GameObject.Find("Panel").transform.GetChild(0).gameObject;



태그로 찾기


GameObject.FindWithTag("태그명");



위 방법들은 유니티 하이라이키상에 있는 오브젝트를 찾을 수 있다.

사실 게임로직에서는 위에 있는 Find로 특정 오브젝트를 찾는 경우는 드물다. 특히 실시간으로 계속해서 찾는 경우는 더더욱 쓰지않는다. 하이라키상에서 나와있는 모든 오브젝트를 모두 검사해야하기 때문에 그만큼 시간도 오래걸리고 비용도 들기 때문이다. 

반응형

AddListener 이용해서 함수불러오기


버튼 프리팹 동적 생성하기(http://funfunhanblog.tistory.com/15)

동적으로 생성한 버튼을 위 그림 처럼 클릭 시 각각 다른 함수를 실행할 수 있도록 하자





유니티에는 UI버튼 기능중에는 OnClick( )이 있다. 일반적으로는 버튼을 생성하면 인스펙터 창을 통해 적용하면 되는데

동적으로 생성된 버튼에는 당연히 인스펙터창에서 실행할 함수를 적용할 수 가 없다.


그러면 스크립트에서 버튼이 생성됨과 동시에 각 버튼마다 OnClick( ) 기능을 주어야한다.



1) 실행 시킬 메서드 생성(스크립트 생성)

먼저 버튼이 눌리면 실행 할 함수들을 작성해준다.

public class BtnAnimal : MonoBehaviour {


        Debug.Log(" 로그 로그 ");

    }

    public void OnClickRed()

    {

        Debug.Log("레드 클릭");

    }

    public void OnClickDog()

    {

        Debug.Log("강아지 클릭");

    }

    public void OnClickCow()

    {

        Debug.Log("소 클릭");

    }

    public void OnClickOct()

    {

        Debug.Log("문어 클릭");

    }

}

 

2) 함수불러오기 AddListener

저번 포스팅에서 만들어 줬던 동적생성 메소드에서 작성해준다.

public void CreateBtns()

    {

////생략 

      for (int nn = 0; nn < 4; nn++)

        {

if (mbtnPrefab == null)

{

Debug.Log("널값");

mbtnPrefab = Resources.Load<GameObject>("BtnAnimal");

}

GameObject button = (GameObject)Instantiate(mbtnPrefab);

                            mmgr.Add(button); //리스트에 추가


////생략


            Button btnMthod = button.GetComponent<Button>();

            BtnAnimal clickbtn = btnMthod.GetComponent<BtnAnimal>();

            if (nn == 0)

{

btnMthod.onClick.AddListener(()=> { clickbtn.OnClickRed(); }); 

}

else if(nn==1)

{

btnMthod.onClick.AddListener(() => { clickbtn.OnClickDog(); }); 

}

else if (nn == 2)

{

btnMthod.onClick.AddListener(() => { clickbtn.OnClickCow(); }); 

}

else if (nn == 3)

{

btnMthod.onClick.AddListener(() => { clickbtn.OnClickOct(); }); 

}

(명시적으로 표현하기 쉬운 if else 사용)

AddListener을 이용하여 BtnAnimal에 있는 함수를 불러오고 있다.


*AddListener : 함수를 불러온다. 콜백






반응형

3D 물리 Physics #1






Adding Physics Forces



마우스를 클릭하면 forward방향으로 물리적 힘을 가해지도록 해보겠습니다.


private void OnMouseDown()

{

Debug.Log("클릭");

Rigidbody Rigidoor = DOOR.GetComponent<Rigidbody>();

Rigidoor.AddForce(transform.forward * 1500);

}


Rigidoor.AddForce(transform.forward * 1500.ForceMode.);

ForceMode. 뒤에 설정값을 다르게 줄수도 있습니다.

ForceMode.Force : 질량의 영향값을 받아 작동, 연속적인 힘을 가하는 경우

ForceMode.Accelration 질량의 영향값 받지 않고 작동, 가속력

ForceMode.Impulse : 질량의 의해서 순간적으로 변함

ForceMode.VelocityChange : 질량의 영향받지 않고 짧은 순간에 적용

예상했던 장면이 나오지 않는다면 ForceMode를 바꿔보는것도 좋을것 같습니다.



private void OnTriggerStay(Collider other)

{

Rigidbody trigger = other.GetComponent<Rigidbody>();

trigger.AddForce(Vector3.up * 20f,ForceMode.Acceleration);

}


OnTriggerStay를 통해 이런 장면도 연출이 가능하겠죠?? 




Adding Physics Troque

이번에는 축을 중심으로 회전을 주겠습니다.

private void OnMouseDown()

{


Rigidbody RigObj = obj.GetComponent<Rigidbody>();

RigObj.AddTorque(transform.up * 1500);

RigObj.AddTorque(transform.right *2000);

}


RigObj.AddTorque(0, 10, 0); 이렇게도 사용이 가능합니다.

Forces와 마찬가지로 ForceMode 설정이 가능합니다.




#2에서는 픽스조인트,스프링조인트,피직스메티리얼에 대해서 알아보겠습니다








반응형

Character Controller


캐릭터 컨트롤러(컴포넌트)

캐릭터 컨트롤러(CharacterController)는 리지드바디(rigidbody)를 다루지 않고,

충돌에 의한 움직임을 다루기 쉽도록 해준다.


캐릭터 컨트롤러는 힘(관성, 중력 등)에 의해 영향을 받지 않고, Move함수가 호출되었을 때만 움직이게 됩니다.

충돌에 의해 힘이 가해졌을 때에만 움직임을 수행한다.


Slope Limit : 경사의 한계를 도의 단위로 나타낸다.

stepOffset : 캐릭터 컨트롤러의 단위의 스텝 오프셋값을 나타낸다(설정 값보다 낮은 높이의 계단만 오를 수 있다.)

Skin Width:  미터단위의 오프셋 설정값보다 낮은 계단만 오를 수 있다.

Center : 플레이의 무게중심

Radius : 캡슐의 반지름

Height : 캐릭터의 캡슐의 높이




CharacterController가 사용할 수 있는 기능과 설정



void Start ()

{

m_Ctrl = GetComponent<CharacterController>(); //컴포넌트에 접근하기 위해 m_Ctrl 필드명을 설정해준다.


}

void Update()

{

if( m_Ctrl.isGrounded == true ) //캐릭터가 땅에 위치하면

{

float fRot = fRotSpeed * Time.deltaTime;

float hor = Input.GetAxis("Horizontal");

float ver = Input.GetAxis("Vertical");

transform.Rotate(Vector3.up * hor * fRot); //Rotate(회전할 기준 좌표 축 * 변위값 * 회전속도)


moveDir = new Vector3(0, 0, ver * fMoveSpeed); //왼쪽과 오른쪽 키보드입력은 이동이 아닌 방향을 바꿈

//캐릭터는 앞으로만 움직이기 때문에 Vertical만 Vector값을 설정한다.

moveDir = transform.TransformDirection(moveDir); //로컬 좌표계 -> 월드 좌표계

if( Input.GetButton("Jump") == true )

{

moveDir.y = fJumpSpeed; //점프 버튼(스페이스바) 입력시 y축으로 힘을 준다.

}

}

}




반응형

버튼(프리펩,Prefab) 동적생성


   

BtnB를 클릭하면 그림 처럼 각각 다른 button 4개가 생성되게 만들겠습니다.


1)Panel 세팅



먼저 UI Panel 아래에 BtnGroupWindow를 만들어 줍니다.

button 4개 위치를  BtnGroupWindow 버튼 관리와 위치를 잡아주기 위해서입니다.


2)프리팹(견본생성)


동적으로 프리팹을 만들기 위해서는 먼저 복사?가 될 프리팹을 1개 만들어 주어야합니다.

GameObject -> UI -> Button

Button을 생성한 다음

Hierarchy창에서 Project창으로 드래그로 하면 프리팹이 만들어집니다.



3)BtnGroupWindow스크립트 작성 (BtnGroupWindow 오브젝트에 추가합니다.)

  

public class BtnGroupWindow : MonoBehaviour {

GameObject mbtnPrefab;

   public Transform panelPos;

mbtnPrefab이란 이름으로 프리팹으로 만들어 주기 위한 세팅입니다.


   string[] mstrImageName = new string[]

   {

        "bonbon_cha0025", "bonbon_cha0021"

                       ,"bonbon_cha0020", "bonbon_cha0014"

   };


버튼 4개가 모두 다른 이미지이기 때문에, 이미지를 바꿔 주기위해 배열을 세팅해줍니다.

이미지이름을 문자열로 넣어줍니다.


   void Start () {


mbtnPrefab = Resources.Load<GameObject> ("BtnAnimal");


if (mbtnPrefab ==null)

       { Debug.Log("mbtnpreprefab==null"); }


   }

mbtnPrefab에 아까 만들어 놓은 BtnAnimal 프리팹을 로드해서 넣어줍니다.


   public void CreateBtns()

   {

       for (int nn = 0; nn < 4; nn++)

       {

           

           GameObject button = Instantiate(mbtnPrefab);

//Instantiate(생성할 물체);

           RectTransform btnpos = button.GetComponent<RectTransform>();

//RectTransform을 잡기 위한 코드

button.transform.position = gameObject.transform.position;

//버튼프리팹의 최초 생성 postion값은 부모인 BtnGroup으로 맞춰줍니다.

//텍스처 바꾸기

Image image = button.GetComponent<Image>();

//생성할 버튼 Image 컴포넌트에 접근

Sprite btnsprite = Resources.Load<Sprite>(mstrImageName[nn]);

//nn이 0부터 3까지 도는 동안 각각에 맞는 이미지 sprite을 바꿔줍니다.

image.sprite = btnsprite;


btnpos.SetParent(gameObject.transform);

//SetParent 부모오브젝트 설정 여기서는 부모의 transform을 받기 위함입니다.

btnpos.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left,(20*nn), 36);

                       //왼쪽 모서리로 부터,얼마만큼 떨어져서 ,버튼의 크기

//버튼의 크기는 만들어 놓은 프리팹의 크기로 맞춰주는게 좋습니다.

       }

}

+원하는 위치에 생성이 안된다면 Panel과 BtnGroupWindow의 Rect Transform의 값을 설정해줍니다.


반응형

캐릭터 점프구현


이번에도 역시나 Roll a Ball을 활용한다.


캐릭터 점프는 실제 위치값을 움직이는 Translate보다는 

물리적 힘을 위로 주어서 튀어 오르는듯한 느낌을 주는 AddForce를 이용하는게 좋아보인다.


먼저 소스코드를 살펴보자


void Start( )

{       

        rb = GetComponent<Rigidbody>();

        jumpCount = 1; //점프 가능횟수

        isGround = true; //땅에 있을때

}

jumpCount는 1로 초기화 해준다.

isGround는 true로 땅에 있을때 캐릭터가 점프를 할 수 있는 환경이라고 판단하기 위해 선언 한 것이다.


void FixedUpdate ()

{        

        if (isGround) 

        {

            jumpCount = 1;

            if (Input.GetKeyDown("space")) //점프

           { 

                if (jumpCount==1){             

                    rb.AddForce(0, 300f, 0); //점프

                    isGround = false;

                    jumpCount = 0;

                }

           }

        }

    }

update문에서는 우선 플에이어가 있는 위치가 땅바닥인지 체크를 해준다.

땅바닥이라면 jumpCount값을 1로 만들어준다.

그리고 스페이스바가 눌리면 다시 jumpCount가 1인지 체크를 한다. 

두 if문이 모두 맞다면 플레이어의 rigidbody에 y값에 힘을 주어 캐릭터가 위로 튀어 오르게 만들어준다.

점프를 하고 있는 중에는

플레이어의 위치가 땅바닥이 아니기 때문에 isGround는 false로 설정하고

점프를 한번 했기 때문에 다시 jumCount는 0으로 만들어준다.(다시 점프를 할수 없게)

    private void OnCollisionEnter(Collision col)

    {

        if (col.gameObject.tag == "ground")

        {

            isGround = true;    //Ground에 닿으면 isGround는 true

            jumpCount = 1;          //Ground에 닿으면 점프횟수가 1로 초기화됨

        }

    }

OnCollision물체가 플레이어에게 닿으면 아래 코드들이 활성화된다.

플레이어에게 Collision(여기서는 땅바닥)이 닿게 되면 

jumCount를 1로 만들어준다. 


여기서 알아야 할 것은 

JumCount와 플레이의 위치 isGround를 체크 하지 않고 스페이스바를 여러번 누르게 되면 

계속해서 하늘로 치솟아 무한 점프가 될것이다 

그것을 방지하기 위해 체크한다. (캐릭터가 땅에 도착해야 다시 점프를 할 수 있게)

그리고 OnTrigger이 아닌 OnCllision을 사용했다는 점도 파악해야한다.


반응형

OnTrigger , OnCollision 비교하기

 

Collider

유니티에서 충돌체크를 하기 위한

필요한 컴포넌트이다.

 

3D오브젝트를 생성하면 Collider가 자동적으로

추가 되어있다.

 

먼저 Trigger에 대해 살펴보자

1) void OnTriggerEnter(Collider other) : Trigger에 들어갔을 때

2) void OnTriggerStay(Collider other) : Trigger안에 있을때

3) void OnTriggerExit(Collider other) : Trigger를 벗어 날때

 

 

1) OnTriggerEnter


    void OnTriggerEnter(Collider other) 

{

if (other.gameObject.CompareTag ("Pick Up"))

{

other.gameObject.SetActive (false);

 

count = count + 1;

           

            SetCountText ();

            Debug.Log(count);

}

코드는 Roll a Ball 플레이 스크립트

Collider가 닿게 되면 아래 코드가 실행된다.

 

 

흰색 볼에 스크립트를 추가 하였다. 그리고 노란색 Cube에 닿을때 마다

왼쪽 상단에 Count 값이 증가되고 있는것을 볼수 있다.

 

 

2) OnTriggerStay

우선 // other.gameObject.SetActive (false); 

위 코드면 큐브가 사라진다.

Collider가 닿은 상태를 유지 하는 동안을 보기위해

주석 처리하고 실행했다.

 

Count가 닿는 동안 계속 증가하는것을 볼 수 있다.

그렇다면 Exit도 충분히 예상 가능하다.

 

 

3) OnTriggerExit

 

노란색 큐브를 닿는 순간에는 아무일이 일어나지 않지만

큐브를 지나쳐가는(벗어나는) 순간 Count가 올라간다.

 

OnTrigger를 알아봤는데 꼭 설정해 줘야하는것들이 있다.

노란색큐브와 흰색공에는 반드시 충동체크를 할수 있는 Collider가 있어야한다.

 

그리고 두 오브젝트중 하나는 Collider에 is Trigget에 체크가 되어있어야한다.

위 게임같은 경우에는 큐브에 체크가 되어있다. 흰색공에 체크 되어있지 않는 

이유는 is Trigger 가 체크가 되면 흰공에는 Rigidbody에 무게 값을 갖고있기 때문에

땅을 통과해 밑으로 사라져버린다.

 

 (하지만 여기서는 Cube에도 Rigidbody에 UseGravity에 체크되어있는데 땅으로 떨어지지 않고있다. Is Kinematic를 체크 하고있기 때문)

 

 

 

OnCollsion

void OnCollisionEnter(Collision other) : Collision에 들어 갔을 때

void OnCollisionStay(Collision other) : Collision과 충돌하고 있는 중

void OnCollisionExit(Collision other) : Collision과 충동에서 벗어 났을 때

 

 

Trigger와 함수의 기능은 똑같다

OnTrigger : 물리 연산 안함, 관통 가능, Collision 보다 연산이 적어서 효율적

OnCollision : 물리 연산을 통해 충돌 처리, 관통 X, 많이 사용하면 부하?.


여기서 주의할 점은 충돌 할 오브젝트들이 Rigidbody를 갖고 있다면오브젝트 모두 isTrigger가 언체크 되어있어야 하고 또,둘중 한 오브젝트는 Is Kinematic가 언체크 되어 있어야 한다.

 

 

반응형

UI기초 : 버튼사용하기


버튼A를 누를때 마다 왼쪽 위 캐릭터모양 ON&OFF하기




1) UI -> Canvas를 만든다. Rect Transform을 사용하기 위해

Rect Transform은 유니티 전체 좌표가 아니다

canvas안에서 기준을 표시한다.(canvas아래 자식 오브젝트들은 부모인 canvas에 로컬좌표에 따라서 설정된다.)


2) UI -> Canvas아래 자식 오브젝트로 Button을 생성한다.


3) 버튼을 클릭 했을때 변화를 주기 위한 스크립트 작성

   public void BtnOnOff()

   {

       bool isview = !gameObject.activeSelf;  //엑티브 상태를 반환한다.(켜져있는지 없는지)

       gameObject.SetActive(isview);

   }

4) UI -> Image 생성 : 변화 될 이미지

5) 작성한 스크립트를 이미지에 추가한다.(버튼이 아닌 이미지에 추가)

6) 버튼 OnClick 컴포넌트

OnClick은 버튼을 클릭 했을때 발동된다.

생성한 Image를 넣어주고 알맞는(BtnOnOff) 함수를 찾아서 설정한다.


완료!

반응형

Roll a Ball



Materials 적용하기

Asset에서 빈Materials을 생성한다.

그리고, Texture파일을 빈Materials에 Albedo에 끌어다 놓는다. 


Physic Material

Materials 에 반동을 주거나 마찰력을 주기 위한 Materials 

Component -> Physic Material 생성한다.



Physic Material 인스펙터창을 살펴보자

Dynamic Friction : 이미 이동중일 때 마찰

Static Friction : 정지시 마찰

Bounciness : 반동방식


나는 벽에다 Physic Material를 추가 하고 Bounciness값을 0.5주었다.



그랬더니 ~

볼을 벽에 부딪히면 전과 다르게 튕겨 나온다.

(캐릭터 움직임에는 translate으로 위치값을 변경해주는 방법과

rigdbody를 통해 물리적힘을 줘서 물체를 움직이는 방법이있는데

이 게임은 rb.AddForce (movement * speed); 로 물체에 힘을 줘서 움직이게 하고있다.)





코드분석






코드분석 : PlayerControllers

public으로 변수를 할당하면 유니티 인스펙터창에서 보인다. 변경가능 (값 적용 우선순위 : 인스펙터 > 소스코드창)

speed : 스피드 값

Text CountText; 현재 점수를 불러올 UI 텍스트

Win Text : 승리시 띄울 UI텍스트


void Start ()

{

rb = GetComponent<Rigidbody>();


count = 0;

SetCountText ();

winText.text = "";

}

주요코드

rb = GetComponent<Rigidbody>();

컴포넌트 Rigidbody를 가져와 변수 rb로 정한다.


void FixedUpdate ()

{

float moveHorizontal = Input.GetAxis ("Horizontal");

float moveVertical = Input.GetAxis ("Vertical");


Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);


rb.AddForce (movement * speed);

}

주요코드

rb.AddForce (movement * speed);

Rigidbody를 물리적 힘을 가해 플레이어를 이동시킨다.



void OnTriggerEnter(Collider other)

{

if (other.gameObject.CompareTag ("Pick Up"))

{

other.gameObject.SetActive (false);


count = count + 1;


SetCountText ();

}

}

주요 키워드

CompareTag : 해당하는 태그를 찾는다.

SetActive : 컴포넌트에 토글? 켜고,끄기

OnTriggerEnter: Collider가 다른 트리거 이벤트에 침입했을 때 호출

(지금 위 코드에서는 pick up 태그가 붙은 오브젝트(노란상자)에 Collider가 닿으면 count를 1증가한다.)




반응형

Quaternion


쿼터니언이은 회전을 표현하기 위해 사용된다.

복잡한 수를 기반하고 있어 직관적으로 이해하기 쉽지 않다.
그래서 대부분 기존의 회전축을 취하고(즉, Transform으로 부터) 새 회전을 생성하기 위해 사용한다.



  •  Quaternion.LookRotation : 지정된 upwards와 upwards 방향들과 함께 rotation을 생성합니다.

  •  Quaternion.Angle :두개의 roation b와 b 사이의 각도를 반환합니다.

  •  Quaternion.Euler : z축 주위로 z, x축 주위로 x, y축 주위로 y 각도만큼 회전한(순서대로) Rotation을 반환합니다.

  •  Quaternion.Slerp : /from/과 /to/사이를 /t/로 구형보간 합니다

  •  Quaternion.FromToRotation:/fromDirection/에서 /toDirection/으로 회전한 rotation을 생성합니다.

  • Quaternion.identity.: 쿼터니언은 "회전 없음"을 의미합니다. 오브젝트는 완벽하게 월드 좌표 축 또는 부모의 축으로 정렬



쉽게 정리하면 transform.rotation에 대입하기 위한 변수 타입이라고 생각하면 쉽다.

Quaternion.Euler(x: float , y: float, z: float) :오일러는 절대각도를 의미.


ex)

현재 transform.Rotate 값이 (0,10,0) 이다


1) transform.Rotate(0,30,0) (더하기 개념)

=>Rotation에 x,y,z가 0,40,0 //현재 상태에서 증가


2) (transform.rotation=Quaternion.Eular(0,30,0))

=> Rotation에 x,y,z가 0,30,0


Eular는 파라미터로 들어온 벡터의 오일러 값을 쿼터니언으로 바꿔주는 함수이다.




반응형




열겨형 Enum 사용법




const 대신 사용하는데 유니티에서 보통 오브젝트의 상태를 구분하여

열거형 타입의 변수를 선언및 할당하여 그 값의 맞는 액션을 취하 도록 한다.


scriptA

public enum eMove_Type { eMove_None, eMove_Normal, eMove_Dash }

public class MoveObj : MonoBehaviour {


   Vector3 vDestPos = new Vector3(7.0f, 1.5f, 1.0f);

   Vector3 vDir;


   public float mfSpeed = 1.5f;

   eMove_Type memove_Type = eMove_Type.eMove_None;



scriptB

eMove_Type mpreType = eMove_Type.eMove_Normal;



반응형



캐릭터 회전시키기 :

마우스 이동 시 큐브가 좌우로 움직임


public class PlayerMove : MonoBehaviour {

     

       float rotSpeed = 1.0f; //ADD

// Update is called once per frame

void Update () {

      


       // 마우스 입력

       float MouseX = Input.GetAxis("Mouse X");


       transform.Rotate(Vector3.up * rotSpeed * MouseX);

}

}

transform.Rotate(회전할 기준 좌표 축 * Time.deltaTime * 회전 속도 * 변위 값)

출처:http://itmining.tistory.com/48



반응형



위 그림처럼 큐브가  키보드 입력을 받으면 앞,뒤,왼쪽,오른쪽으로 이동하게 만들기




public float speed = 5.0f

    //캐릭터가 움직일 스피드설정 public으로 함으로써 유니티 인스펙터 창에 설정이 가능해짐


void Update () { // 매프레임 반복되기때문에 Update에 써준다.


if(Input.GetKey(KeyCode.UpArrow)) //키보드 위쪽 화살표가 눌릴경우  

{ this.transform.Translate(Vector3.forward * speed * Time.deltaTime); } 

// this(이스크립트를 가지고있는).transform(컴포넌트).Translate(움직을 주는)값을

// Vector3(3D 방항).forward(앞).*speed(속도).*Time.deltaTime(1초당)

if(Input.GetKey(KeyCode.DownArrow))

{ this.transform.Translate(Vector3.back * speed * Time.deltaTime); }

if(Input.GetKey(KeyCode.RightArrow))

{ this.transform.Translate(Vector3.right * speed * Time.deltaTime); }

if(Input.GetKey(KeyCode.LeftArrow))

{ this.transform.Translate(Vector3.left * speed * Time.deltaTime);}



*Delta Time 이전 프레임의 시작 시간과 현재 프레임의 시작 시간의 차이



반응형

월드 좌표

-오브젝트의 위치를 나타내는 좌표계로, 화면의 중심을 원점(0,0,0)으로 하는 3차원 상대좌표계 월드 좌표계는 게임 화면을 투영하는 카메라의 위치와 회전 상태에 따라 달라지므로 화면의 중심이 원점이 되는것은 아니다.

쉽게 얘기하면

월드를 기준으로 태양이 우주를 중심으로 0.0.0에 위치라고 하면 내위치를 말하는 것이 월드 좌표다. 


로컬 좌표

자신의 위치를 중심으로 생각하고 각각의 그 오브젝트의 위치에서 어디있는지 계산하는것이다.

만약 부모 객체가 있다면 부모객체의 좌표와의 거리를 나타낸다. 상대좌표라고도 한다.


스크린 좌표

-단말기의 화면 좌표계로, 화면의 왼쪽 아래를 원점으로 하는 평면 절대좌표계 마우스 클릭이나 터치는 스크린 좌표계를 이용해서 처리한다. 카메라의 위치나 각도와 상관없이 일정


뷰 포트 좌표

  • 화면에 글자나 2D이미지를 표시하기 위한 좌표계로, 화면의 왼쪽 아래를 (0,0)오른쪽 위를(1,1)로 하는 평면 상대 좌표계이다.


출처 :​ http://hyunity3d.tistory.com/m/post/368

반응형

break 키워드


조건문 또는 반복문을 벗어날 때에 사용하는 키워드입니다.


ex)


while (true)

{

Console.writeLine("무한반복문");

}


위 예같은 경우 계속 while문 안에있는 문장을 반복해서 출력하겠죠??


ex)

while (true)

{

Console.WriteLine("숫자를 입력해주세요(홀수를 입력하면 종료):");

int input = int.Parse(Console.ReadLine());


if (input % 2 == 1)

{

break;

}

}


이 예제는 어때요??

짝수를 입력하면 계속 실행하고

홀수를 입력하면 if문을 통해 break키워드가 실행되면서 바로 종료가 됩니다.




continue 키워드


반복문 내부에서 현재 반복을 멈추고 다음 반복을 진행하는 키워드입니다.


ex)

for(int i=1; i<=10; i++)

{

if(i%2==0)

{

continue; //짝수이면 다음 반복문으로 넘어갑니다. 아래코드 실행X

}

Console.WriteLine(i);

}


break문과 continue문을 활용하여 반복,조건문을 잘 활용 하시면 되겠습니다~

하지만 너무많은 사용은 코드의 가독성과 유지보수가 좋지 않기 때문에

남용은 좋지 않다고 하네요~





반응형

여러분들 PRG게임 좋아하시나요??


RPG게임이란



Role Playing Game

유저가 게임 속 캐릭터들을 연기하며 즐기는 역할 수행게임! 

(네이버지식백과)



게임속 자신의 캐릭터를 육성하는 게임이죠!



RPG중에서도

여전히 사랑받는 게임


로그라이크(Rogue - like) 형식

게임을 제작중입니다.


로그라이크를 잘모르시는 분들이 있으시겠죠??

저도 제작하기 전까지는 몰랐습니다 .ㅎ.ㅎ


간단히 설명 드리자면


1980년대에 캘리포니아에서 대학을 다니던 세 학생이

한 게임을 개발합니다. 이름하여 Rogue

세련미는 떨어지는 다소 투박한 게임이지만

신선한! 게임플레이를 선보이며 당시 큰 반응을 일으켰답니다.


큰 특징으로는,

1. 하나로 연결된 방대한 던전세계

2. 죽으면 처음으로 시작하는 무자비한 시스템

3. 무작위로 생성되는 시스템


여러 게이머의 도전 정신을 자극하게 되는데요


이 게임 인기를 끌다보니 당연히 파생된

게임들이 나오기 시작했답니다. 

(itunes.apple.com참조)



그리하여  Rogue를 닮았다고 해서 

'로그라이크' 입니다.

반응형

+ Recent posts