GitHub

Unity/Study 2019. 5. 2. 18:18

git?

VCS(Version Control System) 중 하나인 DVCS(Distributed Version Control System)

Working Directory    ->    Index    ->    HEAD

         *add*   *commit*

add를 통해 Index에 추가를하고 commit을 통해 확정

commit하면 HEAD에는 반영됐으나 서버에는 변동X

push를 통하여 HEAD에서 바뀐 값을 서버로 전송

branch(가지치기)

- 격리된 상태에서 개발하기 위함

- 완료 후에 본래의 가지로 돌아와서 병합(merge)

- checkout을 통해 새로운 가지를 만들고,

  새로운 가지에서 작업을 한다.

  완료 후 서버 저장소에 전송하면 타인도 접근가능

merge(갱신과 병합)

- 서버 저장소와 같은 값으로 갱신시 pull이용

- pull 사용시, 서버 저장소의 변경된 값이 로컬에 fetch하고 merge된다.

//merge <가지 이름>으로 가지치기한 가지도 병합이가능

//conflict(충돌)이 일어나는 경우, 해결 후 병합을 하면 됨.

//손머지, 선택 등 머지에는 방법이 많다.

//손머지 같은 경우 손으로 소스코드를 수정하고 bash에서 add를 통하여 추적하게 하고,

//다시 commit을 하면 정상적으로 진행이 된다.

//pull은 서버 저장소의 소스를 로컬로 가져오면서 현재 작업중인 소스들의 merge까지 통합실행

//fetch는 서버 저장소의 소르르 로컬로 가져오기만하고 merge하지않음

'Unity > Study' 카테고리의 다른 글

testgpgs개인정보  (0) 2019.06.13
Animator 이용법 자습  (0) 2019.05.09
3D와 랜더링 파이프라인  (0) 2019.04.19
:

Damage Text 출력하기

C#/수업내용 2019. 4. 25. 18:17


WorldToScreenPoint를 이용하여 캐릭터의 상단에 데미지 텍스트를 출력함


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
70
71
72
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class TestHudText : MonoBehaviour
{
    public Button btn;
    public Button btn2;
    public GameObject pivot;
    public Transform hudPoint;
    public Text txt0; //worldspace point
    public Text txt1; //viewport point
    public Text txt2; //spaceport point
    private Canvas canvas;
 
    private void Awake()
    {
        this.canvas = FindObjectOfType<Canvas>();
    }
 
    private void Start()
    {
        this.btn.onClick.AddListener(() =>
        {
            //프리팹 로드
            var hudPre = Resources.Load<HUDDamageText>("Prefabs/Test/HUDDamageText");
            //인스탄트
            var screenPoint = Camera.main.WorldToScreenPoint(this.hudPoint.position);
            var targetLocalPos = new Vector3(screenPoint.x - Screen.width / 2, screenPoint.y - Screen.height / 2, screenPoint.z);
            this.pivot.GetComponent<RectTransform>().anchoredPosition = targetLocalPos;
            var hud = Instantiate(hudPre);
 
            //인잇 메서드 호출(텍스트랑 컬러)
            Color color = new Color(100);
            hud.Init("456", color);
 
            //부모 Canvas로 설정
            hud.transform.SetParent(this.pivot.transform, false);
 
            //초기화
            hud.transform.localPosition = Vector3.zero;
 
            //타겟 포지션            
            Debug.LogFormat("{0},{1},{2}", targetLocalPos.x, targetLocalPos.y, targetLocalPos.z);
            Debug.LogFormat("{0},{1},{2}", screenPoint.x, screenPoint.y, screenPoint.z);
            var target = new Vector3(01000);
            DOTween.ToAlpha(() => hud.txt.color, x => hud.txt.color = x, 00.5f);
 
            hud.transform.DOScale(new Vector3(222), 0.3f).OnComplete(() =>
            {
                hud.transform.DOScale(new Vector3(111), 0.2f);
            });
            hud.transform.DOLocalMove(target, 1.5f).SetEase(Ease.OutBack).OnComplete(() =>
            {
                Destroy(hud.gameObject);
            });
        });
 
        this.btn2.onClick.AddListener(() =>
        {
            Debug.LogFormat("hudPoint world coordinate : {0}"this.hudPoint.position);
            this.txt0.text = this.hudPoint.position.ToString();
            var viewPortPoint = Camera.main.WorldToViewportPoint(this.hudPoint.position);
            this.txt1.text = viewPortPoint.ToString();
            var screenPoint = Camera.main.WorldToScreenPoint(this.hudPoint.position);
            this.txt2.text = screenPoint.ToString();
        });
    }
}
 
cs


:

Raycast, Collider, Rigidbody, Joystick 이용 캐릭터 이동하기

Unity/수업내용 2019. 4. 25. 18:11

Joystick 이용하여 이동하기



Keyboard(W,A,S,D) 이용하여 이동하기



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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class TestRaycastAndCollider : MonoBehaviour
{
    public Text txtMousePoint;
    public Text txtHitPoint;
    public GameObject heroGo;
    private Animator heroAnim;
    private Coroutine heroRoutine;
    private Coroutine joystickRoutine;
 
    public TestMyJoystick joystick;
 
    private void Awake()
    {
        Debug.Log("TestRaycastAndCollider Awake!");
    }
 
    // Start is called before the first frame update
    void Start()
    {
        this.heroAnim = heroGo.GetComponent<Animator>();
        Debug.Log("TestRaycastAndCollider Start!");
 
        this.joystick.OnPointerDownHandler = () =>
        {
            Debug.Log("다운핸들러");
            if (this.joystickRoutine != null)
            {
                StopCoroutine(this.joystickRoutine);
            }
            StartCoroutine(this.UpdateJoystickImpl());
        };
        this.joystick.OnPointerUpHandler = () =>
        {
            Debug.Log("업핸들러");
            StopAllCoroutines();
            this.heroAnim.Play("idle");
        };
    }
 
    private void UpdateJoystick()
    {
        Vector3 direction = Vector3.forward * this.joystick.Vertical + Vector3.right * joystick.Horizontal;
 
        direction = new Vector3(direction.x, 0, direction.z).normalized;
        if (direction != Vector3.zero)
        {
            this.heroAnim.Play("run");
            this.heroGo.transform.position += direction * 1.0f * Time.deltaTime;
 
            var rad = Mathf.Atan2(direction.x, direction.z);
            var dig = Mathf.Rad2Deg * rad;
            this.heroGo.transform.rotation = Quaternion.LookRotation(direction);
            //this.heroGo.transform.rotation = Quaternion.Euler(new Vector3(0, dig, 0));
 
        }
        else
        {
            this.heroAnim.Play("idle");
        }
    }
 
    private IEnumerator UpdateJoystickImpl()
    {
        while (true)
        {
            Vector3 direction = (Vector3.forward * this.joystick.Vertical + Vector3.right * joystick.Horizontal).normalized;
            if (direction != Vector3.zero)
            {
                this.heroGo.transform.rotation = Quaternion.LookRotation(direction);
                this.heroAnim.Play("run");
                this.heroGo.transform.position += direction * 2.0f * Time.deltaTime;
                yield return null;
            }
            else
            {
                this.heroAnim.Play("idle");
            }
        }
    }
 
    // Update is called once per frame
    private void UpdateKeyInput()
    {
        var keyY = Input.GetAxis("Vertical");
        var keyX = Input.GetAxis("Horizontal");
        Debug.LogFormat("keyY : {0}, keyX : {1}", keyY, keyX);
 
        var moveKey = new Vector3(keyX, 0, keyY).normalized;
        if (moveKey != Vector3.zero)
        {
            this.heroAnim.Play("run");
            this.heroGo.transform.position += moveKey * 1.0f * Time.deltaTime;
            var rad = Mathf.Atan2(keyX, keyY);
            var dig = Mathf.Rad2Deg * rad;
            this.heroGo.transform.rotation = Quaternion.Euler(new Vector3(0, dig, 0));
 
        }
        else
        {
            this.heroAnim.Play("idle");
        }
    }
 
    private void UpdateMouseInput()
    {
        if(Input.GetMouseButton(0))
        {
            //찍은 곳 스크린 좌표 표시
            this.txtMousePoint.text = Input.mousePosition.ToString();
 
            //찍은 곳 Ray생성
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 
            //화면 Ray표시
            Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red, 5f);
 
            RaycastHit hitInfo;
            if(Physics.Raycast(ray.origin, ray.direction, out hitInfo, 1000))
            {
                Debug.LogFormat("hitInfo.point : {0}", hitInfo.point.ToString());
                this.txtHitPoint.text = hitInfo.point.ToString();
                this.Move(hitInfo.point);
            }
            else
            {
                this.txtHitPoint.text = "None";
            }
        }
    }
 
    public void Move(Vector3 targetCoordinate)
    {
        if(this.heroRoutine == null)
        {
            this.heroAnim.Play("run");
        }
        if(this.heroRoutine != null)
        {
            StopAllCoroutines();
        }
        this.heroRoutine = StartCoroutine(this.MoveHero(targetCoordinate, () =>
        {
            this.heroAnim.Play("idle");
        }));
    }
 
    private IEnumerator MoveHero(Vector3 targetCoordinate, System.Action OnCompleteMove)
    {
        this.heroGo.transform.LookAt(targetCoordinate);
        var dir = (targetCoordinate - this.heroGo.transform.position).normalized;
        var speed = dir * 1.0f * Time.deltaTime;
        while(true)
        {
            var distance = Vector3.Distance(targetCoordinate, this.heroGo.transform.position);
            this.heroGo.transform.position += speed;
            if(distance <= 0.01f)
            {
                this.heroGo.transform.position = targetCoordinate;
                break;
            }
            yield return null;
        }
        OnCompleteMove();
    }
}
 
cs


'Unity > 수업내용' 카테고리의 다른 글

