반응형

 

 

 

 

인벤토리 구현하는 중에 Toggle과 ToggleGroup을 사용하던 중, 인벤토리를 껐다켜면 첫번째 토글이 무조건 활성화되게 하려고 OnEnable함수에서 toggle.isOn의 값을 변경했는데, onValueChanged와 같은 콜백은 호출이 되지만 ToggleGroup이 작동을하지 않아서 첫번째 토글이 활성화되지 않았다.

찾아보니 Toggle의 OnDisable에서 ToggleGroup에 등록된 자신을 해제한다고한다. (대체 왜..?)

 

즉, 각 Toggle 컴포넌트가 비활성화되면 ToggleGroup에서 자신을 해제하고 활성화되면 재등록이 이루어지는것 같다.

(ToggleGroup에서 OnEnable함수에 m_Toggles.Count의 로그를 찍어보면 0으로 나온다.)

 

결국 ToggleGroup하고 Toggle을 상속받는 새 컴포넌트를 만들어 Toggle의 OnDisable을 override로 재정의해줘서 해결했다.

 

 

Toggle 컴포넌트

using UnityEngine.UI;

public class SlotToggle : Toggle
{
    protected override void OnDisable() { }
}

 

 

ToggleGroup 컴포넌트

using UnityEngine.UI;

public class InventoryToggleGroup : ToggleGroup
{
    protected override void OnEnable()
    {
        var toggle = GetFirstToggle();
        if (toggle != null)
        {
            toggle.isOn = true;
        }
    }

    private Toggle GetFirstToggle()
    {
	if(m_Toggles.Count <= 0)
        {
            return null;
        }
        
        Toggle toggle = m_Toggles[0];
        for(int i = 1; i < m_Toggles.Count; i++)
        {
            if(toggle.transform.GetSiblingIndex() > m_Toggles[i].transform.GetSiblingIndex())
            {
                toggle = m_Toggles[i];
            }
        }

        return toggle;
    }
    
    protected override void OnDisable()
    {
        base.OnDisable();
        for (int i = 0; i < m_Toggles.Count; i++)
        {
            m_Toggles[i].isOn = false;
        }
    }
}
  • GetSiblingIndex의 값을 비교해서 첫번째 Toggle 컴포넌트를 가져온다. (한번씩 Toggle 순서가 뒤섞이는 문제가 발생해서 함수를 추가로 작성했다. 꼭 저렇게할 필요 없이 Sort()함수를 사용해도 무관할듯하다.)
  • OnDisable()에서 게임오브젝트가 비활성화 될 때, 모든 토글의 isOn을 꺼주는 이유는 다시 활성화될 때 특정 토글의 isOn이 켜져있으면 활성화될 때 켜주고싶은 토글의 isOn이 인스펙터창에서 활성화되지 않아 Graphic의 표시가 변경되지 않는다. (OnValueChanged 콜백만 호출됨)

 

 

 

 

반응형
반응형

 

 

 

 

에셋을 받아 작업하면서 어느순간 An error occurred while resolving packages에러를 발견하게 됐다.

(해당 에러는 Terrain sample asset pack에서 발생하는걸로 확인)

처음에는 크게 신경 안써도 되는줄 알았는데 지워지지 않는 에러라서 그때 제대로 확인했다. 확인해보니 visualgraph 패키지의 버전을 찾을수 없다는 내용이어서 패키지 매니저로 들어가서 해결했다.

 

 

 

해결방법

  • Window - Package Manager 창에서 Unity Registry를 선택해서 에러가 난 패키지를 검색해준다.

  • 여기서 문제가 있는 패키지는 ✔표시 대신 ❗표시가 되어있을건데, Update를 하거나 Remove한다음 재설치를 하면 해결된다.

※ 대부분 위의 방법으로 해결이 되는거같은데, 그래도 안되면 manifast.json에 공백이 있어서 생기는 문제거나 캐시파일 문제라고 한다.

 

 

 

 

 

반응형
반응형

 

 

 

 

NavMeshAgent에 Angular Speed를 아무리 높게 줘도 회전이 늦게 일어난다. (해당 프로퍼티가 초당 회전각도로 알고있는데 아무리 수치를 높여도 회전이 느림)

위와 같이 회전이 몬스터 같은 유닛의 경우 어색할 가능성이 다분하다.

그래서 NavMeshAgent.updateRotation의 값을 false로 설정해준 뒤, 직접 각을 계산해서 넣어줘야한다.

 

 

 

공통

private NavMeshAgent m_agent;

void Start()
{
    m_agent = GetComponent<NavMeshAgent>();
    m_agent.updateRotation = false;
}

 

 

 

 

1. NavMeshAgent의 DesireVelocity값을 이용해 회전값 조정

