본문 바로가기

Unity/Unity 스파르타

10주차 - 개인 심화 3D(움직임,구르기,대쉬,잔상) + Mixamo Tip

728x90

 

1. 마우스 클릭으로 캐릭터 움직이기.

2. 구르기

3. 대쉬

4. 잔상 효과(Mesh)

 


 

더보기

 

fbx에서 Materials - Location 에 Use External Materials(Legacy) 로 체크후

적용 한 뒤 다시 Use Embedded Materials로 적용시켜보기.

그래도 안되면 Textures - Extract Textrues 로 해당 fbx 에 텍스쳐를 받아와 수동으로 텍스쳐를 넣어주는 방법을 쓰면 해결.

 

1. 마우스 클릭으로 캐릭터 움직이기.

카메라에서 마우스 클릭지점으로 Ray 를 쏘고, 바닥과 Ray 가 만나는 지점을 hit 으로 저장해줍니다.

  • Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100, clickableLayerMask))
  • 목표 위치와 방향을 구해줍니다
  • FixedUpdate 를 통해 목표 위치까지 이동시켜줍니다
    • 걷고, 뛸때 적절한 애니메이션을 적용시켜 줘야하기 때문에 애니메이션컨트롤러를 하나 만들고 델리게이트에 연결해 줍니다
    • 플레이어의 이동의 경우 현재위치와 도착위치의 거리를 계산해 목표 위치에 도달했는지 확인해 줍니다.
      • 목표 위치에 도달했다면 캐릭터가 제자리에 멈추도록 해줍니다
    • 플레이어가 목표 위치로 이동할때 몸의 방향을 해당 방향으로 부드럽게 회전시켜줍니다.
  • 쉬프트 키를 누르면 캐릭터가 뛰게 만들 것 입니다.
    • 쉬프트 키를 누르면 평소 이동속도보다 더 빠르게 이동할 것이며, 후일 스테미너를 소모해 뛰게끔 만들 것 입니다. 

2. 구르기

  • FixedUpdate 에서 계속해서 현재위치와 목표 위치를 비교중이라, 구르기를 했을때 목표위치를 계속 벗어나 버리면서 생기는 버그가 있었으며, 애니메이션 자체에 구르기할때 위치값이 변해서 애니메이션의 Root Transform Position (XZ)의 고정을 해제 해 줬습니다.
  • AddForce로 굴렀을때 진행방향으로 순간적으로 나아가게 해줬지만 구르는 모션과, 이동이 매끄럽지가 않아서 순간적으로 플레이어의 이동속도를 증가시켜 주는 쪽으로 변경했습니다.

3. 대쉬

일정속도만큼 점점 증가하다가 최고 속력에 도달하게되면 다시 원래 속도로 돌아오는 대쉬 기술을 만들 것 입니다.

속도가 올라가는 만큼 애니메이션 속도도 같이 올려줄 것 입니다.

    public float initSpeed;
    public float maxSpeed;

    public float accelerationTime = 2f; // 가속 시간
    public float decelerationTime = 2f; // 감속 시간

    public float currentAccelerationTime; // 현재 가속 시간
    public float currentDecelerationTime; // 현재 감속 시간

현재 가속 시간이 가속 시간에 가까워 질수록 최고 속력을 가지고

현개 감속 시간이 감속 시간에 가까워 질수록 원래 속력으로 돌아오게 만들 것 입니다.

애니메이션의 재생속도 또한 1에서 2로, 2에서 1로 돌아오게 만들 것 입니다.

더보기
    IEnumerator ActiveDashCo()
    {
        onDash = true;
        curCooltime = cooltime;

        float initspeed = 1;
        float maxspeed = 2;

        StartCoroutine(DashCooltimeCo());

        playerAnimationController.animator.SetBool("isRunning", true);
        playerAnimationController.isRunning = true;

        while (currentAccelerationTime < accelerationTime) //1
        {
            currentAccelerationTime += Time.deltaTime;
            playerController.playerSpeed = Mathf.Lerp(initSpeed, maxSpeed, currentAccelerationTime / accelerationTime);


            float curSpeed = Mathf.Lerp(initspeed, maxspeed, currentAccelerationTime / accelerationTime);
            playerAnimationController.animator.SetFloat("addSpeed",curSpeed );

            yield return null;
        }

        while (currentDecelerationTime < decelerationTime) //1
        {
            currentDecelerationTime += Time.deltaTime;
            playerController.playerSpeed = Mathf.Lerp(maxSpeed, initSpeed, currentDecelerationTime / decelerationTime);

            float curSpeed = Mathf.Lerp(maxspeed, initspeed, currentDecelerationTime / decelerationTime);
            playerAnimationController.animator.SetFloat("addSpeed", curSpeed);


            yield return null;
        }
        playerController.playerSpeed = 60;
        playerAnimationController.animator.SetBool("isRunning", false);
        playerAnimationController.isRunning = false;

        currentAccelerationTime = 0;
        currentDecelerationTime = 0;

        onDash = false;
    }
    
    
     IEnumerator DashCooltimeCo()
    {
        while(curCooltime > 0)
        {
            curCooltime -= Time.deltaTime;
            yield return null;
        }

        curCooltime = 0;
    }

4. 잔상 효과

캐릭터 오브젝트에 있는 SkinnedMeshRenderer 와 MeshRenderer, MeshFilter 를 사용해 잔상효과를 만들어줄 것 입니다.

플레이어의 몸체를 그리는 SkinnedMeshRenderer를 가져옵니다

가지고온 SkinnedMeshRenderer 를 사용해 새로운 게임오브젝트에 MeshFilter,MeshRenderer 컴포넌트를 추가하고, 새로 mesh 를 만들어 BakeMesh로 구워준뒤 쉐이더 작업을 통해 만들어진 Material을 MeshFilter에 넣어줍니다.

 

    IEnumerator ActiveTrailCo(float activeTime)
    {
        while(activeTime > 0)
        {
            activeTime -= refreshRate;
           
                GameObject gObj = new GameObject();
                gObj.transform.SetPositionAndRotation(GameManager.instance.player.transform.position, GameManager.instance.player.transform.rotation);
                MeshRenderer mr = gObj.AddComponent<MeshRenderer>();
                MeshFilter mf = gObj.AddComponent<MeshFilter>();

                Mesh mesh = new Mesh();
                skinnedMeshRenderer.BakeMesh(mesh);
                mf.mesh = mesh;
                mr.material = mat;

                Destroy(gObj, 0.5f);

                yield return new WaitForSeconds(refreshRate);
            }
        }
    }

728x90