Scroll View 동적생성  (0) 2019.05.28
UGUI를 이용해 Scroll View UI 만들기  (0) 2019.05.24
:

3D와 랜더링 파이프라인

Unity/Study 2019. 4. 19. 01:49

1프레임은 1장의 이미지와 같다.

PC는 3D모델을 재생하는데에 수 많은 연산을 통해 2D 이미지를 연속적으로 재생한다.


unity에서 부르는 scene은 object들의 모음으로서, 이 object들은 Polygon(다각형)이고, 이는 Vertex(꼭지점)으로 이루어진다.

내가 현재 공부하면서 사용하는 모델을 보면 모두 Polygon으로 이루어져 있다.


또한 카메라라고 부르는 object는 우리가 모니터를 통해 게임을 플레이할때 랜더링을 하여 출력할 이미지의 범위(?)를 지정하는 것이다.

카메라가 비추는 부분을 랜더링 파이프라인을 통하여 2D 이미지로 변환하여 모니터에 출력해주는 것이다.


카메라가 비추고 있는 부분, 즉 출력할 장면을 하나의 3차원 이미지라고 하자.

그럼 이 3차원 이미지는 여러개의 Polygon으로 이루어져 있고, 이 Polygon들은 Vertex로 이루어져 있다.

이 3차원 이미지의 Vertex들을 모아 Vertex Shader(정점 셰이더)로 보낸다.

Vertex Shader에서는 변환 과정을 맡는다. 

각각의 Polygon들은 각각의 공간(Local Space)에서 자신만의 좌표(Coordinate)를 가지고 있는데, 이 Polygon들을 하나의 공간(Space)에 모은다.

//unity에서 쓰는 local position 값을 world position으로 바꾼다고 생각하면 편할 것 같다.

후에 우리가 출력을 원하는 곳을 가리키는 카메라가 보고 있는 공간(View Space)으로 Polygon들이 위치한다.

사용하는 카메라라는 개념은 현실과 다르기때문에 일정한 구역까지만 표현한다. //게임에서 시야거리 조절하듯이


위처럼 카메라가 위치해 있는 곳 부터 far plane까지만 표현하는 것이다. 위 그림에서 파란 공간을 view volume이라 한다.

후에 원근법을 이용하여 표현하기 위해 Clipping Space로 변환한다. (3차원 -> 3차원)


그 다음 레스터화(resterize)를 한다.

Clipping Space로 변환하고 나면 선에 걸치거나 육면체 바깥으로 벗어난 Polygon들이 있을텐데 이 부분들을 잘라낸다.

이를 Clipping이라 한다.

다음으로 원근 나눗셈이라는 것을 통하여 3차원을 2차원으로 변환한다. (z좌표로 모든 성분을 나누어 3차원 개념을 지움)

그 다음 보이지 않는 Polygon, 즉 필요가 없는 Polygon들을 제거한다.(back-face culling)

그리고 2차원으로 변환된 이미지가 출력될 뷰포트(스크린상의 공간)으로 이전하기 위해 윈도우 좌표로 변환한다.

마지막으로 픽셀 위치, 컬러 등 각 Vertex간 속성을 할당한다.


마지막으로 생성된 pixel들에 조명, 텍스쳐 등 작업을 거쳐 색칠하는 단계를 거친다. (이를 프래그먼트 처리 단계라고 함)




※공부하는 중이기 때문에 사실과는 다를 수 있음

※내가 이해한 내용을 작성하였기 때문에 난잡함

※랜더링 파이프라인은 고정 기능 파이프라인, 프로그래머블 파이프라인이 있다. (Unity에서는 Scriptable Render Pipeline이 있음)

  //https://www.youtube.com/watch?v=eJEwnI8UGe4 (Scriptable Render Pipeline: 알아두어야 하는 사항들 (Unity Korea))

  //https://www.youtube.com/watch?v=zbjkEQMEShM (Unity at GDC - Scriptable Render Pipeline Intro & Lightweight Rendering Pipeline (Unity))





How Rendering Graphics Works in Games! (TheHappieCat)

https://www.youtube.com/watch?v=cvcAjgMUPUA


Game Graphics Pipeline Explained by Tom Petersen of nVidia (Gamers Nexus)

https://www.youtube.com/watch?v=4gyP94hsC14


Understanding the Graphics Pipeline (Oscar Chavez)

https://www.youtube.com/watch?v=0PTBOX1HHIo


Graphics Pipeline 3D Rendering (LearnEveryone)

https://www.youtube.com/watch?v=BUcch9b6cFg


21 - Rendering Pipeline (Shaderdev.com) (Chayan Vinayak)

https://www.youtube.com/watch?v=qHpKfrkpt4c

'Unity > Study' 카테고리의 다른 글

testgpgs개인정보  (0) 2019.06.13
Animator 이용법 자습  (0) 2019.05.09
GitHub  (0) 2019.05.02
:

씬 전환 및 가서 공격하기

