집게사장의 꿈

[영혼들] 몬스터의 기괴한 움직임 표현 1 본문

제작/영혼들

[영혼들] 몬스터의 기괴한 움직임 표현 1

Krapboss 2023. 10. 20. 01:56

 

 

문제점
- 몬스터의 사지가 꺾이는 듯한 기괴한 움직임을 주고 싶지만, 역동적으로 꺾이는 모습을 구현하기에 고민이 생김

*시도해본 내용

 

1. 각 Rotate좌표에 있는 X Y Z의 값에 가중치를 주어 각 가중치에 맞게 회전시킴.

//1. X Y Z에 대한 가중치를 설정한다.
Vector3 rotateW = Vector3.zero;
rotateW.x = Random.Range(0, 1.0f);
rotateW.y = Random.Range(0, 1.0f - rotateW.x);
rotateW.z = 1.0f - rotateW.x - rotateW.y;

//2. 지정된 값에서 랜덤한 값으로 회전값을 지정한다.
float r = Random.Range(0.0f,parts[i].degree);
rotateW = rotateW * r *2.0f;

//3. 오브젝트 로테이션 지정
parts[i].part.rotation = Quaternion.Euler(defaultRotates[i] + rotateW);

 


*결과

-가끔씩 역동적인 동작이 나오나, 매번 역동적이지 못한 느낌으로 불만족


 

*변경할 부분

1. 역동적인 모습을 연출하려면, 회전되는 좌표 중 x, y, z 중 2개의 방향으로만 회전을 시키거나 가중치를 치중시켜야 된다.

 

*이유

-만약에 비슷한 가중치로 각 로테이션 값이 비슷해진다면 변화률이 크지가 않기 때문이다.


-만약 가중치를 먼저 선정된 좌표를 기준으로 준다면 극적인 꺾임이 가능할 것으로 보임

 


* 가중치 분배 규칙

1. 첫번째로 선정된 좌표는 0.5이상의 가중치를 부여받음.

2. 두번째로 선정된 좌표는 가중치를 0.2이상 부여받음.

3. 세번째로 선정된 좌표는 나머지 값을 가짐.

 

 


*변경 후 결과

-매우 역동적이고 괴기하게 변경되었음. 조금 과한 점이 있다면 각도 값을 조정하면 된다.

public void UpdatePartNextRotate()
{
    if (parts.Length == 0) return;

    for (int i = 0; i < parts.Length; i++)
    {
        //랜덤한 위치값을 지정하기 위한 값
        int[] randomAxis = new int[3] { -1, -1, -1 };

        //1. 가중치를 다르게 하기 위해 랜덤한 순서로 좌표를 선정한다.
        for (int index = 0; index < randomAxis.Length; index++)
        {
            while (true)
            {
                //랜덤값을 선정
                int axis = Random.Range(0, randomAxis.Length);

                //해당 값이 존재하지 않을 경우에만 지정
                if (!randomAxis.Contains(axis))
                {
                    randomAxis[index] = axis;
                    break;
                }
            }
        }

        //2. X Y Z에 대한 가중치를 설정한다.
        Vector3 rotateW = Vector3.zero;
        rotateW[randomAxis[0]] = Random.Range(0.5f, 0.8f);
        rotateW[randomAxis[1]] = Random.Range(0.2f, 1.0f - rotateW[randomAxis[0]]);
        rotateW[randomAxis[2]] = (1.0f - rotateW[randomAxis[0]] - rotateW[randomAxis[1]]);
        rotateW[0] *= (Random.Range(0, 2) == 0 ? 1 : -1);
        rotateW[1] *= (Random.Range(0, 2) == 0 ? 1 : -1);
        rotateW[2] *= (Random.Range(0, 2) == 0 ? 1 : -1);

        //3. 지정된 값에서 랜덤한 값으로 회전값을 지정한다.
        float r = 0.0f;
        if (RandomRotation)
        {
            r = Random.Range(parts[i].degree * 0.3f, parts[i].degree);
        }
        else
        {
            r = parts[i].degree;
        }
        rotateW = rotateW * r *  1.2f;

        //4. 오브젝트 로테이션 저장
        changeRotates[i] = rotateW;
    }
}

 

설명

- rotateW는 각 파츠들의 회전값을 지정하며, 이 값은 ChangeRotate[i]에 저장되어 움직임을 줄 때 사용한다.

- 극단적인 회전으로 기괴함을 표현하기 위하여 Random한 값으로 X Y Z 중 한 곳에 가중치를 치중하여 극단적인 회전 값을 지정해 주었다.