반응형

스크립트컨트롤러가 필요한 이유

게임계에 일하는 애니메이터라면 매일 봐야 하는 바이패드..
본으로 셋팅해야 하는 불편을 없애줘
인간형 애니를 잡을때는 정말 훌륭한 툴이지만 인간의 형태를 벗어날수록
한계점이 많은 녀석입니다..


 

 

예를 들면 켄타로우스 처럼 발은 사족이고 상체는 인간형 같은..

 

 

그런 한계점을 없애기 위해서는 바이패드를 여러개 사용하여 다양한 셋팅을 할수 있습니다.
하지만, 바이패드끼리 링크를 걸면 여러가지 버그가 많이 생깁니다.
링크걸린 바이패드가 위치값을 잘못계산하여 다른 위치로 튀는 현상이 매우 빈번히 발생합니다.
또한 링크된 두번째 바이패드에는 IK(Inverse Kinematic)애니를 줄수 없어 모션 작업이 어렵습니다.
(애니메이션 작업을 해보면 알수 있는..)

그 외에도 엄청나게 많은 문제들이 생깁니다.
바이패드 특성상 맥스와 좀 따로 노는 느낌이라 그런지 맥스에서 사용하는 기능들과 상충할때가 많습니다.

이러한 문제를 스크립트 컨트롤러를 활용하여 멀티 바이패드의 여러 문제를 해결할 수 있습니다.

 

스크립트 컨트롤러 셋팅한 바이패드



영상 

 

 

- 바이패드를 세개 이용하여 제작된 셋팅입니다. 뒷다리쪽이 bip01 , 몸통이 bip02, 추가팔이 bip03입니다.

서로 다른 바이패드끼리 한개의 바이패드처럼 작동이 됩니다.

 

위 그림에 셋팅된 스크립트 컨트롤러 정리

if bip01 != undefined and bip02 != undefined then
(
 if bip01.controller.figureMode then
 (
  bip02.controller.figureMode = true
  bip03.controller.figureMode = true
  
  biped.setTransform bip02 #pos dm.transform.pos false
  biped.setTransform bip02 #rotation dm.transform.rotation false
  biped.setTransform bip02 #scale dm.transform.scale false
  
  biped.setTransform bip03 #pos (biped.getTransform bip02 #pos) false
  biped.setTransform bip03 #rotation (biped.getTransform bip02 #rotation) false
  biped.setTransform bip03 #scale (biped.getTransform bip02 #scale) false
  
  biped.setTransform bip03Spine00 #pos (biped.getTransform bip02Spine00 #pos) false
  biped.setTransform bip03Spine00 #rotation (biped.getTransform bip02Spine00 #rotation) false
  biped.setTransform bip03Spine00 #scale (biped.getTransform bip02Spine00 #scale) false
  biped.setTransform bip03Spine01 #rotation (biped.getTransform bip02Spine01 #rotation) false
  biped.setTransform bip03Spine01 #scale (biped.getTransform bip02Spine01 #scale) false
  biped.setTransform bip03Spine02 #rotation (biped.getTransform bip02Spine02 #rotation) false
  biped.setTransform bip03Spine02 #scale (biped.getTransform bip02Spine02 #scale) false
  
 
 )
 else
 (
  bip02.controller.figureMode = false
  bip03.controller.figureMode = false
 )

 bip02.transform = dm.transform
 bip03.transform = bip02.transform
 bip03Spine00.transform = bip02Spine00.transform
 bip03Spine01.transform = bip02Spine01.transform
 bip03Spine02.transform = bip02Spine02.transform 
)

 

 

스크립트 콘트롤러 제어를 통해 배운점

1. 손으로만 가능할거라 생각했던 바이패드 셋팅을 스크립트를 활용한 특수 셋팅을 알게됐습니다.

2. 중간더미를 적절히 사용하지 않으면 여전히 오류가 발생할수 있습니다. 이것은 손으로 셋팅할때도 마찬가지였습니다.

 

반응형
반응형

이번에 만든 툴은 SpaceWarpToMorph(스페이스워프 투 모프)

라는 툴로서

맥스의 스페이스 워프 툴을 활용하여 물결치는 메시를 제작했지만, 엔진(유니티,언리얼)에는 들어가지지가 않습니다.

유니티나 언리얼에도 이런 애니를 넣도록 해주는 기능도 없습니다.

그럴때 맥스에서 제작된 스페이스 워프 애니를 모핑 애니데이터로 변경하여 버텍스애니를 적용하면

엔진에 불러올수 있습니다.

하지만, 이것을 수동으로 애니를 넣으려면 매프레임마다 오브젝트를 복사하여 키를 찍어주는 엄청난 노가다

작업을 해야하는데, 이 툴을 활용하면 버튼한방에 마무리됩니다.

 

 

 

문제의 발생과 피드백 상황

1. try( )catch( ) 명령어를 잘못사용하여 문제 발생
-catch 옆에 ( ) 안쳐서 버그 발생

2. 오브젝트에 모핑 모디파이를 추가하기 위해서는 반드시 오브젝트가 선택되어 있어야 하고
 모디파이 모드임을 알려줘야 하는데 빼먹었음.
max modify mode
select morpherObj

3. 모핑의 오브젝트를 등록하고도 Autoload 를 활성화 시키지 않으면 갱신이 안되는데 빼먹음