Unity/과제 2019. 4. 16. 18:57

App카메라 유지, 코루틴, Json, 익명함수, 이벤트 이용

App->Logo->Title(데이터로딩)->InGame 순으로 씬전환

#문법 공부 많이 해야함




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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
namespace minseok
{
    public partial class App : MonoBehaviour
    {
        public Camera uiCamera;
 
        //인스턴스화 될때
        private void Awake()
        {
            var oper = SceneManager.LoadSceneAsync("Logo");
            oper.completed += (asyncOper) =>
            {
                Debug.Log("logo scene 로드 완료");
                var logo = GameObject.FindObjectOfType<Logo>();
                logo.Init(this.uiCamera);
            };
            DontDestroyOnLoad(this);
        }
    }
}
 
cs

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;
using UnityEngine.SceneManagement;
 
namespace minseok
{
    public class Logo : MonoBehaviour
    {
        public UILogo uiLogo;
 
        public void Init(Camera uiCamera)
        {
            this.uiLogo.onFadeInComplete = () =>
            {
                var oper = SceneManager.LoadSceneAsync("Title");
                oper.completed += (asyncOper) =>
                {
                    Debug.Log("Title scene 로드 완료");
                    var title = GameObject.FindObjectOfType<Title>();
                    title.Init(uiCamera);
                };
                Debug.Log("fade in 완료");
                StopAllCoroutines();
            };
            
            this.uiLogo.onFadeOutComplete = () =>
            {
                Debug.Log("fade out 완료");
                //3초 후 실행
                StartCoroutine(this.WaitForSecond(3, () =>
                {
                    StartCoroutine(this.uiLogo.FadeIn());               
                }));
            };
 
            this.uiLogo.Init(uiCamera);
            StartCoroutine(this.uiLogo.FadeOut()); //1실행
        }
 
        private IEnumerator WaitForSecond(float sec, System.Action onCompleteWait)
        {
            yield return new WaitForSeconds(sec);
            onCompleteWait();
        }
    }
}
cs


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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Newtonsoft.Json;
 
namespace minseok
{
    public class Title : MonoBehaviour
    {
        public UITitle uiTitle;
        public Button btn;
 
        private void Awake()
        {
            this.btn.onClick.AddListener(() =>
            {
                var oper = SceneManager.LoadSceneAsync("InGame");
                oper.completed += (asyncOperation) =>
                {
                    Debug.Log("InGame 씬 로드완료");
                };
            });
        }
 
        public void Init(Camera uiCamera)
        {
            this.DataLoad();
 
            this.uiTitle.onFadeOutComplete = () =>
            {
                Debug.Log("title의 fade in 완료");
                StopCoroutine(this.uiTitle.FadeOut());
            };
 
            this.uiTitle.Init(uiCamera);
            StartCoroutine(this.uiTitle.FadeOut());
        }
 
        private IEnumerator WaitForSecond(float sec, System.Action onCompleteWait)
        {
            yield return new WaitForSeconds(sec);
            onCompleteWait();
        }
 
        private void DataLoad()
        {
            var data = DataManager.GetInstance();
            var textAsset = Resources.Load<TextAsset>("Data/character_data");
            var json = textAsset.text;
            var dataJson = JsonConvert.DeserializeObject<CharacterData[]>(json);
            foreach(var datas in dataJson)
            {
                data.dicCharacterData.Add(datas.id, datas);
            }
 
            textAsset = Resources.Load<TextAsset>("Data/character_anim_data");
            json = textAsset.text;
            var animJson = JsonConvert.DeserializeObject<CharacterAnimData[]>(json);
            foreach(var datas in animJson)
            {
                data.dicCharacterAnim.Add(datas.id, datas);
            }
        }
    }
}
cs


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;
 
namespace minseok
{
    public class InGame : MonoBehaviour
    {
        private Character hero;
        private Character monster;
        private System.Action onCompleteAttack;
 
        private void Start()
        {
            this.hero = this.CreateCharacter(0);
            this.monster = this.CreateCharacter(1);
            this.StartGame();
        }
 
        private void StartGame()
        {
            this.hero.transform.LookAt(this.monster.transform);
            this.monster.transform.LookAt(this.hero.transform);
            this.hero.Move(this.monster, () =>
            {
                this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnim[this.hero.info.id].idle_anim_name);
                this.hero.Attack(this.monster, this.onCompleteAttack);
            });
            this.onCompleteAttack = () =>
            {
                if(this.monster.info.hp > 0)
                {
                    this.hero.Attack(this.monster, this.onCompleteAttack);
                }
                else
                {
                    Debug.LogFormat("{0}를 처치했습니다!", DataManager.GetInstance().dicCharacterData[this.monster.info.id].name);
                    this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnim[this.hero.info.id].idle_anim_name);
                }
            };
        }
 
        private Character CreateCharacter(int id)
        {
            var data = DataManager.GetInstance();
            var charPrefab = Resources.Load<GameObject>("Prefabs/Character");
            var charGo = GameObject.Instantiate<GameObject>(charPrefab);
            var modelPrefab = Resources.Load<GameObject>(data.dicCharacterData[id].prefab_name);
            var modelGo = GameObject.Instantiate<GameObject>(modelPrefab);
            var character = charGo.AddComponent<Character>();
            
            character.Model = modelGo;
            character.name = data.dicCharacterData[id].name;
            character.info = new CharacterInfo(id, data.dicCharacterData[id].hp, new Vector3(000));
 
            if(character.info.id == 1)
            {
                character.transform.position = new Vector3(505);
            }
            else
            {
                character.transform.position = character.info.position;
            }
 
            Debug.Log("캐릭터가 생성되었습니다.");
            return character;
        }
    }
}
cs


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;
 
namespace minseok
{
    public class DataManager
    {
        private static DataManager instance;
        public Dictionary<int, CharacterData> dicCharacterData = new Dictionary<int, CharacterData>();
        public Dictionary<int, CharacterAnimData> dicCharacterAnim = new Dictionary<int, CharacterAnimData>();
 
        private DataManager()
        {
 
        }
 
        public static DataManager GetInstance()
        {
            if(DataManager.instance == null)
            {
                DataManager.instance = new DataManager();
            }
            return DataManager.instance;
        }
    }
}
 
cs


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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
namespace minseok
{
    public class UIBase : MonoBehaviour
    {
        public Canvas canvas;
        public Image dim;
        public System.Action onFadeOutComplete;
        public System.Action onFadeInComplete;
 
        public virtual void Init(Camera uiCamera)
        {
            this.canvas.worldCamera = uiCamera;
        }
 
        public IEnumerator FadeOut()
        {
            var color = this.dim.color;
            color.a = 1;
            this.dim.color = color;
 
            float alpha = color.a;
            while (true)
            {
                alpha -= 0.016f;
                color.a = alpha;
                this.dim.color = color;
                if (alpha <= 0)
                {
                    alpha = 0f;
                    break;
                }
                yield return null;
            }
            this.onFadeOutComplete();
        }
 
