반응형

2D 네비게이션 기본 사용법

 

2D 네비게이션을 사용하기 위해 세팅한다.

● NavigationRegion2D - Navigation Polygon을 생성하고 NavigationAgent2D가 이동 가능한 공간을 적당히 그린다.

● CharacterBody2D - 스크립트를 생성한다.

   Sprite2D - 스프라이트 사이즈를 적당히 조절한다.

   CollisionShape2D - 스프라이트 사이즈에 맞게 적당히 조절한다.

   NavigationAgent2D - Debug - Enabled - On 체크한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Godot;
 
public partial class Nav : CharacterBody2D
{
    public float movement_speed = 300.0f;
    public Vector2 movement_target_position = new Vector2(950500);
    public NavigationAgent2D navigation_agent;
 
    public override void _Ready()
    {
        navigation_agent = GetNode<NavigationAgent2D>("NavigationAgent2D");
 
        // These values need to be adjusted for the actor's speed
        // and the navigation layout.
        navigation_agent.PathDesiredDistance = 4.0f;
        navigation_agent.TargetDesiredDistance = 4.0f;
 
        // Make sure to not await during _ready.
        CallDeferred("actor_setup");
        // Calls the method on the object during idle time. Always returns null,
        // not the method's result.
    }
 
    public async void actor_setup()
    {
        // Wait for the first physics frame so the NavigationServer can sync.
        // On the first frame the NavigationServer map has not synchronized region
        // data and any path query will return empty. Await one frame to pause
        // scripts until the NavigationServer had time to sync.
        
        //await ToSignal(GetTree(), "physics_frame");
        await ToSignal(GetTree(), SceneTree.SignalName.PhysicsFrame);        
        // physics_frame
        // Emitted immediately before Node._physics_process is called on every node
        // in the SceneTree.
 
        // Now that the navigation map is no longer empty, set the movement target.
        set_movement_target(movement_target_position);
    }
 
    public void set_movement_target(Vector2 movement_target)
    {
        navigation_agent.TargetPosition = movement_target;
    }
 
    public override void _PhysicsProcess(double delta)
    {        
        if (navigation_agent.IsNavigationFinished())
        {
            return;
        }
 
        //Vector2 current_agent_position = GlobalPosition;
        //Vector2 next_path_position = navigation_agent.GetNextPathPosition();
        //Vector2 new_velocity = next_path_position - current_agent_position;
        Vector2 new_velocity = ToLocal(navigation_agent.GetNextPathPosition());
 
        new_velocity = new_velocity.Normalized();
        new_velocity = new_velocity * movement_speed;
 
        Velocity = new_velocity;
        MoveAndSlide();
    }
}
 

 

 

CharacterBody2D에 추가한 스크립트에 2D 네비게이션 사용 코드를 작성한다.

movement_target_position은 목표 지점을 적당히 지정한다.

 

목표지점까지 캐릭터가 진행하는 경로가 표시되며 이동한다.

 

이번엔 마우스 포인터를 따라가도록 해 보자.

 

Navigation Polygon을 수정한다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using Godot;
 
public partial class Nav : CharacterBody2D
{
    public float movement_speed = 200.0f;
    public NavigationAgent2D navigation_agent;
 
    public override void _Ready()
    {
        navigation_agent = GetNode<NavigationAgent2D>("NavigationAgent2D");
 
        navigation_agent.PathDesiredDistance = 4.0f;
        navigation_agent.TargetDesiredDistance = 4.0f;
    }
 
    public override void _Process(double delta)
    {
        navigation_agent.TargetPosition = GetGlobalMousePosition();
    }
 
    public override void _PhysicsProcess(double delta)
    {
        if (navigation_agent.IsNavigationFinished())
        {
            return;
        }
 
        Vector2 new_velocity = ToLocal(navigation_agent.GetNextPathPosition());
        new_velocity = new_velocity.Normalized();
        new_velocity = new_velocity * movement_speed;
 
        Velocity = new_velocity;
 
        MoveAndSlide();
    }
}
 

 

 

마우스 포인터를 따라가는 코드를 작성한다.

 

Navigation Polygon 내에서 마우스를 따라 움직인다.

 

이번엔 타일맵을 이용해 맵을 만들고 길을 찾아보자.

Tile-Sets (64-64).png
0.01MB

 

NavigationRegion2D를 삭제하고 TileMap을 추가해 위와 같이 맵을 만든다.

TileMap에 Physics Layer와 Navigation Layer를 하나씩 추가한다. 각 타일의 설정은 아래 내용을 참고한다.

 

여러 타일 중 두 가지만(벽과 길) 사용해 맵을 만들어 보자. 벽으로 사용할 타일에 Physics(Collision) Polygon을 생성한다.

 

 

길로 사용할 타일에 Navigation Polygon을 생성한다.

 

CharacterBody2D의 설정도 바꿔야 한다.

● Motion Mode - Floating

● Wall Min Slide Angle - 0

● 자식노드의 CollisionShape2D - Shape이 사각형이라면 원으로 바꾼다.

이렇게 변경하지 않으면 캐릭터가 이동 중 모서리에 걸려 움직이지 못하는 경우가 발생한다.

스크립트는 변경할 필요 없다.

 

게임을 실행하면 마우스를 따라 캐릭터가 길을 찾고 이동한다.

 

※ 참고

2D Navigation Overview

Using NavigationAgents

 

반응형
Posted by J-sean
: