본문 바로가기

블루프린팅/2. 블루프린트 프로그래밍

[2.블루프린트연습] 액터 이동시키기

이제 BP_Cube를 움직이게 해보자.

이전 채터에서 연습했던 홀수 합구하기 노드들을 지울수도 있지만 함수를 만들어 저장해 놓겠다.

MyBluePrint>Functions 옆 +를 누르고 OddSum 이라고 이름을 변경하자. 다시 이벤트 그래프로 돌아와

맨 왼쪽 Event BeginPlay만 빼고 다 선택한 다 선택후 Ctrl-X로 잘라내기 하고 

OddPrint 탭을 눌러 Ctrl-V로 붙여주고 맨 왼쪽에 OddPrint 노드를 연결해준다.

이제 EventGraph로 돌아와 방금만든 함수 OddPrint를 끌어다 놓고 Event BeginPlay와 연결해주고 플레이해보면 잘된다. SaveAll해주고 연결했던 OddPrint 노드는 지워준다. 에디터 오른쪽 밑을 보면 *Unsaved를 누르면 된다.

그래프에 우클릭후 SetActorLocation노드를 추가하고 EventBeginPlay와 연결해준다.

플레이해보면 BP_Cube가 좌표(0,0,0)으로 이동해 있다. 중앙에 약간 주저 앉아 있다.

New Location 파라미터를 (100,0,0)으로 바꾸고 플레이 해보면 액터는 뒤로 물러나게 된다.

이제 움직이게 해보겠다.  For Loop노드를 추가하고 Last Indexfmf 500으로 하고 index를 Set actor location노드의 New Location입력에 넣어준다.

컴파일후 플레이해보면 우상뒤쪽으로 떠 있다.  플레이를 일시정지하고 SHIFT_F1을 눌러 BP_Cube의 Transform을 확인해보면 Location X,Y,Z가 ( 500,500,500)으로 되어 있다.

x만 변경하고 싶다면 New Location의 연결을 ALT-좌클릭으로 끊고 우클릭해서 Split Struct Pin을 선택하면  XYZ로 분리된다.

For Loop Index에서 New Location X로 끌어주고 아까 만들어져있던 형변환 노드는 은 지워준다

컴파일 저장후 플레이해보면 이제 X축으로 500만큼 이동해 있다.

 잘 생각해보면 이동해 있지 움직이지 않았다. For Loop문에서 1~500번까지 index를 발생했는데 Print문은 분명해 1~10까지 잘 찍어줬는데 이건 게임엔진의 동작원리를 파악해야 한다. C프로그램에서 콘솔 Print문은 한번의 출력에 한번씩 화면을 갱신하도록 되어있어 우리가 출력한 숫자들이 스크롤 되는것 처럼 보인다. 언리얼은 여러줄은 보이지만 한번에 보였다.

그런데 Actor는 최소한 500개의 BP_Cube 액터가 겹쳐서라도 보여야할것 같은데 그렇지 않다. 기본적으로 액터는 위치가 갱신되면 이전 액터를 지운다. 그리고 가장 문제점은 우리가 Event BeginPlay 이벤트를 사용했다는 거다. 플레이를 누르자마자  ForLoop가 순시간에 500번이 돌면서 분명히 BP_Cube를 500번 그렸지만 그게 너무 순식간이라 우리는 맨 마지막 위치의 BP_Cube만 보게된다. 

움직이게 보이기 위해서는 매프레임 호출되는 EventTick이라는 이벤트를 사용하면 된다. 그래프를 잘보면 맨처음부터 있었던 3개 이벤트중의 맨 아래노드다.  ForLoop노드를 지우고 Set Actor Location과 EventTick을 연결해준다.

빈곳을 우클릭후 GetActorLocation을 추가하고  Return Value핀을 우클릭후 Split Stuct Pin을 선택한다. 그럼 X,Y,Z 세개의 스칼라값으로 변경된다.

매TikEvent마다 X값을 증가시키기위해 + 노드를 추가하고 연결해준다 Add노드의 아래입력값은 1로 해서 매Tik1씩 더해줄것이다.

컴파일 플레이해보면 BP_Cube가 X축으로 이동한다. 끝도없이 ㅎㅎ 잘보면 BP_Cube가 (0,0,0)이 아닌 원래 제자리에서 이동한다 시작 위치를 GetActorLocation을 이용해 받아와서 X축만 1 증가시켜 Set ActorLocation에 전달하기 때문이다.

ActorLocation = ActorLocation + new Vector3(1,0,0); 같은 느낌이다.  

GetActorLocation,Set ActorLocation함수는 BP_Cube액터의 Transform컴포넌트의 Location변수를 읽거나 쓰는 함수이다.

Add 노드를 Y값과 연결해 보겠다. 연결하다 보면 기존 노드가 끊긴다. 끊을 노드는 ALT+좌클릭으로 끓어주면 된다.

컴파일 플레이하면 오른쪽 Target을 겹치면서 지나간다. 강제적으로 위치만 바꾸다보니 물리현상이 안 일어난다. 유니티의 RigidBody같은게 있어야 할것 같다. EventTick 실행 연결을 ATL+좌클릭으로 일단 끊겠다. 이렇게만해도 배치된 노드들은 실행되지 않는다. 지우지 않아도 된다.

따라서 우클릭후 Location으로 찾아봤더니 Add Impuse at Location이라는함수가 있었고 연결후 실행해봤더니 Set Simulate Physics가 필요하다고 경고가 떠 우클릭후 Set Simulate Physics를 추가후 꼭 Simulate를 체크해준다.