        public IEnumerator FadeIn()
        {
            Debug.Log("fadein호출");
            var color = this.dim.color;
            color.a = 0;
            this.dim.color = color;
 
            float alpha = color.a;
            while (true)
            {
                alpha += 0.016f;
                color.a = alpha;
                this.dim.color = color;
                if (alpha >= 1)
                {
                    alpha = 1f;
                    break;
                }
                yield return null;
            }
            this.onFadeInComplete();
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
namespace minseok
{
    public class UILogo : UIBase
    {
        public override void Init(Camera uiCamera)
        {
            base.Init(uiCamera);
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace minseok
{
    public class UITitle : UIBase
    {
        public override void Init(Camera uiCamera)
        {
            base.Init(uiCamera);
        }
    }
}
 
cs


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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace minseok
{
    public class Character : MonoBehaviour
    {
        private Coroutine routine;
        public CharacterInfo info;
        public Animation anim;
        public GameObject model;
        public GameObject Model
        {
            get
            {
                return this.Model;
            }
            set
            {
                this.model = value;
                this.model.transform.SetParent(this.transform);
                this.anim = this.model.GetComponent<Animation>();
            }
        }
        
        public Character(CharacterInfo info, GameObject model)
        {
            this.info = info;
            this.Model = model;
        }
 
        public void Move(Character target, System.Action onCompleteMove)
        {
            StartCoroutine(this.MoveImpl(target, onCompleteMove));
            StopCoroutine(this.MoveImpl(target, onCompleteMove));
        }
        private IEnumerator MoveImpl(Character target, System.Action onCompleteMove)
        {
            Debug.Log("걸어간다");
            var data = DataManager.GetInstance();
            this.anim.Play(data.dicCharacterAnim[this.info.id].run_anim_name);
            var normVector = (target.transform.position - this.transform.position).normalized;
            var speed = normVector * 1.0f * Time.deltaTime;
            while(true)
            {
                var distance = Vector3.Distance(target.transform.position, this.transform.position);
                this.transform.position += speed;
                if(distance <= data.dicCharacterData[this.info.id].attack_range)
                {
                    break;
                }
                yield return null;
            }
            onCompleteMove();
        }
 
        public void Attack(Character target, System.Action onCompleteAttack)
        {
            if (this.routine != null)
            {
                StopCoroutine(this.routine);
            }
            this.routine = StartCoroutine(this.AttackImpl(target, onCompleteAttack));
        }
        private IEnumerator AttackImpl(Character target, System.Action onCompleteAttack)
        {
            Debug.Log("공격한다");
            var data = DataManager.GetInstance();
            this.anim.Play(data.dicCharacterAnim[this.info.id].attack_anim_name);
            yield return new WaitForSeconds(0.26f);
 
            Debug.LogFormat("{0}에게 {1}의 데미지를 입혔습니다!", data.dicCharacterData[target.info.id].name, data.dicCharacterData[this.info.id].damage);
            target.TakeDamage(data.dicCharacterData[this.info.id].damage);
            yield return new WaitForSeconds(0.86f);
 
            onCompleteAttack();
        }
 
        public void TakeDamage(int damage)
        {
            this.info.hp -= damage;
            if(this.info.hp <= 0)
            {
                this.anim.Play(DataManager.GetInstance().dicCharacterAnim[this.info.id].die_anim_name);
            }
        }
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace minseok
{
    public class CharacterAnimData
    {
        public int id;
        public string attack_anim_name;
        public string damage_anim_name;
        public string idle_anim_name;
        public string run_anim_name;
        public string die_anim_name;
    }
 
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace minseok
{
    public class CharacterData
    {
        public int id;
        public string prefab_name;
        public string name;
        public int hp;
        public int damage;
        public float attack_range;
    }
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace minseok
{
    public class CharacterInfo
    {
        public int id;
        public int hp;
        public Vector3 position;
 
        public CharacterInfo(int id, int hp, Vector3 position)
        {
            this.id = id;
            this.hp = hp;
            this.position = position;
        }
    }
}
 
cs


'Unity > 과제' 카테고리의 다른 글

Isometric, 클릭시 좌표 출력하기  (0) 2019.05.13
2D Running Game 기본 시스템 만들기  (0) 2019.05.09
왔다갔다 때리기  (0) 2019.04.16
0  (0) 2019.04.11
:

왔다갔다 때리기

Unity/과제 2019. 4. 16. 08:46
코루틴은 사용 후 항상 stop할 것

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public partial class App : MonoBehaviour
{
    private eSceneType sceneType;
 
    private void Awake()
    {
        this.sceneType = eSceneType.None;
        Object.DontDestroyOnLoad(this);
    }
 
    // Start is called before the first frame update
    void Start()
    {
        this.LoadScene(eSceneType.Logo);
    }
 
    private void LoadScene(eSceneType sceneType)
    {
        AsyncOperation asyncOperation = null;
        if(this.sceneType != sceneType)
        {
            this.sceneType = sceneType;
            asyncOperation = SceneManager.LoadSceneAsync((int)sceneType);
            asyncOperation.completed += (ao) =>
            {
                switch (this.sceneType)
                {
                    case eSceneType.Logo:
                        {
                            this.LoadScene(eSceneType.Title);
                        }
                        break;
                    case eSceneType.Title:
                        {
                            this.LoadScene(eSceneType.DataLoad);
                        }
                        break;
                    case eSceneType.DataLoad:
                        {
                            this.LoadScene(eSceneType.InGame);
                        }
                        break;
                    case eSceneType.InGame:
                        {
                            var inGame = GameObject.FindObjectOfType<InGame>();
                            inGame.Init();
                        }
                        break;
                }
            };
 
        }
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public partial class App : MonoBehaviour
{
    public enum eSceneType
    {
        None = -1,
        App = 0,
        Logo = 1,
        Title = 2,
        DataLoad = 3,
        InGame = 4
    }
}
cs



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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Character : MonoBehaviour
{
    public CharacterInfo info;
    public Animation anim;
    private GameObject model;
    public GameObject Model
    {
        get
        {
            return this.model;
        }
        set
        {
            this.model = value;
            this.model.transform.SetParent(this.transform);
            this.anim = this.model.GetComponent<Animation>();
        }
    }
    public System.Action OnAttackComplete;
    private Coroutine routine;
 
    //생성자
    public Character(CharacterInfo info)
    {
        this.info = info;
    }
 
    //이동메서드
    public void Move(Vector3 targetPosition, System.Action onCompleteMove)
    {
        Debug.Log("Move호출");
        if(routine != null)
        {
            StopCoroutine(this.routine);
        }
        this.routine = StartCoroutine(this.MoveImpl(targetPosition, onCompleteMove));
    }
 
    //이동코루틴
    private IEnumerator MoveImpl(Vector3 targetPosition, System.Action onCompleteMove)
    {
 
        Debug.Log("moveImpl 호출");
        this.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.info.id].run_anim_name);
        var normVector = (targetPosition - this.transform.position).normalized;
        var speed = 1.0f;
        var moveVector = normVector * speed * Time.deltaTime;
        while(true)
        {
            this.transform.position += moveVector;
            var distance = Vector3.Distance(targetPosition, this.transform.position);
            if(distance <= 0.5f)
            {
                break;
            }
            yield return null;
        }
        onCompleteMove();
    }
 
    //공격메서드
    public void Attack(Character target)
    {
        Debug.Log("Attack 호출");
        if (routine != null)
        {
            StopCoroutine(this.routine);
        }
 
        this.routine = StartCoroutine(this.AttackImpl(target));
    }
 
    //공격코루틴
    private IEnumerator AttackImpl(Character target)
    {
        Debug.Log("attackImpl 호출");
        var attackAnimName = DataManager.GetInstance().dicCharacterAnimData[this.info.id].attack_anim_name;
        this.anim.Play(attackAnimName);
        yield return new WaitForSeconds(0.26f);
 
        Debug.LogFormat("{0}에게 {1}의 데미지를 입혔습니다!", DataManager.GetInstance().dicCharacterData[target.info.id].name, DataManager.GetInstance().dicCharacterData[this.info.id].damage);
        target.GetDamage(DataManager.GetInstance().dicCharacterData[this.info.id].damage);
        yield return new WaitForSeconds(0.46f);
        
        this.OnAttackComplete();
    }
 
    //피해메서드
    public void GetDamage(int damage)
    {
        this.info.hp -= damage;
        if (this.info.hp <= 0)
        {
            this.gameObject.GetComponentInChildren<Animation>().Play(DataManager.GetInstance().dicCharacterAnimData[this.info.id].die_anim_name);
        }
        else
        {
            this.gameObject.GetComponentInChildren<Animation>().Play(DataManager.GetInstance().dicCharacterAnimData[this.info.id].hit_anim_name);
        }
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class DataLoad : MonoBehaviour
{
    private AsyncOperation asyncOperation;
 
    // Start is called before the first frame update
    void Start()
    {
        //데이터 로드, 데이터 적재
        Debug.Log("DataLoad 씬 Start()");
        DataManager dataManager = DataManager.GetInstance();
        dataManager.LoadDatas();
    }
}
 
cs


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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
 
public class DataManager
{
    private static DataManager instance;
    public Dictionary<int, CharacterData> dicCharacterData;
    public Dictionary<int, CharacterAnimData> dicCharacterAnimData;
 
    //생성자
    private DataManager()
    {
        this.dicCharacterAnimData = new Dictionary<int, CharacterAnimData>();
        this.dicCharacterData = new Dictionary<int, CharacterData>();
    }
 
    //인스턴스리턴
    public static DataManager GetInstance()
    {
        if(DataManager.instance == null)
        {
            DataManager.instance = new DataManager();
        }
        return DataManager.instance;
    }
 
    //제이슨 파일로드
    public void LoadDatas()
    {
        //캐릭터데이터
        var textAsset = Resources.Load<TextAsset>("Datas/character_data");
        var json = textAsset.text;
        var arrJson = JsonConvert.DeserializeObject<CharacterData[]>(json);
        foreach (var data in arrJson)
        {
            this.dicCharacterData.Add(data.id, data);
        }
        //애니메이션데이터
        var textAsset2 = Resources.Load<TextAsset>("Datas/character_anim_data");
        var json2 = textAsset2.text;
        var arrJson2 = JsonConvert.DeserializeObject<CharacterAnimData[]>(json2);
        foreach (var data in arrJson2)
        {
            this.dicCharacterAnimData.Add(data.id, data);
        }
        Debug.LogFormat("dicCharacterData  {0}개"this.dicCharacterData.Count);
        Debug.LogFormat("dicCharacterAnimData  {0}개"this.dicCharacterAnimData.Count);
    }
 
}
 
cs


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
70
71
72
73
74
75
76
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class InGame : MonoBehaviour
{
    private Character hero;
    private Character monster;
    private bool completeMethod;
 
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("InGame Start 메서드 실행");
        this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.hero.info.id].idle_anim_name);
        this.monster.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.monster.info.id].idle_anim_name);
 
        this.hero.Move(this.monster.transform.position, () =>
        {
            Debug.Log("사정거리에 도달했습니다.");
            this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.hero.info.id].idle_anim_name);
            this.hero.Attack(this.monster);
        });
        this.hero.OnAttackComplete = () => {
 
            this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.hero.info.id].idle_anim_name);
            if (this.monster.info.hp > 0)
            {
                this.hero.Attack(this.monster);
            }
            else
            {
                this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.hero.info.id].idle_anim_name);
            }
        };
 
        this.hero.transform.LookAt(new Vector3(101));
        this.hero.Move(new Vector3(101), () =>
        {
            Debug.Log("초기위치에 도달했습니다.");
            this.hero.anim.Play(DataManager.GetInstance().dicCharacterAnimData[this.hero.info.id].idle_anim_name);
        });
    }
 
