티스토리 뷰

Unity 3D 모델 캐릭터 배치, 무기 배치, 헤어스타일 배치

 

 

Unity 3D에서 3D 모델 캐릭터를 배치하는데는 약간의 기교가 필요합니다.

단순히 캐릭터를 배치하는 것은 어렵지 않지만 게임에서 흔히 볼 수 있는 것처럼 캐릭터가 갑옷을 착용하고, 무기도 장착하고, 헬멧도 착용한다거나 날개를 다는 등의 경우에는 약간은 복잡한 과정을 거치게 됩니다.

 

 

 

위의 그림 및 동영상은 게임을 처음 설치했을 때 캐릭터를 선택하는 화면으로, 남자 캐릭터 3종(백인, 황인, 흑인)과 여자 캐릭터 3종(백인, 확인, 흑인) 중에서 하나를 선택하는 화면입니다.

 


 

지금은 테스트 중으로 화면의 오른쪽 이미지는 얼추 비슷하게 그림을 넣어놨지만 실제 3D 모델은 테스트를 위해 다양한 캐릭터를 배치해 둔 상태입니다.

 

아래의 설명 중 캐릭터 6종이 이미지와 다르더라도 양해 바랍니다.

 

 

캐릭터를 처음 배치할 때 어디에 배치할 것인지를 결정해야 합니다.

지금의 경우는 캐릭터가 이동하지는 않는 상황이기 때문에 카메라(위 그림에서는 SignUpMainCamera)에 SP(위 그림에서는 SpSignUpPlayerFrame)를 추가하고 SP에 캐릭터를 배치하였습니다.

 

캐릭터가 이동하는 경우에는 카메라에 배치하는 것보다는 별도의 SP를 만들고 여기에 추가해서 관리하는 것이 좋습니다.

 

프로그램 내에서 SP의 위치를 언제나 불러서 사용할 수 있도록 전역변수로 설정해 줍니다.

 

전역변수로 선언 

public static GameObject signUpMainCamera;

 

함수에서 실행

signUpMainCamera = GameObject.Find("SignUpMainCamera");

 

signUpMainCamera는 사전에 전역변수로 설정되어 있어야 합니다.

 

캐릭터를 위의 SpSignUpPlayerFrame에 배치하기 위해 다음의 함수를 작성했습니다.

 

void SignUpPlayerFrameSet()
{
        StartCoroutine(SignUpPlayerAllSet());
}

 

함수명 앞에 void 가 아닌 StartCoroutine 명령을 사용해서 SignUpPlayerAllSet()를 호출하도록 한 이유는 SignUpPlayerAllSet() 함수 안에서 yield 명령을 사용하기 위해서입니다.

 

 

IEnumerator SignUpPlayerAllSet()
    {
        spSignUpPlayerFrame = signUpMainCamera.transform.Find("SpSignUpPlayerFrame").gameObject;
        spSignUpPlayerFrame.transform.localScale = Vector3.one;
        spSignUpPlayerFrame.transform.localPosition = Vector3.zero;
        spSignUpPlayerFrame.transform.localRotation = Quaternion.Euler(Vector3.zero);
        SignUpArmorSet();
        yield return null;
       
        SignUpWeaponSet();
        SignUpHairSet();
        objSignUpArmor.transform.localScale = Vector3.one;
        objSignUpArmor.transform.localPosition = new Vector3(-1.5f, -0.5f, 4);
        objSignUpArmor.transform.localRotation = Quaternion.Euler(new Vector3(0, 135, 0));
        DungeonCharacterShadowHiddenRecursion(objSignUpArmor);
        objSignUpArmor.SetActive(true);
        signUpAnimator = objSignUpArmor.GetComponent<Animator>();
    }

 

spSignUpPlayerFrame을 찾아서 초기화 작업을 진행해 줍니다.

 

제가 사용하고 있는 캐릭터는 갑옷이 입혀진 상태의 캐릭터가 기본이기 때문에 SignUpArmorSet()를 사용해서 갑옷이 입혀진 캐릭터를 배치합니다.

 

그런 다음 yield return null; 명령을 사용해서 다음 프레임에 이후의 명령을 실행하도록 해 줍니다.

 

위의 yield 명령을 사용하지 않을 경우 갑옷을 입고 있는 캐릭터를 배치했지만 화면에는 나오지 않은 상태라서 이후에 착용하는 무기 및 헤어스타일을 캐릭터에 배치할 수 없기 때문입니다.

 


 

캐릭터 배치 순서는 다음과 같습니다.

 

1. 캐릭터 배치(SignUpArmorSet();)