Event BeginPlay와 연결해주었다. 일단 EventTick의 연결은 끊어서 관섭을 막겠다.

이제 우클릭후  Add Impuse at Location를 추가해주고  Impuse값은 Y:200000으로 한다. 유니티에 비해 값이 무척크다. 처음에는 꿈쩍도 안해 실험적으로 얻은 값이다. ㅠㅠ. GetActor Location을 추가해 Location과 연결해준다  필요없을것 같아 연결을 끊어보니 뱅글뱅글 돌면서 날아갔다. 힘을 주는 초기 위치 같다. 

플레이 해보면 Y축으로 출발해 BP_Target과 충돌후 반동으로 튀어나오지만 BP_Target은 꿈쩍도 하지 않는다 Movable인데도.  BP_Target에도 Set Simulate Physics를 넣어줘야한다. 레벨에디터에서 BP_Target의 Edit BP_Target을 클릭해 에디터를 연후 이벤트그래프에서 우클릭후 Set Simulate Physics(Cube)를 추가해주고 Event BeginPlay와 연결해준다.

컴파일후 플레이 해보면 충돌후 옆으로 밀리는걸 알수 있다.

이제 BP_Target 컴포넌트에 Box Collision을 추가해주고 디테일에서 Shape를 BP_Target보다 살짝 크게 설정해준다.

Box는 Cube의 자식으로 만든다. 마우스로 클릭후 드래그 하면 됨. (자식이 아닐 경우 물리엔진이 Cube에만 적용되어 있어  Box(Collision)은 움직이지 않아 원하는 결과를 얻을 수 없다.

Box Collision컴포넌트를 넣어주었기 때문에 이벤트그래프에서 EventActorBeginOverlap을 사용할 수 있다. 다음과 같이 노드를 추가해준다. Impulse값은 Z:200정도로 해준다. 먼저 Add Impulses는 액터에 충격을 주는것이었지만 이번에 사용하는 Add Velocity Change Impuse를 액터의 속도를 순간적으로 가속하는것이라 좀더 민감한것 같았다. GetActorLocation를 사용해야 충돌의 방향이 좀더 명확한것 같았다.

컴파일후 실행해보면 멋지게 위로 날라간다. 충돌의 힘으로 약간 Y방향으로 밀리면서

Set Simulate Physics노드를 Event ActorBeginOverlap다음에 연결해도 잘 동작한다. 다만 이러면 충돌전까지는 물리시뮬레이션이 안돼어 플레이어가 가서 부딪칠경우 밀리지 않는다 경우에 따라 잘 사용하면 될것 같다.

 

Add Impuse at Location라는 함수는 아마 순간적으로 힘을 주어 발사하는 함수 일것이다 따라서  총알발사와 같이 한번의 폭발로 힘을 주어 그다음부터는 자연스러운 감속이 일어나는걸 구현하기 때문에 Event BeginPlay에서 사용할것 같다. 

AddForce at Location과 함수를 이용하면 TickEvent를 이용해 매 프레임 힘을주어 가속을 유지할 수 있을듯 하다.

컨텐트드로워에서 +Add>BlueprintClass>Actor로 만든후 이름을 BP_Cone으로 이름을 변경한다

블루프린트 에디터가 열리면 Components에서 +Add를 클릭해 StaticMesh를 추가하고 StaticMesh를 선택하고 디테일에서 Cone을 선택한다.

저장하고 컨텐트드로워에서 BP_Cone을  레벨에디터 뷰포트에 끌어다 놓고  Target 옆에 위치시킨다.

BP_Cube가 BP_Target과 충돌할때 BP_Target도 같이 위로 점프되도록 만들어 보겠다.

이 작업은 BP_Target 블루프린트에서 하겠다.

My Blueprint패널 Variables +를 클릭해 Target이라는 변수를 추가한다. 타입은 BP_Cone으로 찾아 ObjectReference로 클릭한다.

방금만든 변수 Target의 디테일패널에서 Instance Editable을 체크해준다 그래야만 외부에서 참조를 설정할 수 있다. 유니티 public같은 기능이다.

방금만든 변수 Target을 끌어다놓고 Get Target을 선택한후 핀을 끌어 Set SimulatePhysics를 선택한다. 꼭 Simulate를 체크해준다.

출력핀에서 Add Velocity Change Impuse at Location을 추가하고 Impulse Z:500으로 한다. 다음과 같이 연결후 Location 입력에서 선을 끌어 Get Actor Location을 추가하고 입력으로 Target을 연결해준다. 

BP_Target에서 BP_Cone을 설정하려면 외부에서 참조해줘야한다. Target이 public변수처럼 그 역할을 할것이다.

컴파일 저장하고 레벨에디터로 돌아가자.

BP_Target을 선택하고 디테일 메뉴에서 Target의 디폴트값을 BP_Cone으로 설정하자.

이제부터 BP_Target의 Target변수는 BP_Cone을 참조를 가리키게 되고 BP_Cone을 설정할 수 있다. 블루프린트를 잘보면  2번째 Set SimulatePhysics의 Target은 BP_Cone을 참조하고 있어 BP_Cone의  속성이 바끼게 된다. 플레이해보면 BP_Cone은 수직으로 떠오른다. BP_Target고 부딪치면 BP_Target의 Z impulse를 1000정도로 낮추면 충돌을 피할 수 있다.