    public void Init()
    {
        Debug.Log("InGame 스크립트의 Init메서드 호출");
        var data = DataManager.GetInstance();
        this.hero = this.CreateCharacter(0);
 
        this.monster = this.CreateCharacter(1);
        this.hero.transform.position = new Vector3(101);
        this.monster.transform.position = new Vector3(505);
        this.hero.transform.LookAt(this.monster.transform);
        this.monster.transform.LookAt(this.hero.transform);
    }
 
    public Character CreateCharacter(int id)
    {
        var data = DataManager.GetInstance();
 
        //캐릭터생성
        var characterPrefab = Resources.Load<GameObject>("Prefabs/Character");
        var characterGo = GameObject.Instantiate<GameObject>(characterPrefab);
        var modelPrefab = Resources.Load<GameObject>(data.dicCharacterData[id].prefab_name);
        var modelGo = GameObject.Instantiate<GameObject>(modelPrefab);
        var character = characterGo.AddComponent<Character>();
        character.Model = modelGo;
        character.name = data.dicCharacterData[id].name;
        character.info = new CharacterInfo(id, data.dicCharacterData[id].anim_data_id, data.dicCharacterData[id].hp);
        character.transform.position = character.info.position;
 
        Debug.Log("캐릭터 생성됨");
        return character;
    }
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class Logo : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Logo씬 스크립트의 Start메서드가 호출됨");
        Debug.Log("Logo를 보여줍니다.");
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
 
public class Title : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Title Scene Title Script 호출");
        Debug.LogFormat("DataLoad씬 호출완료");
    }
}
 
