게임 개발기/Gravity War

[Gravity War] 중력 방식 변경

bokob 2024. 12. 29. 23:59

기존에는 우선순위를 두어 중력을 적용하였다.

이 방식은 자연스럽지 않다고 생각이 들어, 만유인력의 법칙을 추가적으로 적용하여 더 자연스러운 중력을 적용하였다.

플레이어 기준으로 동일한 거리에 동일한 중력의 행성이 존재하는 경우

같은 조건의 행성이 플레이어로부터 같은 거리에 존재하게 되면, 중간에서 떠다니는 문제가 발생했다.

따라서 다음과 같이, 코드를 더 보완했다.

Vector3 LawOfUniversalGravity()
{
    if (_gravityAreaList == null || _gravityAreaList.Count == 0) return Vector3.zero;

    // 중력의 총합이 0이 되어 표류하지 않도록 하기 위함
    // 다른 행성에 있는데, 중력이 큰 행성에 끌려가지 않기 위함
    // 이를 위한 가장 가까운 행성과의 거리, 힘, 방향
    float closetPlanet = 9999999f;
    float closetPlanetForce = 0.0f;
    Vector3 closetPlanetVector = Vector3.zero;

    float objectMass = _rb.mass;
    Vector3 totalForce = Vector3.zero;
    for (int i = 0; i < _gravityAreaList.Count; i++)
    {
        float pivotMass = _gravityAreaList[i].GetComponent<Rigidbody>().mass;                  // 행성 질량
        Vector3 distVector = _gravityAreaList[i].transform.position - transform.position;      // 행성과의 거리 벡터
        float dist = distVector.magnitude;                                                     // 행성과의 거리
        float force = G * pivotMass * objectMass / Mathf.Pow(dist, 2);                         // 만유인력

        // 플레이어 전용
        if(closetPlanet > dist)
        {
            closetPlanet = dist;
            closetPlanetForce = force;
            closetPlanetVector = distVector;
        }

        totalForce += distVector.normalized * force;                                           // 타겟에 적용되는 모든 힘 더하기
    }

    // 플레이어의 경우
    if (gameObject.TryGetComponent(out _playerStatus))
    {
        if (_playerStatus.IsFall)
        {
            totalForce = closetPlanetVector.normalized * closetPlanetForce;
        }
    }

    return totalForce.normalized;
}

 

플레이어 기준으로 동일한 거리에 동일한 행성이 존재해도 마지막에 탐색된 행성으로 지정되게 함

 

그리고 행성 표면에 있어도 다른 행성의 큰 중력에 영향을 받아 날아가지 않도록 공중에 떠있는 IsFall 상태를 따로 두어, 해당 상태일 때만 중력에 영향을 받도록 하였다.

 

잡담)

계산하면서 이런 저런 방식을 시도해보니 시간이 너무 많이 들지만 재밌었다.

조금 더 속도를 내보자.

'게임 개발기 > Gravity War' 카테고리의 다른 글

[Gravity War] 기초 작업  (0) 2024.11.26