morpherObj.modifiers[#Morpher].Autoload_of_targets = 1

1값이면 true 0값이면 false

Default가 false라 발생한 문제

4. for문에서는 ( ) 를 한줄정도 생략이 가능한데, 어느 부분에서 쓰고 빼는지에 대해서 어려움을 느낌.

5. 버그가 엄청 발생했는데, print문을 활용하는 능력이 떨어져 버그 잡는데 많은 시간이 소요됨

 

 

본 공부를 통해 깨닫고 배운 내용

1. 함수 선언의 개념에 대해서 학습 - fn 을 통해 함수를 정의할 수 있고, 함수를 파일로 저장하여
include 명령어로 활용할수 있다.

2. for문과 if문에 대한 반복학습을 통해 개념 파악
- for문으로 곱하기 조차 어려워하던 수준인데.. 이제야 그 수준을 살짝 탈피해 가는거 같습니다..ㅠ

3. 레퍼런스 찾기 연습을 통해 버그나 코딩이 막힐때 해결방법에 대해 숙지
- 여전히 더 많은 훈련이 필요함.

4. 배열의 사용법과 append의 사용법 숙지

5. animationRange 활용법 숙지

6. print 문을 활용하여 버그 잡기

 


스크립트 코드



global g_MeshToMorph


try(destroydialog g_MeshToMorph)catch()


rollout g_MeshToMorph "버텍스애니를 모핑으로"
(
 --로컬로 픽 오브젝트 변수 선언--------------------------------------------------------- 
 local setMainObj
 ----------------------------------------------------------------------------------- 
 
 -- FilterMesh ---------------------------------------------------------------------------
 fn FilterMesh obj =
 (
  if iskindof obj PolyMeshObject or iskindof obj Editable_Mesh then
   return true
  else
   return false
 )

 -----------------------------------------------------------------------------------
 --레이아웃
 -----------------------------------------------------------------------------------
 pickbutton pkn_MeshButton "오브젝트 선택" witdh:180 Filter:FilterMesh
 spinner spn_StartFrame "시작프레임: " range: [-9999,9999,0] type:#integer
 spinner spn_EndFrame "끝프레임: " range: [-9999,9999,10] type:#integer
 button btn_make_morph "모핑시작"
 hyperLink hlnk_Frame "100f" color:(color 28 28 177) align:#left offset:[65,1]
 -----------------------------------------------------------------------------------
 
 -----------------------------------------------------------------------------------
 --한계치 넘어가면 색깔 변하게__
 -----------------------------------------------------------------------------------
 fn SetFrameHlink =
 (
  -- String --
  intervalFrame = spn_EndFrame.value - spn_StartFrame.value + 1
  hlnk_Frame.text = "" -- 한번 지워줘야 잔상이 생기지 않음
  hlnk_Frame.text = (intervalFrame as string) + "f"
  
  -- Color --
  if intervalFrame > 0 and intervalFrame < 101 then
   hlnk_Frame.color = color 28 28 177
  else
   hlnk_Frame.color = color 141 7 58
 )
 
 -----------------------------------------------------------------------------------
 --모핑버튼 활성화 조건--
 -----------------------------------------------------------------------------------
 fn IsValidMorpher =
 (
  startFrame = spn_startFrame.value
  endFrame = spn_endFrame.value
  
  if  startframe - endframe < 0 and abs(startFrame - EndFrame) <100 then
  (
   if SetMainObj != undefined then
    btn_make_morph.enabled =  true
   else
    btn_make_morph.enabled =  false
  )
  else
  (
   btn_make_morph.enabled =  false
  )
  
 )
 
 -----------------------------------------------------------------------------------
 --픽 버튼 누를때 
 -----------------------------------------------------------------------------------
 on pkn_MeshButton picked obj do
 (
  pkn_MeshButton.text = obj.name
  SetMainObj = obj
  
  IsValidMorpher()
  
 )
 -----------------------------------------------------------------------------------
 --시작프레임 수치는 아래 함수를 따른다
 -----------------------------------------------------------------------------------
 on spn_StartFrame changed val do
 (
  IsValidMorpher()
  SetFrameHlink()
  
 )
 -----------------------------------------------------------------------------------
 --끝프레임 수치는 아래 함수를 따른다 
 -----------------------------------------------------------------------------------
 on spn_EndFrame changed val do
 (
  IsValidMorpher()
  SetFrameHlink()
 )
 -----------------------------------------------------------------------------------
 --가장 중요한 모핑시작 버튼을 누를때의 반응설정--
 -----------------------------------------------------------------------------------
 on btn_make_morph pressed do
 (
  startFrame = spn_startFrame.value
  endFrame = spn_EndFrame.value
  
  --애니메이션 구간설정
  animationRange = interval startFrame endFrame
  
   
  targetObjs = #()  --복사될 오브젝트들을 배열로 변수 선언.  배열 번수는 복수형으로 쓰자
  objCount = 0
  
  --프레임 수 만큼 오브젝트 복사  
  for i = startFrame to endFrame do
  (
   slidertime = i
   objCount += 1
   newObj = snapshot SetMainObj
   append targetObjs newobj
   
   --복사된 오브젝트와 원본 오브젝트를 숨겨야 중간에 디버그하기가 편함
   newobj.ishidden = true
   setMainObj.ishidden = true
  )
  
  --모핑추가할 오브젝트 제어
  morpherObj = copy SetMainObj
  convertto morpherObj Editable_Poly
  addmodifier morpherObj(morpher())
  
  
  --모핑 리스트를 자동으로 갱신하기 위해서 필요한 명령어
  morpherObj.morpher.Autoload_of_targets = 1
 
   
  --모핑 오브젝트에 복사된 오브젝트 프레임순으로 등록
  for i=1 to targetObjs.count do  --모핑되는 인덱스를 반복문으로 설정하여 각 인덱스별로 오브젝트가 설정되도록 하기위한 반복문
  (
   WM3_MC_BuildFromNode morpherObj.morpher i targetObjs[i]  -- 모핑 오브젝트의 인덱스 i  그 인덱스에 들어갈 타겟 오브젝트 역시 i
  )
  
  --아래 두 명령어 없으면 실행 안됨
  max modify mode
  select morpherObj
  
  --적용된 모핑리스트들에 키 값 추가
  morpherCount = 0
  for i = startFrame to endFrame do
  (
   morpherCount += 1
   for k = -1 to 1 do
   addnewkey morpherObj.Morpher[morPherCount].controller.keys(i + k) --for문에 ()한개쯤은 생략할 수 있다.
   
    morpherObj.Morpher[morPherCount].controller.keys[2].value= 100
  )
  
  delete targetObjs
  delete SetMainObj
   
  
 )
    
   
)

createdialog g_MeshToMorph width:200 height:200

반응형
반응형
 바이패드를 박스모드로 변환시켜주는 툴입니다. 이 툴은 애니메이터들에게 필요한 툴로서 바이패드를 박스형태로

변환시켜 모델 원본을 보는데 방해를 받지 않고 애니메이션 작업을 할 수 있도록 하는 툴입니다.

 

1. 툴 화면


 

2. 전체 바이패드 전환


 

3. 선택 바이패드 전환


 

- 이 스크립트 제작을 통해 배운 내용

1. for문의 사용법 숙지(반복문)

2. 주석처리 방식 숙지

3. true와 false 수치를 글로별변수로 선언하여 제어하는 방법 숙지

4. 메크로 버튼을 만들어 나만의 메뉴를 생성하는 방식

 

코드 원문

--==========================================================================================================
--==========================================================================================================

-- 바이패드 박스 전환툴 : 바이패드를 박스모드로 변환해 해주는 Tool입니다.
-- 버그나 관련 내용 문의 요청 언제나 환영

-- 제작 : Taeyo

--==========================================================================================================
--=====================================================================================================


--박스모드와 플로터에 대한 글로벌변수 선언---------
Global BipedToBoxFloater
Global isBoxMode = true


--===========================================================================================================

---롤아웃지정------

--===========================================================================================================
rollout BipChange "바이패드 박스모드로 변환"
(

 --================================================================================== 
 -----버튼 지정----
 --================================================================================== 
 button BtnBipToBox1 "선택바이패드만전환"
 button BtnBipToBox3 "바이패드 박스모드전환"

 
 --================================================================================== 
 -----선택된 바이패드만 전환시킴-----
 --==================================================================================
 on BtnBipToBox1 pressed do
 (
  
  ----------------------------------------------------
  --SelObj선언---
  ----------------------------------------------------
  SelObj = $
  

  ----------------------------------------------------
  --선택된거 없을때---
  ----------------------------------------------------
  if selection.count == 0 then
   (
    messagebox "선택된게 없습니다."
    return 0
   )
  
  ----------------------------------------------------
  --for문을 통해 선택된 오브젝트가 무엇인지 판별----
  ----------------------------------------------------
    for SelObj in $selection do
   ( 
  
   if iskindof SelObj Biped_Object then
   (
    SelObj.boxmode = isBoxMode
   )
   else
   (
    SelObj.boxmode = isBoxMode
    messagebox "바이패드가 아닙니다."
    return 0
   )
  
   
  )
  
  ---------------------------------------------------------------------
  --isBoxMode로 선언된  글로벌변수를 통해 on/off를 지정할수 있는 함수--------------------------
  ---------------------------------------------------------------------
  if isBoxMode then
  (
   isBoxMode = false
  )
  else
  (
   isBoxMode = true
   return 0
  )
  clearselection()
 )
 
 --==================================================================================
 -------전체 씬을 뒤져서 바이패드만 골라 박스모드로 변환시켜줌------------------------
 --==================================================================================
 on BtnBipToBox3 pressed do
 (
  
  
  ----------------------------------------------------
  --for문을 통해 전체 씬의 오브젝트를 검색함--------------------------
  ----------------------------------------------------
  for obj in objects do
  (
   if iskindof obj Biped_Object then
    obj.boxmode = isBoxMode
  )
  
  ----------------------------------------------------
  --isBoxMode로 선언된  글로벌변수를 통해 on/off를 지정할수 있는 함수--------------------------
  ----------------------------------------------------  
  if isBoxMode then
  (
   isBoxMode = false
  )
   else
  (
   isBoxMode = true
   return 0
  )
   
 )
   
  
)

--===========================================================================================================

------재실행시 기존 창 지우기 위해 트라이 캐치 실행---------------------------------------------

--===========================================================================================================
try(CloseRolloutFloater BipedToBoxFloater) catch()


--===========================================================================================================

---실행창 생성--------------------------------------------

--===========================================================================================================

BipedToBoxFloater = newrolloutfloater "바이패드 박스로 변환툴" 200 130
addrollout BipChange BipedToBoxFloater

반응형
반응형

 

1.메쉬 LOD 변환툴


- LOD를 적용할 메쉬를 선택하여 수치를 정하여 메쉬를 변환시켜주는 툴입니다.

 

1. 툴 화면

 

2. 비대칭 실행시 적용화면 - 원본 오브젝트의 50퍼센트의 LOD를 적용하여 비대칭 메쉬를 새로 생성합니다.


 

 3. 대칭 실행시 적용 화면 - 원본 오브젝트의 50퍼센트의 LOD를 적용하여 대칭 메쉬를 새로 생성합니다.

 

- 이 스크립트 제작을 통해 배운 내용

1. if문의 사용법 숙지(조건문)

2. roll과 button을 사용하여 메뉴 창 생성하는 법

3. 오브젝트의 모디파이의 속성을 제어하는 방법

  

코드 원문

global TEST

rollout noskin "스킨없을때"
 
(
 spinner noskin1 "버텍스수치" range:[0,100,50] type:#integer
 button btn1 "비대칭"
 button btn2 "대칭"
 
 
 on btn1 pressed do
 (
  if selection.count != 1 then
  (
   messagebox "한개만 선택하세요"
   return 0
  )
  
  if $.modifiers[#skin] == undefined then
  
  (
   local VF = noskin1.value
   
   a= $
   copyobj = copy$
   select copyobj
   
   --modPanel.setCurrentObject $.baseObject
   modPanel.addModToSelection (MultiRes ()) ui:on
   $.modifiers[#MultiRes].reqGenerate = on
   $.modifiers[#MultiRes].vertexPercent = VF
   maxOps.CollapseNodeTo $ 1 off
   
   clearselection()
   
   delete a
   
   select copyobj
  )   
  else
  (
   messagebox "스킨없애시오"
   return 0
  )
  
 )
 ----------스킨 없고 대칭 일때-------------------
 on btn2 pressed do
 (
  if selection.count != 1 then
  (
   messagebox "한개만 선택하세요"
   return 0
  )
  
  if $.modifiers[#skin] == undefined then
  
  (
   local VF = noskin1.value
   
   
   a= $
   copyobj = copy$
      
   
   ---헬퍼박스 생성----
   Box lengthsegs:1 widthsegs:1 heightsegs:1 length:5000 width:5000 height:5000  pos:[0,0,0]  name:"Helper_Box"
   select $Helper_Box
   max rotate
   toolMode.coordsys #local
   rotate $(angleaxis -90 [0,1,0])
   move $ [-0.1,0,0]
   macros.run "Modifier Stack" "Convert_to_Poly"
   
  
   select copyobj
   
   modPanel.addModToSelection (Vol__Select ()) ui:on
   $.modifiers[#Vol__Select].level = 1
   $.modifiers[#Vol__Select].volume = 3
   $.modifiers[#Vol__Select].node = $Helper_Box
   modPanel.addModToSelection (Edit_Poly ()) ui:on
   subobjectLevel = 1
   max delete
   maxOps.CollapseNode $ off 
   modPanel.addModToSelection (MultiRes ()) ui:on
   $.modifiers[#MultiRes].reqGenerate = on
   $.modifiers[#MultiRes].vertexPercent = VF
   modPanel.addModToSelection (symmetry ()) ui:on
   $.modifiers[#Symmetry].threshold = 0
   maxOps.CollapseNode $ off
    
   clearselection()
   
   delete a 
   delete $Helper_Box
      
   select copyobj
  )   
  else
  (
   messagebox "스킨없애시오"
   return 0
  )
    
 )

)


----------------스킨있을때-------------------------------------

rollout yeskin "스킨있을때"
 
(
 spinner yeskin1 "버텍스수치" range:[0,100,50] type:#integer
 button btn3 "비대칭"
 button btn4 "대칭"
 
 on btn3 pressed do
 (
  if selection.count != 1 then
  (
   messagebox "한개만 선택하세요"
   return 0
  )
  
  if $.modifiers[#skin] != undefined then
  (
   local VF = yeskin1.value
   
   a= $
   copyobj = copy$
   select copyobj
   
   $.modifiers[#Skin].Enabled = off
   modPanel.setCurrentObject $.baseObject
   modPanel.addModToSelection (MultiRes ()) ui:on
   $.modifiers[#MultiRes].reqGenerate = on
   $.modifiers[#MultiRes].vertexPercent = VF
   maxOps.CollapseNodeTo $ 2 on
   $.modifiers[#Skin].Enabled = on
   
   clearselection()
   
   delete a
   
   select copyobj
  )  
 
  else
  (
   messagebox "스킨을 넣으세요"
  )
 
 )
  
 ------------스킨 있고 대칭 일때---------------------------------------------------------------
 on btn4 pressed do
 (
  if selection.count != 1 then
  (
   messagebox "한개만 선택하세요"
   return 0
  )
  
  if $.modifiers[#skin] != undefined then
  
  (
   local VF = yeskin1.value
   
   
   a= $
   copyobj = copy$
      
   
   ---헬퍼박스 생성----
   Box lengthsegs:1 widthsegs:1 heightsegs:1 length:5000 width:5000 height:5000  pos:[0,0,0]  name:"Helper_Box"
   select $Helper_Box
   max rotate
   toolMode.coordsys #local
   rotate $(angleaxis -90 [0,1,0])
   move $ [-0.1,0,0]
   macros.run "Modifier Stack" "Convert_to_Poly"
   
  
   select copyobj
   
   $.modifiers[#Skin].Enabled = off
   modPanel.setCurrentObject $.baseObject
   modPanel.addModToSelection (Vol__Select ()) ui:on
   $.modifiers[#Vol__Select].level = 1
   $.modifiers[#Vol__Select].volume = 3
   $.modifiers[#Vol__Select].node = $Helper_Box
   modPanel.addModToSelection (Edit_Poly ()) ui:on
   subobjectLevel = 1
   max delete
   maxOps.CollapseNodeTo $ 2 off
   modPanel.setCurrentObject $.baseObject
   modPanel.addModToSelection (MultiRes ()) ui:on
   $.modifiers[#MultiRes].reqGenerate = on
   $.modifiers[#MultiRes].vertexPercent = VF
   modPanel.addModToSelection (symmetry ()) ui:on
   $.modifiers[#Symmetry].threshold = 0
   maxOps.CollapseNodeTo $ 2 on
   $.modifiers[#Skin].Enabled = on
    
   clearselection()
   
   delete a 
   delete $Helper_Box
      
   select copyobj
  )   
  else
  (
   messagebox "스킨을 달라"
   return 0
  )
 )
  
)


TEST = newrolloutfloater "공부용 LOD시스템" 200 200

addrollout noskin TEST
addrollout yeskin TEST

 

반응형
반응형

언리얼 튜토리얼에 올라온 비헤이비어 트리 쿽스타트 가이드를 토대로

평소에는 천천히 돌아 다니다가 주인공을 만나면 속도를 내서 달려올수 있도록 함수를 추가해 봤습니다.

https://docs.unrealengine.com/latest/KOR/Engine/AI/BehaviorTrees/QuickStart/index.html

 

 

블루프린트 함수 추가 내용

1. AI 캐릭터 추가 내용 - 일반 속도를 60으로 규정하는 함수 추가. speed rate 값을 캐싱하여 속도 조절 가능

 

2. 일반이동 BTT 추가내용

-문서에서는 기본으로 제공하는 노드로 구성되어 있는데, 그 부분을 제거하고 아래 내용을 추가해주면 됩니다.

원본 - https://docs.unrealengine.com/latest/KOR/Engine/AI/BehaviorTrees/QuickStart/12/index.html

 

 

3.  주인공을 만났을때의 BTT 추가내용

원본 - https://docs.unrealengine.com/latest/KOR/Engine/AI/BehaviorTrees/QuickStart/10/index.html

원본BTT에 아래 내용만 추가하면 됩니다.

 

 

4. 원본에서 비헤이비어 트리 구조 변경

원본에는 기본 트리를 사용하기 때문에 여러가지 조건문이 붙지만, 함수안에 이동 조건을 걸어놨기 때문에

필요없는 부분들이 생겼습니다.

원본 구조 - https://docs.unrealengine.com/latest/KOR/Engine/AI/BehaviorTrees/QuickStart/12/index.html

변경 구조


 

 

완료영상

 

 

반응형
반응형

스켈레탈 메시를 처음 생성하면 피직스 에셋이 자동 생성됩니다.

자동 생성이 안됐어도 스켈레탈 메시를 누르고 피직스 추가를 하면 피직스를 새로 만들수 있습니다.

 

자동 생성된 피직스는 모양과 크기가 제대로 설정되어 있지 않아 시뮬레이션 결과가 엉망으로 나옵니다.

처음 생성했을때의 피직스 모양 - 모양과 크기가 엉망입니다..

피직스 셋팅이 안된 상태의 시뮬레이션 영상 -  아 흉해라.. 

 

이 상태로 게임에 쓸수 없기에 각 관절마다 피직스 셋팅을 해줘야 합니다.

 

설정가이드

1. 각 관절이 전부 Sphyl 형태로 되어 있는데, 계산이 많이 필요한 허벅지나 양쪽 팔등만 설정하고 나머지는 Box 형태로

설정해 줍니다.

 

2. 관절형태를 설정후 크기 및 방향등을 재설정해 줍니다.

-각 관절이 겹치게 될경우 물리 계산이 꼬이게 되므로 서로 겹치지 않도록 하고 사이즈가 너무 크지 않고 설정해 줍니다.

 


3. 각 관절별 사이즈 조절이 끝나면 컨스트레인트 각도 설정을 해줘야합니다.

- 관절 사이즈보다 컨스트레인드 각도와 위치가 더 큰영향을 끼치게 되므로 많은 테스트가 필요한 부분입니다.

여기서 각 관절이 얼마만큼 꺽이도록 할것인지 설정하고, 방향은 어느 쪽으로 향하는지 등을 설정할 수 있습니다.

여기서 주의할 점은 컨스트레인트는 한번 삭제하면 복구하기가 굉장히 까다롭기 때문에(거의 다시 만들어야함..)

삭제할때 신중을 기해야 합니다.

 

4. 새로 셋팅된 피직스형태

 

 

위와 같이 셋팅을 마치고 나면 아래처럼 시뮬레이션이 출력됩니다. 아직 완벽하진 않지만, 점점 좋아질것을 기대하며.. 

 

오늘 처음 해본거라 아직 셋팅이 완벽하지 않아 여전히 부족한 부분이 있지만, 앞으로 많은 테스트를 거치다 보면

이쁜 결과물을 충분히 만들어 낼수 있을거라 기대합니다.

앞으로 배포될 APK에 일단 주인공만 포함될 예정이며 좀더 연구해 본후 몬스터에도 적용시킬지 검토중입니다.

 

반응형
반응형

 

 

 

 

 

 

 

언리얼 파츠 작업시 유의사항

- 스켈레탈 메시인경우 맥스에서 여러개의 모델로 디테치가 되어 있어도 언리얼로 임포트를 하면 메시가 전부 컴바인되어 임포트 됩니다.(스태틱 메시는 나뉘어서 부르는게 가능)

따라서 파츠를 나눌 부분은 맥스에서 익스포트시 따로 선택하여 익스포트 한후 언리얼로 임포트 해 올때 원본 모델의 스켈레톤과 피직스를 공유 받으면 파츠별로 붙혔다 뗐다가 가능해 집니다.

- 그리고 모델링 주실때 링크 구조로 주셨는데, 모델링은 링크 구조 없이 주셔야 문제가 없습니다.

스켈레탈 메시를 링크구조로 익스포트 하면 제일 상위 메시만 익스포트 되고 나머지는 익스포트 되지 않습니다.

 

 

파츠 분리 익스포트 방식

1. 메인 바디가 될 부분을 먼저 익스포트 한다.

 

 

2. 파츠로 나뉘어질 모델과 메인 바디와 똑같은 본을 선택후 각각 익스포트 한다.

 


 

3. 메인 바디를 언리얼로 임포트 한다.

-원본 모델이므로 스켈레톤과 피직스를 새로 생성한다.

 

-임포트후 생기는 파일들 : 메시, 스켈레탈, 피직스, 메터리얼

 

 

4. 그리고 파츠모델들을 각각 임포트해 온다.

-임포트시 기존에 생성된 메인 바디와 스켈레탈과 피직스를 상속받도록 설정한후 임포트한다.

 

5. 그렇게 불러진 파츠 모델들은 아래 그림처럼 몸에 붙혔다 뗐다 하는것이 가능해집니다.


 

 

반응형
반응형

스켈레톤을 교체하게 된 원인 - 문제가 발생했던건 prop1의 위치였습니다,

발사 모션을 할때 Spine 본 아래로만 모션이 들어가도록 설정했는데,

prop1 본이 스파인본 보다 상위에 있어 발사 모션을 할때 총이 따라오지 않는 문제가 발생했습니다.

 

원본데이터를 바꿔버리면 쉽지만, 내부망에 이미 등록되어 있는 주인공 데이터의 원본 모델링 소스를 바꿔버리면

여기저기 미싱이 나기 때문에 스켈레톤만 교체하는 방법에 대해 공유합니다.

 

 

1. 맥스에서 다시 본위치를 설정후 메쉬와 애니메이션을 전부 다시 뽑습니다.


 

 

2. 그 후 뽑힌 모델링 파일의 이름을 원본이름과 다르게 설정해서 임포트 해 줍니다.

- 여기서 중요한 것은 애니 이름은 그대로 뽑고 원본 모델 소스 이름만 다르게 해줍니다.


 

3. 새로 뽑은 모델링 FBX 데이터(pawn_women2)를 언리얼에 임포트해 오면 세가지 파일이 생깁니다.

- 여기서 스켈레톤외의 파일들은 전부 제거해 줍니다. 필요없기 때문에...

 

 

4. 기존 원본 모델링 FBX 데이터(pawn_women)의 스켈레톤을 새로 뽑아서 생성된 스켈레톤 데이터로

다시 할당해 줍니다.


 

5. 새로 할당후 반드시 리임포트를 해줘야 정상적으로 변환됩니다.

- 리임포트를 해야 정상적으로 나온다는것을 뒤늦게 알게 되어 엄청 헤맸네요..ㅠㅠ

**여기서 중요한 사항은 기존에 임포트했던 원본 FBX 파일이 기억되어 있으면 새소스를 불러올수 없으니

기존 원본 fbx는 반드시 삭제해 줍니다.


 

6. 모델링 임포트가 끝나면 적용된 애니메이션들도 전부 리임포트 해줘야 정상적으로 모션이

출력됩니다.

- 리임포트를 해주지 않으면 모션이 전부 미싱나거나 깨져서 나오게 됩니다.

 

 

위 작업은 외부망에서 테스트 할때는 문제되는 내용이 아니지만, 내부망에서 프로그래머들과 협업시

원본 모델링 소스가 바뀔 경우 많은 데이터에 오류가 발생하므로 원본 모델링 데이터를 바꾸지 않고

스켈레톤을 바꾸기 위한 방법이었습니다.

쉽게 바꿀수 있을거라 생각하고 접근했다가 반나절을 날려 보냈네요..ㅠ

잊어버릴까봐 메모해 둡니다~

 

반응형
반응형

트리거를 이용하여 특정위치나 캐릭터로 이동했을때 마티네가 발동하도록 손쉽게 구현할 수 있습니다.

또한 마티네가 시작됨과 동시에 주인공 캐릭터를 가리고 마티네가 끝나면 NPC가 사라지도록 하는등 트리거 박스와

레벨 블루프린트를 활용하여 손쉽게 제어가 가능합니다.

 

1. 트리거를 생성하여 발동 위치 정하기



 어디쯤에서 연출이 발동할지 박스 트리거의 크기와 위치로 지정한다.

 

 

2. 레벨 블루프린트를 통해 트리거에 주인공이 닿았을때 마티네 발동하도록 설정하기


OnActorBeginOverlap 명령어를 통해 트리거를 통해 마티네 실행을 제어할 수 있다.

 

 

3. 각 상황마다 NPC 나 주인공을 어떻게 처리할 것인지도 레벨블루프린트에서 정해주면 화면상에 나오는 캐릭터들을 정하고 배치할 수 있습니다.

 

 

위와 같은 설정을 하면 아래와 같이 캐릭터가 특정위치로 갔을때 연출이 발동하도록 할 수 있습니다.

아래 연출 화면은 삼품 7막영상의 마초대 허저의 영상을 언리얼로 간단히 이식한 영상입니다.

연출팀 마티네 교육을 위해 제가 만들었는데, 아직 후처리 전이라 퀄리티가 그렇게 높지는 않은 상황입니다.

 

 

 

 

 

게임 발동후 마초가 허저에게 다가가면 연출이 발동하고 연출이 끝나면 NPC가 사라지도록 설정했습니다.

반응형
반응형

Apex Cloth를 이용하기 위해서는 먼저 ndivia홈페이로 가셔서 개발자 계정으로 회원가입을 한 후

플러그인을 받아야 합니다.

https://developer.nvidia.com/apex-clothing-3dsmax-tutorials

NVIDIA_PhysX_For_Autodesk_3ds_Max_2014_64bit_3.02.01024.04200.msi(자료방에 공유)

라는 파일을 다운받고 설치하면 맥스에 PhysX라는 플러그인이 설치됩니다.


 

-간단한 사용법 튜토리얼

물리를 적용할 캐릭터에  Skin 작업 완료후 Apex를 적용해 줍니다.


 

그리고 Max Distance로 설정하여 Brush Value값을 지정한뒤 시뮬이 적용될 Poly를 칠해줍니다.

 

 

페인트 작업이 끝나면 천이 충돌하는 위치의 Bone들에게 충돌처리를 해줍니다.

Create Kinematic Rig를 실행후 Bone들을 ADD해 줍니다.


 

위 작업을 해주면 지정한 본들의 캡슐이 생성되며 각 캡슐마다 충돌영역을 수정하여 크기를 지정해 줍니다.


 

이제 맥스작업이 마무리되면 언리얼로 넘기기 위해 Export를 해줘야 합니다.

구 버전에는 없지만, 최신버전에는 export를 할 수있는 메뉴가 친절히 내재되어 있습니다.

 

익스포트 완료후 캐릭터FBX파일을 언리얼로 임포트후 생성된 Apx 파일을 추가해 주면 언리얼에서

시뮬을 하기 위한 모든 셋팅이 완료됩니다.

 

 

 

천시뮬이 제대로 들어갔는지 확인하기 위해 페르소나툴의 메시 카테고리에서 바람을 적용해 보면 시뮬레이터 적용을 확인해 볼수 있습니다.

 

 


 

 

 

모든 셋팅이 끝난후 애니메이션을 적용해 보면 천시뮬레이션이 멋지게 적용된 것을 확인하실 수 있습니다.

 

 

테스트하면서 발생했던 에로사항들..

1. 신버전에 대한 제대로된 튜토리얼이 존재하지 않아 혼자서 삽질하며 알아냈습니다. 까페에 글올려도 대답이 없어

혼자서 자문자답했다는..

2. 언리얼상에 임포트가 되지 않아 문제 원인을 찾던중.. 이거 역시 아무리 뒤져도 나오지 않아 혹시나 해서 폴더를

영문으로 바꿨더니 잘 되네요..ㅠ

3. 맥스 작업시 가끔씩 트랜스폼 기즈모가 사라집니다. 자세히 보니 사라지는게 아니고 엄청 작아져서 다시 키워줘야

합니다.

4. 페인트 브러시 크기가 줄어들지 않아 찾느라 엄청 헤맸네요.. 구글 어디에도 답이 없다가 혼자서 이거저거 뒤지다

겨우 알아냈습니다.

 

반응형
반응형

fbx2011로 제작된 데이터를 임포트해왔을 경우

페르소나만 열면 엔진이 꺼져버려 에디팅이 불가한 상태입니다.

아직 마티니에서 시퀀스간 블렌딩하는 방식을 찾아내지못해 페르소나에서 여러가지 해보려 했는데,

새로운 프로젝트를 만들어 언리얼 규약에 맞춰 fbx2014버전으로 다시 뽑아 제작해 봐야할거 같습니다.

 

반응형
반응형

유니티로 구매한 캐릭터들을 언리얼로 이식하는데 성공했습니다.

이식하면서 여러 문제가 발생했는데, 그 문제들을 필두로 리타겟 매니저를 활용하여 다양한 몬스터들의 모션을 한 가지 스켈레톤으로 공유 할 수 있는 방법을 알게 되었습니다. 그 부분에 대해서 자세히 기술하도록 하겠습니다.

리타겟 매니저의 가장 큰 장점은 본의 스케일이 달라도 애니메이션을 공유할수 있다는 점입니다.

 

- 원래 본 스케일이 다를때 모션을 공유하면 아래같이 스킨이 깨지고 늘어나는 현상이 일어납니다.

 

- 하지만, 리타겟 매니저를 사용하면 아래 그림처럼 다른 캐릭터의 스케일과 본 사이즈에 맞춰 자동 조절하여 정상적으로 출력됩니다.(맥스의 바이패드와 같은 기능)

이 부분은 아래 3번에서 자세히 다루도록 하고 순서대로 이슈 정리하겠습니다.

 

 

1. 유니티 구매 캐릭터를 언리얼로 옮기면서 생긴 첫 번째 문제.

- 본 축이 다르다! 리타겟 매니저를 활용해도 축이 다른 문제는 해결이 안됩니다.

그래서 이 부분은 맥스에서 수동으로 축을 재설정하는 작업을 진행했습니다. 실제로 이 작업이 가장 많은 시간이 걸렸

습니다. 자동화로 하려 했으나 스크립트 만드는데만 하루가 더 소요될거 같아 그냥 수동으로 잡았습니다..;;

현재는 스크립트 제작이 완료된 상태입니다.

 

이 작업의 공정

(1) 원본 메시의 스킨값을 저장하고 스킨을 없앤다. 혹은 에디터블 폴리로 통합한다.

(2) 그리고 언리얼과 축이 다른 본들을 언리얼 축과 맞춰 Affect Pivot Only로 축을 조절한다.

(3) 본들의 축을 수정후에 다시 스킨을 주고, 저장했던 스킨값들을 불러온다.

 

- 어셋 스토어 캐릭터들의 팔 축 (X축이 앞뒤, Y축이 좌우)
 

- 언리얼 캐릭터들의 팔 축 (X축이 좌우, Y축이 앞뒤)

 

 

2.  최초로 제작된 유니티 구매 캐릭터들을 언리얼로 불러오면서 기존 제작된 애니메이션을 리타겟하여 맞춘다.

- 스켈레톤을 공유하지 않고 새로 생성된 스켈레톤에 맞춰 애니메이션을 복사해서 새로 붙러온다.

 
(1) 복사할 모션을 전체 선택후 애님애셋리타겟


 

(2) 호환스켈레톤 표시를 체크 해제후 새로 불러온 스켈레톤에 맞춰 애니를 복사해서 넣어줍니다.

이 과정을 마치면 최초 생성된 유니티 캐릭터에게 새로운 애니메이션이 정상적으로 입혀집니다.

 

 

3. 복사된 애니메이션을 리타겟 매니저를 사용하여 다양한 체형의 유니티 캐릭터에게 공통 적용한다.

(1) Show retargeting Options를 체크한다. - 체크해야 리타겟 매니저를 쓸수 있는 옵션이 활성화 된다.

 

 

(2) root를 '스켈레톤의 트랜슬레이션 리타게팅 재귀적설정'으로 변환한다.

-root 아래 본들의 트랜지션을 각 본마다 공유하도록 하는 기능이다.


 

 

(3) 펠비스를 '스케일 적용 애니메이션의 트랜슬레이션 리타게팅 재귀적 설정'으로 변환한다.

- 펠비스 아래 본들이 스케일에 따라 애니메이션이 자동 보정되도록하는 기능이다.

 

 

(4) 창 -> 리타겟 매니저 로 들어와서 스켈레톤을 공유할 모델과 Humanoid에 공유할 본을 지정해 준다.

- 언리얼에서 지정한 본 위치에 불러온 본을 적용해 주는 기능이다.

 

이 과정을 마치고 각 모델들을 불러올때 최초 생성된 스켈레톤을 공유하도록 설정해서 임포트하면 아래 처럼 각 모델들이 서로 다른 체형임에도 같은 애니메이션을 문제없이 공유할 수 있게 된다.

 

 

 

 

앞으로는 다양한 체형의 좀비를 제작해서 다양한 모션을 함께 공유해서 사용하는것이 간편해 질거 같습니다.

 

반응형
반응형

일시 : 2015년 12월 9일

장소 : 판교 메리어트 호텔

 

스팅레이의 발표회에 다녀와서 가장 인상 깊었던 것을 두 가지로 요약하자면..

1. 3DMAX와의 편한 연동 - 맥스와의 카메라 연동등.. 다양한 플래폼에서 연동가능~

영상참조 

2. 언리얼과 많이 흡사하다. 언리얼을 공부한 사람들은 어렵지 않게 엔진에 접근할 수 있을듯~

레이어 구성, 비헤이비어트리, 노드기반 스크립트(블루프린트)등..

 

 

 

세미나 내용 정리

두둥~ 

이사님의 인사말로 시작~! 

오토데스크에서 만든 디자인툴과의 호환성이 아마도 가장 큰 장점이겠죠~ 

이렇게 세가지 버전이 있다고 합니다. 유니티와 언리얼이 무료화가 됐는데 비싸면 안되겠죠^^ 

 

 

세션 1 - Warhammer - End Times : Verminitide 제작 노하우 사례 발표

Fatshark 라는 스웨덴 회사의 대표이신 Rikard Blomberg 님이 스팅레이로 개발한 Warhhamer - End Times의 제작 노하우 발표 시간입니다. 

이쯤에서 어떤게임인지 영상하나 보고 가시죠~ 1인칭 어드벤처 게임입니다. 

 

 

왜 스팅레이를 선택했는가? 친절하게 번역까지 해드림~

- 리스크를 최소화하기 위해(오토데스크와의 확장성)

- 재작업 축소

- 플랫폼의 확장성

- 비용 축소

- 개발 시간 축소

- 그러면서 창의성에 영향을 주지 않고 싶었음..

 

그리고 멋진 게임을 만들기 위해 돈과 시간을 모두 쏟아 부었다 합니다~!

 

PC, XBOX, PS4 플랫폼으로 개발~ (부럽..;;) 

 

스팀에 출시하여 매출 1위~ 높은 평점~ 다양한 수상등 화려한 이력을 자랑하십니다~

 

개발팀 사진입니다~ 기분탓인지 왠지 떳떳해 보이네요~

 

Art팀에서 사용중인 툴 소개~ 한국과 큰 차이 없습니다~

 

Lua를 메인 스크립트로 사용하는 점이 매우 특이합니다..

 

스팅레이가 제공하는 컴포넌트들인데 뭐 이건 언리얼이나 유니티나 도찐개찐

 

렌더링 파이프라인으 최근 트렌드를 충실히 따라가고 있네요~

 

하지만, Lua를 쓰는게 어떻게 작용하게 될지 미지수입니다. 플머들 사이에선 한물간 용어로 인식되던데..

하지만, 게임코드와 엔진코드를 따로 관리하기때문에 유지보수가 매우 편하다는 부분을 계속 강조했습니다.. 하지만 써봐야 알듯..

 

애니메이션과 피직스의 강력함을 강조했습니다~ 이것도 써봐야 알듯..

 

리소스 핸들링이 편한 부분 강조~

 

스팅레이의 화면 구성입니다. 

 플레이 화면입니다. 플레이시 캐릭터의 복식이나 행동양식을 편하게 에디팅할 수 있습니다.

영상 보시죠~ 

 

 

 

 

언리얼의 Behaviour와 비슷하면서 많이 다릅니다.

 

네브메쉬, 스마트 오브젝트, 비헤이비어 트리등을 활용하여 아래와 같은 연출이 가능합니다~ 영상참조

 

 

 

 

 

편리한 물리 적용~ 영상참조 

 

 

 

세션 2 - Stringray Game Engine / Art & Technology

다음 세션입니다~ 박종태 차장님께서 좀더 다각적으로 설명해 주셨습니다.

이번 세션에는 스케일폼 적용과 루아 스크립트에 관련된 내용이 많았습니다.

이러이러한 장점들이 있습니다~ 첫 세션 내용과 동일

오토데스크의 아트툴과 엔비디아의 피직스를 지원합니다~

런쳐 화면도 언리얼과 굉장히 흡사합니다.

레벨과 어셋브라우저도 언리얼 판박이

스케일폼 적용하는것을 시연해 주십니다.

영상 시연 

 

 

맥스와의 편한 연계성 - 라이브 카메라 적용 영상

 

 

세션 3 - Stingray 유저 사용후기 발표

스피커 - 이승훈 교수님(영산대학교)

 

 

 

 

 

 

 

반응형
반응형

캐릭터가 굴곡진 곳이나 불균형적인 곳을 다닐때 발이 땅을 뚫고 들어가는 것을 방지하도록 하는 기능입니다.

비대칭 지역을 다리가 알아서 인식하여 짝다리를 해주는 기능..ㅎㅎ

간단한 용어 설명

- IK(Inverse Kinematics)란?

일반적인 애니메이션은 아래 그림처럼 정방향 운동을 합니다. 하위 본에 로테이션을 주며 한개의 본만 영향을 끼치도록

애니를 줄수 있습니다.  

하지만 발끝등에 IK 체인을 걸어 IK 셋팅을 해주면 체인을 이용한 포지션 애니를 줌으로써 함께 IK셋팅이 되어 있는 모든

본이 동시에 애니가 적용되게 되며 발끝을 기점으로 애니메이션이 알아서 계산됩니다.

 

 

이 기능을 넣기 위해서는 캐릭터 블루 프린트와 애니메이션 블루 프린트 두 곳에 셋팅을 해줘야 합니다.

먼저 스켈레톤을 열어 바닥을 인식하게 할 위치에 소켓을 박아 줍니다.

 

 

지정한 소켓밑으로 오브젝트가 있는지 검사하여 충돌을 체크해주는 기능을 블루프린트를 통해 코딩해줍니다.
(문서 참조 - https://docs.unrealengine.com/latest/KOR/Engine/Animation/IKSetups/index.html)

IK Foot Trace라는 커스텀 함수를 제작하여 발 밑에 오브젝트가 있는지 검사합니다.

 

  

이렇게 제작된 캐릭터 블루프린트의 함수를 애니메이션 블루프린트에 형 변환후 변수로 호출하여 셋팅해 줍니다.

 

마지막으로 애님 그래프를 통해 오브젝트가 발생시에는 트레이스를 계산하여 발밑 연산을 해주고 평평한 평지에서는 원래 애니로 돌아오도록 설정해 줍니다.

 

위 셋팅이 끝나면 아래 그림처럼 발밑에 오브젝트를 계산하여 알아서 발위치를 잡아주게 됩니다.

 

반응형
반응형

언리얼4에는 블렌딩 스페이스, 몽타주, 에임오프셋 이 세가지의 강력한 모션 믹싱 기능이 내장되어 있습니다.

이 세가지만 잘 숙지하고 사용이 가능해 진다면 디자이너가 직접 캐릭터 움직임을 설정할 수도 있을거 같습니다.

하지만, 아직까지 버그가 좀 있고 프로그램의 기본적인 로직을 알아야 구성 가능하므로 협업이 반드시 필요할 거

같습니다. 저도 프로그래머의 도움으로 한 단계 한 단계 알아가고 있습니다..;; 혼자서는 불가능..ㅠ

 

 

1. 블렌딩 스페이스


- 각 모션별로 알아서 블렌딩 해줘서 방향과 위치별로 모션을 지정하고 수치값을 넣어주면
자동으로 블렌딩해주는 시스템입니다.
앞뒤 좌우 움직임 총 4종의 모션만 있으면 전진, 후진, 45도 우로 전진, 45도 좌로 전진, 45도 백좌로 후진, 45도 백우로 후진, 우측전진, 좌측 전진 총 8종의 모션을 알아서 블렌딩 해줍니다. 아래 동영상 참조.


이렇게 제작해준 블렌드 스페이스 파일을 애니메이션 블루 프린트에서 불러와 애니 스테이트 머신에 연결해 준후
방향과 속도값에 대한 변수 설정후 이벤트 그래프에서 설정하면 사용할 수 있습니다.
움직임을 줄 캐릭터에게는 입력값에 대한 움직임에 대해 블루프린트나 c++에서 코딩후 사용할 수 있습니다.

 

2. 몽타주


- 본을 슬롯으로 지정해 이름을 정한 후 다양한 모션에서 원하는 본의 애니만 넣어줄 수 있다.
가령 예를 들어 무기를 장전하는 애니에서 상체에만 애니를 주고 뽑은후 몽타주로 지정을 해주면
다리는 뛰거나 앉거나 하면서 상체는 장전하는 애니가 나올수 있다.
여기서 몽타주로 지정한 슬롯 이름이 'UpperBody'일 경우 몽타주내에서 지정한 슬롯 이름이 'UpperBody'로
설정한 몽타주들은 다 공통으로 사용할 수 있다.


아래 동영상은 뛰기 모션에서 총을 장전하는 모션과 칼질하는 모션을 몽타주를 이용하여 믹싱한 영상이다.
몽타주 파일 역시 캐릭터 블루 프린트와 애니메이션 블루 프린트에서 간단한 설정후에 사용할 수 있다.

 

 

 

 

3. 애임 오프셋

- Aim Offset, 에임 오프셋은 캐릭터의 무기 조준시 도움이 되는 블렌딩가능 포즈 시리즈가 저장된 애셋입니다.

 

애니메이션 도중, 에임 오프셋 결과를 달리기, 걷기, 점프 등과 같은 다른 모션과 블렌딩하여 캐릭터가 어느 방향을 보더라도 부드럽게 보이도록 만드는 것입니다.

에임 오프셋 배후의 핵심 개념은, 기존 애니메이션 위에 애디티브(더하기식) 블렌딩할 수 있도록 디자인된 것입니다.

예를 들어 에임 오프셋을 사용해서 캐릭터가 무기 조준을 하고자 한다면, 그 애디티브 모션이 캐릭터의 다른 모션에

방해받지 않도록 할 수 있습니다.(블렌드스페이스보다 강력하게)

다른 말로 하자면, 달리기, 빈둥거리기, 점프 등의 동작을 할 때 팔 부분은 에임 오프셋을 통해 더하기식으로 제어할 수 있도록 비교적 엄격하게 다뤄집니다.

여러가지 면에서 에임 오프셋은 BLend Space(블렌드 스페이스)와 비슷합니다. 블렌드 스페이스는 모션위주 블렌딩

이라면 에임오프셋은 포즈위주의 블렌딩으로서 캐릭터가 벽에 기대거나 특수 포즈를 취한다고 하더라도 에임오프셋에

기억되어있는 메시 스페이스를 기억해주는 특수한 기능입니다.

따라서 에임오프셋으로 설정할 모션들은 메시스페이스로 설정해줘야 합니다.(보통은 전부 로컬스페이스로 설정되어

있음)

메시 스페이스는 애니메이션 시퀀스의 프로퍼티로 설정됩니다. Additive Settings (애디티브 세팅) 카테고리 아래

Additive Anim Type (애디티브 애님 타입) 프로퍼티가 있습니다.

이것을 Mesh Space (메시 스페이스)로 설정하면 설명한 대로 메시 좌표계가 활용됩니다. 이 블렌딩은 비용이 꽤

들기 때문에, 일반적으로 에임 오프셋처럼 일정한 방향으로 계속해서 움직이는 애니메이션이 필요한 블렌드

스페이스 유형에만 사용해야 할 것입니다.

 

 

 

아래는 위 세가지 시스템을 사용하여 간략히 제작해 본 모션 시스템입니다.

 

 

 

반응형
반응형

제작 방식.

1. 시뮬레이션에 적용 될 본에는 공통적으로 Rigid Body와 Collider 를 달아줘야 합니다.

Rigid Body는 시뮬레이션이 사용될 캐릭터에 반드시 들어가야할 컴포넌트이고, Collider는 시뮬레이션오브젝트가 충돌이 일어날 부분에 넣어주게 됩니다. 


 

2. 시뮬레이션이 적용된 자식 본들에는 Character Joint 컴포넌트를 셋팅해 줘야 합니다.

Connected Body에는 자신의 부모본을 넣어줍니다.

 

프로퍼티: 기능:
Connected Body 조인트가 의존하는 Rigidbody에 대한 옵션의 참조. 설정하지 않으면, 조인트는 월드에 연결합니다.
Anchor 조인트가 그 주변에서 회전하는 GameObject의 로컬 공간에서의 점.
Axis 트위스트 축. 오렌지색의 기즈모 원추로 표시됩니다.
Auto Configure Connected Anchor If this is enabled, then the Connected Anchor position will be calculated automatically to match the global position of the anchor property. This is the default behavior. If this is disabled, you can configure the position of the connected anchor manually.
Connected Anchor Manual configuration of the connected anchor position.

Swing Axis 스윙 축. 녹색 기즈모 원추로 표시됩니다.
Low Twist Limit 조인트의 하한 값을 나타냅니다. 아래를 참조하세요.
High Twist Limit 조인트의 상한 값. 아래를 참조하세요.
Swing 1 Limit 정의된 Swing Axis 주변의 하한 값. 아래를 참조하세요.
Swing 2 Limit 정의된 Swing Axis 주변의 상한 값. 아래를 참조하세요.
Break Force 조인트가 제거되도록 하기위해 필요한 힘의 크기를 나타낸다.
Break Torque 조인트가 제거되도록 하기위해 필요한 토크(torque)의 크기를 나타낸다.
Enable Collision 이 조인트가 분해하는 데 적용되어야 하는 토크.
Enable Preprocessing Disabling preprocessing helps to stabilize impossible-to-fulfil configurations.

 

상세정보

캐릭터 조인트는 유니버설 조인트의 경우와 마찬가지로, 움직임을 제한하는 많은 기능을 제공합니다.

트위스트 축(오렌지색 기즈모로 표시)에 따라 상한과 하한(한계 각도는 시작 위치로 측정됩니다)을 도(degree)로 명시함으로써, 제한의 대부분을 제어할 수 있습니다. Low Twist Limit->Limit에서의 ?30 값 및 High Twist Limit->Limit에서의 60은, ?30°와 60° 사이로, 트위스트 축(오렌지색 기즈모) 주변에서 회전을 제한합니다.

Swing 1 Limit 은 스윙 축(녹색 축) 주변에서의 회전을 제한합니다. 한계 각도는 대칭적입니다. 따라서, 예를 들면 30의 값은 ?30과 30 사이에서 회전을 제한합니다.

Swing 2 Limit 축에는 기즈모는 없지만, 이 축은 다른 두 축에 대해 직각입니다. 앞서 말한 축처럼 제한이 대칭이기 때문에, 예를 들어, 40의 값은 ?40과 40 사이에서 회전을 제한합니다.

For each of the limits the following values can be set:

프로퍼티: 기능:
Bounciness A value of 0 will not bounce. A value of 1 will bounce without any loss of energy.
Spring 스프링 힘은 두개의 오브젝트 간의 거리를 유지하기위해 사용된다.
Damper 저항력(damper force)은 스프링 힘을 약화시키기위해 사용된다.
Contact Distance Within the contact distance from the limit contacts will persist in order to avoid jitter.

 

 

3. 시뮬레이션이 적용된 본에는 애니메이션 키 값이 있으면 안된다.

stay1 모션에서 시뮬레이션 본들에게 시뮬레이션이 적용되기 위해서는 키 정보를 지워줘야 정상적으로 출력됩니다.

아마도 키 프레임이 있을경우에는 우선적으로 키 프레임이 출력되도록 강제 셋팅되어 있는거 같습니다.


 

완료영상

 

 

반응형
반응형

참고 자료

[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리

http://www.slideshare.net/agebreak/unite2015-47100325?related=1

 

유니티 그래픽 최적화, 어디까지 해봤니

http://www.slideshare.net/ozlael/graphics-opt-ndc?related=2

 

최적화 내용 간단 정리

** 가장 중요한 것은 병목 지점 파악~(메모리인지, 콜인지, CPU인지, 버텍스연산인지.. 아니면 다함께..)

** 리소스 아껴 쓰기

** 드로우콜 관리하기

** 모바일 사운드는 모노로 사용하기~

** 가비지 컬렉터 관리~~

** 스크립트 함수에 무거운 함수 쓰지 않기~

** 셰이더에 무거운 함수 사용 줄이기~

** 물리 사용은 최소로~

 

1. 프로그램 최적화

* 스크립트 최적화

--- 유니티 객체들을 변수에 저장하고, 캐싱해서 사용하는 것이 좋다.

--- FindObject 계열 함수들은 매우 느리다. (미리 찾아서 캐싱)

--- Update 함수 보다는  Coroutine을 활용한다.

--- 박싱과 언박싱은 부하가 큰 작업이다.

--- 나눗셈보다 곱셈이 몇십배 빠르다.

--- 삼각함수의 값은 상수로 저장하고, 사용하는 것이 좋다.

--- 문자열은 readonly 혹은 const 키워드를 사용하여, 가비지 컬렉션으로부터 벗어나도록 한다.

* 문제의 원인 : 가비지 컬렉터

--- Mono의 동적 메모리 관리 때문에, 메모리 해제를 위해 GC가 자동 호출 된다.

--- GC는 언제 일어날지 모른다.

--- 오브젝트(or 프리팹)의 동적생성과 해제는 부하가 크다.

--- 오브젝트 풀링 사용은 선택이 아닌 필수!

--- 문자열 병합은 StringBuilder

--- foreach 대신에 for문 사용 (foreach는 한번 돌때마다 24Byte의 쓰레기 메모리를 생성)

--- 태그 비교에는 compareTag() 사용

--- 데이터 타입에는 Class 대신 구조체 사용

--- 즉시 해체할 때는 Dispose 수동 호출

--- 임시 객체들을 만들어내는 API들을 조심하라.

* C++ <-> C# 오버헤드

--- 객체의 변경 사항을 캐싱

--- 컴포넌트 참조를 캐싱

--- 빈 콜백 함수는 제거

 

 

2. 그래픽 최적화

* 텍스쳐 최적화

--- 권장 압축 사용하기 : 아이폰 -> PVRTC   ,  안드로이드(Tegra) -> DXT , 안드로이드(Adreno) -> ATC , 안드로이드(공통) -> ETC1 / ETC2

--- 텍스쳐 사이즈는 무조건 2의 제곱이어야 한다. POT(Power of Two) 아닐 경우 무조건 POT로 강제 변환함

--- 텍스쳐는 묶어서 사용하는게 이득이다. 한 화면에 나오는 것끼리~ 같은 재질의 오브젝트끼리~ 알파가 있는것과 없는것끼리

--- 32bit 텍스쳐보다는 16bit를 큰 텍스쳐로 쓰는게 이득이다.

--- 모바일뷰에서 가장 최적화된 해상도를 찾는데 주력한다. 이거저거 다해봐도 개개의 소스를 절약하는 방식이 최고임.

* 메쉬 최적화

--- Import시에 언제나 "Optimize Mesh" 사용 - 버텍스 캐쉬를 최적화 해준다.

--- 언제나 Optimize Mesh Data 옵션을 사용한다. 사용하지 않는 버텍스 정보들을 줄여준다.

--- 사용하지 않는 버텍스 정보들을 줄여 준다.

* 드로우 콜

--- 적절한 DP 는 100이하를 추천, 보통 70~100 정도가 일반적

* CULLING

---- 각 Layer 별로 컬링 거리를 설정해 준다. 중요도가 낮은 오브젝트의 컬링커리를 짧게 설정한다.

---- 오클루젼 컬링을 활용하여 카메라 밖은 잘라내도록 한다.

* 오브젝트 통합

---- 성질이 동일한 오브젝트들은 하나의 메쉬와 재질을 사용하도록 통합

*Batch

---- 스태틱 배치와 다이내믹 배치의 적절한 조합

* 라이팅

---- 라이트맵과 라이트렌더 모드 활용

* OverDraw

--- 한 픽셀에 두 번 이상 그리게 되는 경우 OVERDRAW 문제가 발생한다.

--- 기본적으로 앞에서 뒤로 그린다. Depth testing으로 인해서 오버드로우를 방지한다. 알파 블렌딩이 있을경우 소팅 문제 발생

--- 반투명 오브젝트의 개수의 제한을 건다. 뒤에서 앞으로 그려야 함. 반투명 오브젝트 갯수가 늘어날수록 퍼포먼스 직결~!

 

 

3. 사운드 최적화

--- 모바일에서 스테레오 사용은 퍼포먼스에 큰 영향을 끼친다. -> 되도록이면 모두 92 kb, 모노로 인코딩

--- 사운드 파일을 임포트하면 디폴트로 3D 사운드로 설정 -> 2D 사운드로 변경

--- 압축 사운드(mp3. ogg) , 비압축 사운드(wav) 구별.    압축 사운드-> 순간적인 효과음, 이펙트등..      비압축사운드 -> 배경 음악 

 

 

4. 폰트 리소스 최적화

--- Packed Font - R,G,B,A channel에 각각 글자의 형태를 저장하는 방법. 메모리 용량을 1/4로 절약

--- 리소스 기타 - ResourceLoadAsync() 함수는 엄청 느리다.

 

5. 셰이더 최적화

--- 기본 셰이더를 사용할 경우, 모바일용 셰이더 사용 Movile -> VertexLit 가장 빠른 셰이더

--- pow, exp, log, cos, sin, tan 같은 수학 함수들은 고비용이다.

--- 텍스쳐 룩 업 테이블을 만들어서 사용하는 것도 좋다.

--- 알파 테스트 연산(discard)은 느리다. 무조건 최소로..

--- 라이트맵 활용은 필수.

* 실수 연산

--- float : 32bit -> 버텍스 변환에 사용, 아주 느린 성능 (픽셀 셰이더에서 사용은 피함)

--- Half : 16bit -> 텍스쳐 uv에 적합, 대략 2배 빠름

--- fixed : 10bit -> 컬러, 라이트 계산과 같은 고성능 연산에 적합, 대략 4배 빠름]

 

6. 물리 엔진 최적화

--- FixedUpdate()는 Updata와 별도로 주기적으로 불리며, 주로 물리 엔진 처리

--- Default는 0.02초, 게임에 따라 0.2초 정도로 수정해도 문제 없음

--- 물리 엔진이 적용되지 않는 오브젝트는 Static으로 설정

--- 리지드 바디가 없는 고정 충돌체를 움직이면, CPU 부하 발생 - 물리 월드 재구성 - 이럴경우 isKinematic 옵션 사용

--- Maximum Allowed timestep 조정하여 물리 계산을 건너뛸 수 있는 부분은 무조건 건너 뛴다.

--- EDIT -> Project Setting -> Physics 에서 Solver Iteration Count 조정. 높을수록 정교하므로 낮게 설정한다.

--- Sleep 조절 -> 리지드 바디의 속력이 설정된 값보다 작을 경우, 휴면상태에 들어감.

--- Physics.Sleep() 함수를 이용하면, 강제 휴면 상태로 만듬.

--- 래그돌 사용 최소화

--- 태그 대신 레이어 활용 - 물리처리에서 레이어가 훨씬 유리, 성능과 메모리에서 장점을 가진다.

--- 메쉬 콜리더는 절대 사용 금지.

--- 레이캐스와 Sphere Check 같은 충돌 감지 요소를 최소화

--- Tilemap Collision Mesh -- 2D 게임에서 타일맵의 Collison Mesh를 최적화 하라.

 

반응형
반응형

루트 모션 사용하기

1. 루트 본 설정하기

- 기존과 동일하게 임포트 한 후 애니메이션을 등록할때 RootNode를 설정해 주면 됩니다.

 

2. 루트 모션의 특성을 지정한다.

Tramsform 이나 특정 축에 따라 어떤 방식으로 할지 정할 수 있습니다.

Original로 할 경우 원래 방향성을 유지하게 되고 Root Node Position으로 할 경우 지정된 루트 노드의 방향성과

위치값을 그대로 따라가게 됩니다. (Bone001을 루트 노드로 설정하면 무조건 Bone001을 따라가게 됨)

평면축에서만 루트 모션을 사용하고 싶을때는 마지막에 있는 Root Transforrm Position(XZ) 만 루트 노드를 따라가게 하면 됩니다.

  

3. 설정이 완료되면 루트모션이 적용됩니다.

캐릭터 발 아래의 둥근 원이 루트 모션이 사용될 Root Node 입니다.(루트 모션 적용이 안되면 아래 원이 따라다니지 않습니다.)

 

반응형
반응형
반응형
반응형

http://acegikmo.com/shaderforge/

CG 스크립트 없이 쉐이더 편집을 가능하게 해주는 플러그인

최근 교육 받고 있는데 언리얼 쉐이더와 맞먹을정도로 편하네요~

홈페이지를 가보면 쉐이더를 눈으로 쉽게 알수 있도록 구성해 놨습니다.

쉐이더 공부하기에 매우 좋은 사이트~!

반응형

+ Recent posts