Unity

UnityChan-SD 가지고 놀기

Drill_Labito 2023. 4. 17. 00:23

SD 유니티짱 에셋 : https://unity-chan.com/download/releaseNote.php?id=SDUnityChan&lang=en 

 

SD Unity-chan 3D model data - Download - UNITY-CHAN! OFFICIAL WEBSITE

ver 1.1.0 release Checked with Unity 2020.3.44f1. Compatible with Unity Toon Shader. To use this data, you need to install Unity Toon Shader from Package Manager, which is installed in Anime Toolbox.

unity-chan.com

유니티짱 툰 쉐이더 : https://unity-chan.com/download/releaseNote.php?id=UTS2_0&lang=en 

 

UnityChanToonShader2.0 - Download - UNITY-CHAN! OFFICIAL WEBSITE

2022/06/14: 2.0.9 Release: new features added. * Changed release environment to Unity 2019.4.31f1, tested with Unity 2020.3.x LTS. * Single Pass Instanced rendering (also known as Stereo Instancing), support. See Unity Manual for supported platforms. * Not

unity-chan.com

 

현재는 아래와 같이 걸어다니는 동작까지 구현 및 처리를 해봤다. 

유니티가지고 게임을 만들고 싶은데, 매번 박스나 캡슐 오브젝트보는게 지겨워서 에셋중 어떤게 좋을까 하다, 유니티짱이라는 유명한 에셋이 있다고 해서 찾아봤다. 

아래는 유니티짱 SD Asset에 있는 Misaki_sum_humanoid 라는 프리팹이다. 

에셋을 가져올때 Material에서 Shader 리스트 중 Standard로 설정하면 아래와 같이 기본형으로 나온다. 

하지만 이렇게 보기엔 아쉬워서 카툰쉐이더를 따로 구해서 적용해봤다. ( Unitychan Toon Shader )

확연히 차이가 많이 난다. 내부적으로 어떻게 동작하는지는 모르니 추후 에셋에 세팅된 정보를 살펴보며 공부해봐야겠다. 

에셋에 보면 Animator 정보에 움직임에 대한 애니메이션 정보가 이미 다 있는상태이고, face 쪽에는 각종 표정들이 많이 있다. 

기존 Animation 파라미터값으로 Next, Back 2가지만 존재하는데 실제로 이것만가지고 자연스런 움직임을 줄 수없어서 

- Stand

- Walk

2가지 Bool 변수를 추가해서 키입력에 따라 처리하였다. 

하지만 이후를 생각해보면 Bool 값이 아닌, 정수형하나를 선언하고 열거형 값 같은걸로 캐릭터 상태를 전이시킬 수 있는게 더 바람직하다고 생각된다. 

 

현재는 간단하게 움직이는거 까지 현재 진행해봤다.

이후엔 이 캐릭터들로 가벼운 미연시 게임이나 캐주얼 게임 개발을 목표로 해봐야겠다. 

 

캐릭터 움직임에 관한 코드는 아래와 같이 사용하였다. 

아직 개선이 필요해보인다.  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Animator animator;

    public float turnSpeed = 8.0f;
    public float smoothMoveTime = 0.1f;
    public float moveSpeed = 1.0f;

    private float smoothInputMagnitude;
    private float smoothMoveVelocity;
    private float playerAngle;              // 캐릭터 회전각도 
    private Vector3 velocity;               // 실제 속도
    private Rigidbody rigidbody;
    private bool disable = false;

    // 개인적으로 Awake는 생성자 느낌으로 사용 ( 최초 1회만 호출되므로 )
    void Awake()
    {
        turnSpeed = 10.0f;
        smoothMoveTime = 0.1f;
        moveSpeed = 2.0f;
        disable = false;

        animator = GetComponent<Animator>();
        rigidbody = GetComponent<Rigidbody>();
    }

    // 캐릭터 움직이기 
    void Update()
    {
        Vector3 inputDirection = Vector3.zero;
        if (!disable)
        {
            float input_X = 0.0f;
            input_X = Input.GetAxisRaw("Horizontal");
            float input_Z = 0.0f;
            input_Z = Input.GetAxisRaw("Vertical");

            // 입력에 따른 방향벡터 구하기
            inputDirection = new Vector3(   input_X,
                                            0,
                                            input_Z);

            if(input_X != 0.0f || input_Z != 0.0f)
            {
                animator.SetBool("Stand", false);
                animator.SetBool("Walk", true);
            }
            else
            {
                animator.SetBool("Walk", false);
                animator.SetBool("Stand", true);
            }
        }

        // 방향벡터 정규화
        float inputMagnitude = inputDirection.magnitude;
        smoothInputMagnitude = Mathf.SmoothDamp(smoothInputMagnitude, inputMagnitude, ref smoothMoveVelocity, smoothMoveTime);

        // 입력방향에 맞는 회전각도 구하기
        float targetAngle = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg;
        playerAngle = Mathf.LerpAngle(playerAngle, targetAngle, Time.deltaTime * turnSpeed * inputMagnitude);
        transform.eulerAngles = Vector3.up * playerAngle;

        velocity = transform.forward * moveSpeed * smoothInputMagnitude;

        // transform.rotation *= Quaternion.AngleAxis(_look.x * rotationPower, Vector3.up);
    }

    // Rigidbody 이용하면 FixedUpdate 사용, 아니면 Update 사용
    void FixedUpdate()
    {
        rigidbody.MoveRotation(Quaternion.Euler(Vector3.up * playerAngle));
        rigidbody.MovePosition(rigidbody.position + velocity * Time.deltaTime);
    }
}