안녕하세요 이번 시간에는 저번 시간에 이어서 진행됩니다.

 

먼저 이번 시간을 통해 할 수 있는 것 들을 보여드리겠습니다.

 

 

위의 이미지에서 물뿌리개를 사용해 물을 주는 애니메이션과 비료통을 흔들어 비료를 주는 애니메이션을 

확인할 수 있습니다.

 

 

이번에는 목표지점으로 이동하기

 

위 xyz 화살표는 도착지라는 객체로 해당 지점으로 npc가 이동하게 됩니다. 

 

 

저번 시간에 만들었던 LookAtPlayer에 변화가 있습니다.

 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class LookAtPlayer : MonoBehaviour
{
    // 밑의 변수로 플레이어가 근처에 있는지 알 수 있다.
    public static int player_in;
    public static bool off_panel;
    // 유니티 인스펙터 창에서 패널을 넣어주자
    public GameObject Intro_panel;
 
    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Player" && farmer_animator.IsMove == false)
        {
            player_in = 1;
            Intro_panel.SetActive(true);
        }
    }
    private void OnTriggerStay(Collider other)
    {
        if (other.tag == "Player" && farmer_animator.IsMove == false)
        {
            // 플레이어를 바라보게 만든다
            transform.LookAt(other.transform);
            Intro_panel.SetActive(true);
 
        }
        else
        {
            Intro_panel.SetActive(false);
        }
 
    }
    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "Player")
        {
            player_in = 0;
            Intro_panel.SetActive(false);
        }
    }
 
    
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

IsMove라는 bool 변수가 트리거의 조건에 추가되었습니다.

위의 변수는 NPC농부가 이동할 때  TRUE가 되는 값입니다.

NPC가 이동 중에는 플레이어에 반응 하지 않도록 하였습니다.

 

NPC의 이동을 보여드리겠습니다.

 

이동하는 모습을 보면 방향 커서를 따라 이동하는 것을 볼 수 있습니다.

커서는 empty object로 태그를 target이라고 정했습니다.

 

 

움짤을 만들어서 올리니 생각난게 npc에 새로운 애니메이션을 추가한 게 있습니다.

따라서 모델을 다시 한번더 올리도록 하겠습니다.

 

farmer_02.fbx
0.44MB

추가된 애니메이션으로는 뛰기, 비료주기, 삽질하기, 물 주기입니다.

 

비료 통이나, 삽 같은 오브젝트도 같이 사용해보려 해 보았지만

시간만 날렸네요 ㅠㅠ 유니티에 따로 추가하도록 하겠습니다.

 

비료주기 

 

 

 

밑의 코드는 automove라는 코드입니다. 

영어 뜻 그대로 자동 움직임이라는 뜻인데

도착지를 정하면 도착지로 이동하는 코드입니다.

farmer_animator라는 스크립트에 있는 변수를 사용하고 있어서

밑의 스크립트를 먼저 만들게 되면 오류가 생기게 될 수 있습니다.

지금은 무시하셔도 됩니다.

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
65
66
67
68
69
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class automove : MonoBehaviour
{
    public GameObject target;
 
    public GameObject Fertilize_box;
    public GameObject Water_box;
    public GameObject Shovel;
 
    // Start is called before the first frame update
    void Start()
    {
        
    }
 
    // Update is called once per frame
    void Update()
    {
        MoveToTarget();
        showing_Fertilize_Box();
        showing_Water_box();
    }
 
    void MoveToTarget()
    {
        if (target.transform.position != Vector3.MoveTowards(transform.position, target.transform.position, 1f))
        {
            transform.position = Vector3.MoveTowards(transform.position, target.transform.position, 1f); // 현위치, 도착점, 속도
 
            transform.LookAt(target.transform);
       
        }
        else
            farmer_animator.IsMove = false;
    }
 
    void showing_Fertilize_Box()
    {
        if (farmer_animator.Fertilize_on == true && Fertilize_box != null)
        {
            if (Fertilize_box.activeSelf == false)
                Fertilize_box.SetActive(true);
        }
        else
        {
            Fertilize_box.SetActive(false);
        }
    }
 
    void showing_Water_box()
    {
        if (farmer_animator.Water_on == true && Water_box != null)
        {
            if (Water_box.activeSelf == false)
                Water_box.SetActive(true);
        }
        else
        {
            Water_box.SetActive(false);
        }
    }
 
}
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs
 

우선 automove스크립트의 핵심 메서드 MoveToTarget에 대해 설명하겠습니다.

MoveToTarget은 영어 뜻 그대로 목표지점으로 이동하라는 메서드입니다.