2. 다음 프레임 이후에 명령을 실행(yield return null;)

3. 무기 배치(SignUpWeaponSet();)

4. 헤어스타일 배치(SignUpHairSet();)

5. 캐릭터 크기 변경(objSignUpArmor.transform.localScale = Vector3.one;)

6. 캐릭터 위치 변경(objSignUpArmor.transform.localPosition = new Vector3(-1.5f, -0.5f, 4);)

7. 캐릭터 회전 각도 변경(objSignUpArmor.transform.localRotation = Quaternion.Euler(new Vector3(0, 135, 0));)

 

위의 소스 중 DungeonCharacterShadowHiddenRecursion(objSignUpArmor); 함수는 캐릭터에 설정된 그림자를 모두 제거하는 재귀호출함수입니다. 유니티에서 제공하는 함수는 아니고 제가 작성한 소스입니다.

 

게임 실행 중에는 캐릭터의 발 아래에 그림자가 나오는게 자연스럽지만 위쪽의 그림처럼 캐릭터 선택화면에서는 그림자가 나오면 어두운 느낌이 있어서 캐릭터에 설정된 그림자를 재귀호출함수를 사용하여 제거한 것입니다.

 

위의 작업이 끝나고 나면 objSignUpArmor.SetActive(true); 함수를 사용하여 캐릭터를 Active (화면에 보이도록) 해 줍니다.

캐릭터가 정지되어 있으면 게임의 퀄리티가 떨어지므로 캐릭터가 자연스럽게 움직이도록 하기 위해 애니메이션 컴포넌트를 설정해 주고 나중에 원하는 애니메이션을 지정해 줍니다.

 

현재는 Idle 상태이며 일정 시간 간격으로 Attack(공격)을 하는 애니메이션을 넣어둔 상태입니다. 이 과정은 위의 소스에는 포함되어 있지 않습니다.

 

 

void SignUpArmorSet()
    {
        string strText;
        Destroy(objSignUpArmor);
       
        strText = string.Format("Armor/{0:0000}", mPlayer.ArmorDefaultNo);
        //objSignUpArmor = Instantiate(Armor[mPlayer.ArmorDefaultNo], Vector3.zero, Quaternion.identity) as GameObject;
        objSignUpArmor = Instantiate(Resources.Load(strText), Vector3.zero, Quaternion.identity) as GameObject;
        objSignUpArmor.transform.parent = spSignUpPlayerFrame.transform;
        objSignUpArmor.SetActive(false);
    }

 

위의 함수 SignUpArmorSet()는 캐릭터를 배치하는 소스입니다.

 

 

void SignUpWeaponSet()
    {
        string strText;
        Destroy(objSignUpWeapon);
       
        GameObject obj = objSignUpArmor.transform.Find("RigPelvis/RigSpine1/RigSpine2/RigRibcage/RigRArm1/RigRArm2/RigRArmPalm/Dummy Prop Right").gameObject;
        strText = string.Format("Weapon/{0:0000}", HEROWEAPONDEFAULTNO);
        //objSignUpWeapon = Instantiate(Resources.Load(strText), obj.transform.position, Quaternion.Euler(90, -150, 0)) as GameObject;
        objSignUpWeapon = Instantiate(Resources.Load(strText), obj.transform.position, Quaternion.Euler(-90, 0, 0)) as GameObject;
        objSignUpWeapon.transform.parent = obj.transform;
    }

 

위의 함수 SignUpWeaponSet()는 캐릭터에 무기를 장착하는 소스입니다.

 

 

void SignUpHairSet()
    {
        string strText;
        Destroy(objSignUpHair);
        GameObject obj = objSignUpArmor.transform.Find("RigPelvis/RigSpine1/RigSpine2/RigRibcage/RigNeck/RigHead/Dummy Prop Head").gameObject;
       
        strText = string.Format("Hair/{0:0000}", mPlayer.HairDefaultNo);
        objSignUpHair = Instantiate(Resources.Load(strText), obj.transform.position, Quaternion.Euler(-90, 0, 0)) as GameObject;
        objSignUpHair.transform.parent = obj.transform;
    }

 

위의 함수 SignUpHairSet()은 캐릭터에 헤어스타일을 장착하는 소스입니다.

 

게임 설치 후 캐릭터를 설정하는 단계이기에 갑옷을 입은 캐릭터를 선택하는 단계이며, 기본적으로 무기 중 기본무기를 제공하고, 헤어스타일까지만 제공하도록 설정해 둔 상태입니다.

 

위의 그림 및 동영상에 나오는 캐릭터는 유니티 에셋스토어에서 구매한 제품입니다.

 


 

댓글