cs


'Unity > 과제' 카테고리의 다른 글

Isometric, 클릭시 좌표 출력하기  (0) 2019.05.13
2D Running Game 기본 시스템 만들기  (0) 2019.05.09
씬 전환 및 가서 공격하기  (0) 2019.04.16
0  (0) 2019.04.11
:

0

Unity/과제 2019. 4. 11. 22:04

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Character : MonoBehaviour
{
    private float moveSpeed = 1;
    private float distance;
    private float attackRange;
    private float translation = 0;
    private int attackDamage;
    private int hp;
    private int count = 0;
    private int attackCount = 1;
    private Vector3 normVector;
    private Vector3 targetPosition;
    private Character target;
    private Animation anim;
    private bool isMoveStart = false;
    private bool isAttackStart = false;
 
    void Awake()
    {
        this.anim = this.gameObject.GetComponent<Animation>();
    }
 
    // Start is called before the first frame update
    void Start()
    {
 
    }
 
    //초기화
    public void Init(int attackDamage, int hp, float attackRange, Vector3 initPosition)
    {
        this.attackDamage = attackDamage;
        this.hp = hp;
        this.attackRange = attackRange;
        this.gameObject.transform.position = initPosition;
    }
 
    //공격
    public void AttackMotion()
    {
        switch (this.attackCount)
        {
            case 1:
                {
                    this.anim.Play("attack_sword_01");
                }
                break;
        }
            //case 2:
            //    {
            //        this.anim.Play("attack_sword_02");
            //    }
            //    break;
            //case 3:
            //    {
            //        this.anim.Play("attack_sword_03");
            //    }
        //    //    break;
        //}
        //this.attackCount++;
        //if (this.attackCount > 3)
        //{
        //    this.attackCount = 1;
        //}
 
    }
 
    //피해받음
    public void GetDamage(int damage)
    {
        this.hp -= damage;
        Debug.Log("데미지를 입었습니다.");
    }
 
    //이동
    public void Move()
    {
        this.gameObject.transform.position += this.normVector * this.moveSpeed * Time.deltaTime;
        this.distance = Vector3.Distance(this.targetPosition, this.gameObject.transform.position);
 
        if (this.distance <= this.attackRange)
        {
            Debug.Log("이동완료");
            this.anim.Play("idle@loop");
            this.isAttackStart = true;
            this.isMoveStart = false;
        }
    }
 
    //이동시작
    public void MoveStart(Character target)
    {
        this.target = target;
        Debug.Log("이동시작");
        this.isMoveStart = true;
        this.targetPosition = this.target.gameObject.transform.position;
        this.normVector = (this.targetPosition - this.gameObject.transform.position).normalized;
 
        //animation start
        this.anim.Play("run@loop");
 
        //방향 변경
        this.gameObject.transform.LookAt(targetPosition);
    }
 
    // Update is called once per frame
    void Update()
    {
 
        this.translation += Time.deltaTime * 10;
        //Debug.Log(translation);
 
        if (isMoveStart)
        {
            this.Move();
        }
        else if (isAttackStart)
        {
            //Debug.Log(this.translation);
            if (this.attackCount == 1)
            {
                if (this.translation >= 6.48f)
                {
                    this.translation = 0;
                    this.target.GetDamage(this.attackDamage);
                }
                else if (this.translation <= 6.47f)
                {
                    this.AttackMotion();
                }
            }
        }
 
    }
}
 
cs

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 App : MonoBehaviour
{
    public Character hero;
    public Character monster;
 
    void Awake()
    {
        this.hero.Init(15700.5f, new Vector3(000));
        this.monster.Init(1050, 1f, new Vector3(505));
        this.hero.MoveStart(this.monster);
 
    }
    // Start is called before the first frame update
    void Start()
    {
    }
 
    // Update is called once per frame
    void Update()
    {
        
    }
}
 
cs


'Unity > 과제' 카테고리의 다른 글

Isometric, 클릭시 좌표 출력하기  (0) 2019.05.13
2D Running Game 기본 시스템 만들기  (0) 2019.05.09
씬 전환 및 가서 공격하기  (0) 2019.04.16
왔다갔다 때리기  (0) 2019.04.16
:

Programmers

Algorithm/Programmers 2019. 4. 11. 09:53

https://programmers.co.kr/

: