odyssey

#1 odyssey 개발일지 : 지형 생성, 캐릭터 움직임 구현

san10 2022. 11. 7. 01:49

컨셉아트도 대충 짰고 이제 본격적으로 개발을 해야한다.

 

 

1. 지형생성

우선 처음으로 한 일은 지형생성인데

곡선의 언덕을 어떻게 만들까 고민했고, 우선 지금 지형을 생성하는 방식은

 

1. 폴리곤 콜라이더로 뼈대를 만든다.

2. 폴리곤 콜라이더의 포인트를 받아와서 포인트를 바탕으로 메쉬를 생성한다

3. 메쉬에 머티리올 적용

 

그럼 최종적으로 다음과 같은 모습이 된다

 

아직 테스트 용이라 곡선이 삐뚤삐뚤하지만

나중에는 베지어 곡선으로 곡선을 구현하려고 한다.

미리 베지어 곡선으로 지형을 만들어서 플레이할때 적당히 붙일지

아니면 플레이할때 랜덤하게 지형을 만들지는 고민이지만

우선 테스트 수준이기에 이정도로 만족하기로 했다.

 

    private List<Vector3> vertiece = new List<Vector3>();
    private List<Vector3> sortVertiece = new List<Vector3>();
    private List<int> triagles = new List<int>();
    PolygonCollider2D point;


    void generateMesh()
    {
        Vector3 tmp = new Vector3();
        for (int i = 0; i < point.GetTotalPointCount(); i++)
        {
            tmp.x = point.points[i].x;
            tmp.y = point.points[i].y;
            vertiece.Add(tmp);
        }

        sortVertiece = vertiece.OrderBy(x => x.x).ToList();
        Vector3 center = new Vector3(((sortVertiece[0].x + sortVertiece[point.GetTotalPointCount() - 1].x) / 2), sortVertiece[0].y, 0);

        sortVertiece.Insert(0, center);

        triagles.Clear();
        for (int i = 1; i < sortVertiece.Count-1; i++)
        {
            triagles.Add(0);
            triagles.Add(i);
            triagles.Add(i + 1);
            Debug.Log(i);
        }
        Mesh mesh = new Mesh();
        mesh.vertices = sortVertiece.ToArray();
        mesh.triangles = triagles.ToArray();
        GetComponent<MeshFilter>().mesh = mesh;
    }

    void Start()
    {
        point = GetComponent<PolygonCollider2D>();
        generateMesh();
    }

 

2. 캐릭터 움직임 구현

캐릭터가 어떻게 움직일지 간단하게 써보자면

기본적으로 알토의 모험처럼 지형을 따라 움직이고

이단 점프가 가능하게 만들 생각이다.

그리고 점프 중에는 앞뒤회전도 가능하게 만들 예정이다

 

우선은 지형을 따라 움직이는 것을 만들었다.

처음에는 무작정 AddForce에 transform.right 를 통해 앞으로 가게 만들었는데

캐릭터를 아직 안그려서 병아리 스프라이트를 가져왔다.

보다시피 지형을 따라 움직이지도 않고 무엇보다 경사가 생기면 더이상 나아가지 못한다.

 

그래서 다음에는 리지드바디의 velocity를 통해 움직임을 구현했다.

AddForce로 구현했을 때보단 훨씬 낫지만 경사에 따라 속도차가 너무 크고

무엇보다 속도가 빠르거나 경사가 크면 통통 튀면서 내려가는 문제점이 있다.

 

 

해결 방법을 찾아보니 경사의 노말벡터로 캐릭터의 이동방향을 투영해줘야 한다고 하는데

사실 정확히 이해하진 못했지만 아래 블로그글 참고하면서 수정했다.

https://daekyoulibrary.tistory.com/147

 

[Charon] #3. RigidBody를 사용한 3D 캐릭터의 경사로(Slope) 지형 이동 구현하기

목차 인사말 오랜만에 다시 포스팅을 올리네요. 그동안 다른 교육 프로그램을 듣는다고 바빠서 카론 개발을 못 했습니다. FPS 게임 개발은 처음 진행해봤는데, 어릴 때 카운터스트라이크 온라인

daekyoulibrary.tistory.com

생각한대로 잘 움직인다.

 

이제 경사에 따라 캐릭터의 회전축을 변경해 주려고 하는데, 이거에 관해서는 아래글을 많이 참고했다.

https://gall.dcinside.com/mgallery/board/view/?id=game_dev&no=19943 

 

유니티 물리엔진으로 움직임 구현하기~ - 인디 게임 개발 마이너 갤러리

유니티에서 Rigidbody와 Collider를 이용하여 움직임을 구현하시는분들이 많을겁니다~그런데 구현하다 보면 뭔가조금 비자연스러운 경우가 많이 있으실텐데요.여러 사례를 들어 조금 자연스러운 움

gall.dcinside.com

플레이어 캐릭터의 Vector.down 방향으로 레이캐스트를 쏘고, 지형의 법선 벡터를 구해서 캐릭터의 up벡터와 내적하면 기울기를 구할 수 있다.

 

그리고 내적의 값은 항상 양수라서, 법선 벡터의 x값이 양수면 기울기도 -시켜줬다.

최종적으로 이렇게 움직인다.

 

private void Move()
    {
        slopeHit=Physics2D.Raycast(transform.position, Vector3.down*50f, rayDistance,1<<6);
        if (slopeHit.normal.x >= 0)
        {
            playerAngle = -Vector3.Angle(transform.up, slopeHit.normal);
        }
        else
        {
            playerAngle = Vector3.Angle(transform.up, slopeHit.normal);
        }
        transform.GetChild(0).localEulerAngles = new Vector3(0,0,playerAngle);

        velocity = AdjustDirectionToSlope(direction);
        gravity= Vector3.down* Mathf.Abs(rigid.velocity.y);

        rigid.velocity =velocity*walkForce+gravity;
    }

 

 

위의 코드를 FixedUpdate에서 돌려준다