핵심 코드를 살펴보겠습니다. 

 

transform.position = 

Vector3.MoveTowards(transform.position, target.transform.position, 1f); 

// 현 위치, 도착점, 속도

 

MoveTowards라는 내장 함수는 매개변수 값으로 받은 속도 값으로 도착점을 향해

지정된 오브젝트를 이동시킵니다.

그리고 밑에 LookAt은 npc가 이동할 때 목표점을 바라보며 이동할 수 있도록 해주기

위해서 추가되었습니다.

 

 

showing_Fertilize_box는 아까 비료주기 애니메이션에서 비료통이

없던걸 보셨습니다. 위의 함수는  

green_box라는 비료통을 애니메이션 실행에 맞추어

보여주는 함수입니다.

showing_Water_box()는 물뿌리개를 보여주는 함수입니다.

automove 스크립트는 farmer_controller에 추가해주세요

스크립트 설명은 여기까지 하고, 히어라키 창에 엠티 오브젝트를 생성하여서

목표점으로 사용하고 실행해서 되는지 안되는지 확인해주세요

 

green_box.fbx는 비료통입니다.  혹시 구현해볼 분은 사용해주세요

 

green_box.fbx
0.03MB

 

모델 안에 라이트랑 카메라가 포함돼있는데, 제거해주시면 됩니다.

 

<애니메이션 넣기>

 

 

이번엔 애니메이션을 넣도록 하겠습니다.

 

위의 이미지처럼 npc 모델 객체 자식으로 green_box와 water_can을 넣어주세요

water_can은 물뿌리개입니다. 물뿌리개는 없으면 큐브로 대체합니다.

 

애니메이션이 새로 추가되었기 때문에 새로운 모델을 사용해야 합니다.

기존 모델을 삭제하고 저번 시간에 했던 것처럼 Idle 애니메이션 까지는

이전 글을 참조해주세요

 

 

 

애니메이터에 애니메이션을 삽입하는 방법은 

프로젝트 창에서 모델 오른쪽 플레이 버튼을 클릭하여

모델을 펼치면 모델 구성 요소를 볼 수 있습니다.

거기서 애니메이션을 애니메이터에 드래그엔 드롭하시면 됩니다.

 

이번에는 애니메이터에 파라미터를 추가합니다.

 

 

애니메이터 좌측에 보면 파라미터를 추가할 수 있는 공간이

있습니다. 위의 이미지처럼 IsMove,..., Water_on을 bool 타입으로 추가해주세요

 

 

위의 이미지처럼 Armature|run 과 Idle 애니메이션 사이에 있는

화살표를 만들어 주세요 Idle 우클릭하면 make Transaction으로 추가 가능합니다.

다음으로 화살표를 더블클릭합니다.

인스펙터 창에 위와 같이 나타납니다.

Has Exit Time 체크를 해제합니다.

해제하는 이유는 체크돼있을 경우 실행되고 있는 애니메이션이 종료돼야

다음 애니메이션을 진행하게 됩니다.

예를 들어 목표점으로 이동하기 위해 뛰기 애니메이션을 실행해야 하는데

숨시기 애니메이션이 끝나지 않았으므로 끝날 때까지 기다린 후 

뛰기 애니메이션이 실행되게 됩니다. 그러면 npc가 이동 중인데

뛰지 않는 현상이 발생할 수도 있습니다.

has exit time 아래에 보면 조건을 지정할 수 있습니다.

Idle -> run 일 때는 IsMove값을 true

Idle <- run 일 때는 IsMove값을 false

넣어주시기 바랍니다.

마찬가지로

각 애니메이션에 화살표에도 이름에 해당하는 조건을 false로 지정해주세요

 

이제 run 애니메이션을 실행할 준비가 되었으니 밑의 코드를 통해서

애니메이션이 실행될 수 있도록 하겠습니다.

아래의 코드는 애니메이션을 수행하는 모델에 넣어주시기 바랍니다.

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 System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class farmer_animator : MonoBehaviour
{
    Animator animator;
    public static bool IsMove = false;
    public static bool Fertilize_on = false;
    public static bool Water_on = false;
    public static bool Shovel_on = false;
 
 
    // Use this for initialization
    void Start()
    {
        animator = GetComponent<Animator>();
    }
 
    // Update is called once per frame
    void Update()
    {
        animator.SetBool("IsMove", IsMove);
        animator.SetBool("Fertilize_on", Fertilize_on);
        animator.SetBool("Water_on", Water_on);
        animator.SetBool("Shovel_on", Shovel_on);
 
        PlayAnimation();
    }
 
    void PlayAnimation()
    {
        if (IsMove == false && Fertilize_on == false && Water_on == false && Shovel_on == false)
        {
            if (Input.GetKeyDown(KeyCode.X))
            {
                animator.Play("Armature|Fertilize"-10);
                Fertilize_on = true;
            }
            else if (Input.GetKeyDown(KeyCode.Z))
            {
                animator.Play("Armature|water"-10);
                Water_on = true;
            }
        }
    }
 
    public void invisible_Fertilize_box()
    {
        if (Fertilize_on)
        {
            Fertilize_on = false;
        }
    }
    public void invisible_Water_box()
    {
        if (Water_on)
        {
            Water_on = false;
        }
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

        animator.SetBool("IsMove", IsMove);

        animator.SetBool("Fertilize_on", Fertilize_on);

        animator.SetBool("Water_on", Water_on);

        animator.SetBool("Shovel_on", Shovel_on);

위의 코드는 아까 애니메이터에서 생성했던 파라미터의 값에 접근하게 해 줍니다.

 

여기서 run 애니메이션이 실행되는 원리를 말하자면 

automove 스크립트의 메서드인 MoveToTarget()에서 

이동시에 IsMove 값에 true를 넣게 됩니다. 그렇게 되면 

뛰기 애니메이션이 바로 실행 되게 됩니다.

목표점에 도달하거나 가만히 있게 되면 IsMove값에 false를 넣어 다시

숨쉬기 애니메이션으로 돌아오게 됩니다. 

 

다음으로, 메서드별로 설명을 하겠습니다.

첫 번째 메소드 PlayAnimation()은 실행되고 있는 애니메이션이 없을 때

애니메이션을 실행시키도록 하는 메서드입니다.

플레이어가 x를 눌렀을 때 실행되는 코드를 살펴보면

 animator.Play("Armature|Fertilize"-10);

이것은 

Armature|Fertilize라는 애니메이션을 실행하게 도와주는 메서드입니다.

 Fertilize_on = true; 이 코드를 실행시키면

비료 통이 보이게 됩니다.

그렇게 되면 비료주기 애니메이션이 실행되면서 비료통이 보이게 됩니다.

 

그다음에는

public void invisible_Fertilize_box() 라는 메서드가 있습니다.

밑의 애니메이션은 이제 비료주기 애니메이션이 끝났을 때

박스를 다시 안 보이는 상태로 변환하기 위해서 사용됩니다.

애니메이션이 끝났을 때 사용하기 위해서 콜백 메서드 형식으로 사용하게 됩니다.

 

<애니메이션에 특정 시점에 실행될 메소드 넣기>

다시 애니메이터로 돌아옵니다.

 

위의 버튼 Fertilize를 더블클릭하면

아래의 창이 나타납니다.

 

여기서 아래쪽으로 드래그합니다.

 

이벤트라는 항목이 있습니다.

펼쳐주고

위의 이모티콘을 눌러줍니다.

그러면 시간 줄에 커서 같은 게 생기는데 가장 오른쪽으로 당겨 둡니다.

그렇게 되면 애니메이션 종료 시점에서 이벤트가 실행되게 됩니다.

이번에는 function에다가 위의 이미지 함수 명처럼 넣어주세요

Float, Int, String은 매개변수가 있을 경우 사용합니다. 우리는 없으니 사용하지 않습니다.

이번에는 Object에다가 해당 메서드가 있는 스크립트를 넣습니다.

여기서 주의할 점은 스크립트가 애니메이션을 실행하는 모델에 속해있지

않으면 오류가 발생할 수 있습니다. 고로 해당 스크립트는 모델에 속해있어야 합니다.

이제 apply 버튼을 눌러 적용하면 됩니다.

invisible_Water_box()함수 또한 위처럼 적용해주시면 됩니다.

 

<비료통 & 물뿌리개 움직임 넣는 코드>

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class autoRotation : MonoBehaviour
{
 
    int i = 0;
    float x, y, z;
    // Start is called before the first frame update
    void Start()
    {
        x = transform.rotation.x;
        y = transform.rotation.y;
        z = transform.rotation.z;
    }
 
    // Update is called once per frame
    void Update()
    {
        if (i % 14 >= 7)
            transform.Rotate(00-4);
        else
            transform.Rotate(004);
        i++;
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

위의 코드를 비료통과, 물뿌리개에 적용 시켜주면 비료통과 물뿌리개가 움직이게 됩니다.

 

이제 모든 것이 완료되면

 

이렇게 됩니다.

+ Recent posts