- NavMeshAgent.DesireVelocity - 회피를 고려한 목표 속도

- Qaternion.LookRotation을 이용해서 회전값을 적용해주면 된다.

void Update()
{
    transform.rotation = Quaternion.LookRotation(m_agent.desireVelocity);
}

 

 

- 결과

그런데 한가지 문제가 있다면 커브길 주변에서 유닛이 떨리는 현상이 발견된다. (실제로 적용해보면 심각할정도로 떨린다.)

 

 

 

2. 직접 각을 계산해서 적용하기

- NavMeshAgent.steeringTarget값을 이용해 회전 값을 계산해서 적용하기

void Update()
{
    Vector2 forward = new Vector2(transform.position.z, transform.position.x);
    Vector2 steeringTarget = new Vector2(m_agent.steeringTarget.z, m_agent.steeringTarget.x);
    
    //방향을 구한 뒤, 역함수로 각을 구한다.
    Vector2 dir = steeringTarget - forward;
    float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    
    //방향 적용
    transform.eulerAngles = Vector3.up * angle;
}

※ 3차원 공간에서는 전진 방향이 z축이니 Vector2의 x값을 transform.position.z값으로 설정한다.

※ steeringTarget : 경로상의 다음 목적지.

 

- 결과

1번과 다르게 떨리는 현상 없이 바로 회전하는것을 볼 수 있다.

 

 

 

 

 

반응형
반응형

 

 

 

 

Navigation Bake (Baked Agent)

  • Agent Radius : Agent의 반지름, Agent와 벽까지의 거리이다. 해당 반지름의 길이만큼 Agent가 벽에 붙어서 움직일 수 있다.
  • Agent Height : Agent의 높이, Agent의 높이를 지정해서 천장이 있는 지형의 통과 여부를 결정한다.
  • Max Slope : 이동 가능한 경사도
  • Step Height : 이동 가능한 단차의 한계 값, 설정한 수치만큼의 단차를 이동 할 수 있다.

※ Agent Height에 따른 네비메쉬 차이

 

 

NavMeshAgent Component

- A* PathFinding 알고리즘을 사용하여 길을 탐색한다.

- Bake된 네비메쉬의 정보를 바탕으로 목적지까지의 최단거리 이동을 계산하며, Agent간의 충돌을 회피할 수 도 있다.

 

AgentType : Navigation의 Agents 탭에서 지정한 정보

BaseOffset : NavMeshAgent는 Bake된 네비메쉬의 표면에 붙어있기 떄문에 실제 맵 오브젝트로부터 공중으로 살짝 떨어지게 되어있다. 해당 값으로 높이조절이 가능하다.

 

Steering

  • Speed : 최대 이동 속도
  • Angular Speed : 회전 속도(Degree/sec)
  • Acceleration : 최대 가속도
  • Stopping Distance : 목표점에 가까워졌을 때, 설정한 거리에 들어오면 감속
  • Auto Braking : 목적지에 도착하기 직전에 감속을 시작할 것인지 결정

 

Obstacle Avoidance

- 다른 Agent와 Obstacle을 어떻게 회피할 것인지 결정하는 프로퍼티

  • Radius : 지형과 관계없이 다른 Agent나 Obstacle의 충돌하는 영역의 두께가 조절된다.
  • Height : Agent끼리의 높이 충돌을 조절한다.
  • Quality : 회피 품질(None은 회피 무시)
  • Priority : Agent간의 회피 우선 순위, 낮은 수가 높은 우선 순위이며 자신보다 낮은 Agent는 회피 대상에서 제외된다.

 

Path Finding

  • Auto Traverse Off Mesh Link : 분리된 메쉬 간에 자동으로 링크를 생성하는 옵션. Off Mesh Link 컴포넌트를 사용할 시 해당 기능을 비활성화해야한다.
  • Auto Repath : 네비메쉬에 변동이 생기거나 길이 막혔을 때, 재탐색한다.
  • Area Mask : 네비메쉬의 영역별로 이동을 제한할 수 있는 기능

 

 

 

 

 

반응형
반응형

 

 

 

 

VS Code의 터미널을 실행하려했을 때 터미널이 설정되어있지 않으면 '터미널 프로세스를 시작하지 못했습니다'는 에러가 나타나면서 터미널이 실행되지 않는다. 이럴때 다음과 같이 해결한다.

 

- FilePreferencesSetting(단축키 Ctrl,)에서 검색창에 default profile:windows를 검색한다.

 

 

- 여기서 null로 설정되어있을건데 해당 값을 원하는 터미널로 변경해주면 된다.

- 다시 터미널을 실행해보면 다음과 같이 제대로 실행된다.

 

 

 

 

 

반응형

+ Recent posts