무기 착용

2020. 5. 13. 12:32Unity/수업내용

<UIStudio.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
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
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
 
public class UIStudio : MonoBehaviour
{
    public enum eBtnTypes
    {
        NONE = -1, HAMMER, MACHETE, AXE
    }
    private eBtnTypes btnType;
    public Button[] arrBtns;
    public Button attackBtn;
    public Image weaponIconImage;
    public Sprite[] arrSprites;
    private bool isWeaponChange;
 
    private Hero hero;
 
    private GameObject weaponShell;
 
    private GameObject axe;
    private GameObject hammer;
    private GameObject machete;
 
    private GameObject axeEffect;
    private GameObject hammerEffect;
    private GameObject macheteEffect;
 
    void Start()
    {
        this.Init();
        for (int i = 0; i < this.arrBtns.Length; i++)
        {
            int captureIdx = i;
            this.arrBtns[i].onClick.AddListener(() =>
            {
                this.btnType = (eBtnTypes)captureIdx;
                weaponIconImage.sprite = arrSprites[captureIdx];
                isWeaponChange = true;
            });
            this.attackBtn.onClick.AddListener(() =>
            {
                hero.Attack();
            });
        }
    }
    void Update()
    {
        if (isWeaponChange)
        {
            switch (this.btnType)
            {
                case eBtnTypes.AXE:
                    this.axe.SetActive(true);
                    this.hammer.SetActive(false);
                    this.machete.SetActive(false);
                    break;
                case eBtnTypes.HAMMER:
                    this.axe.SetActive(false);
                    this.hammer.SetActive(true);
                    this.machete.SetActive(false);
                    break;
                case eBtnTypes.MACHETE:
                    this.axe.SetActive(false);
                    this.hammer.SetActive(false);
                    this.machete.SetActive(true);
                    break;
            }
            isWeaponChange = false;
        }
        this.RotateObject(hero.gameObject);
 
    }
    void Init()
    {
        this.btnType = eBtnTypes.NONE;
 
        // 캐릭터 생성
        this.hero = CreateHero("Prefabs/ch_02_01");
 
        // 무기 Shell 생성
        this.weaponShell = new GameObject();
        this.weaponShell.name = "Weapon";
 
        // 무기 생성
        this.axe = CreateWeapon("Prefabs/axe");
        this.hammer = CreateWeapon("Prefabs/hammer");
        this.machete = CreateWeapon("Prefabs/machete");
 
        // 이펙트 생성
        this.axeEffect = CreateEffect("Prefabs/ErekiBall");
        this.hammerEffect = CreateEffect("Prefabs/ErekiBall2");
        this.macheteEffect = CreateEffect("Prefabs/frameBall");
 
        // 이펙트 - 무기 SetParent
        this.axeEffect.transform.SetParent(this.axe.transform);
        this.hammerEffect.transform.SetParent(this.hammer.transform);
        this.macheteEffect.transform.SetParent(this.machete.transform);
 
        // 무기 - 무기Shell SetParent
        this.axe.transform.SetParent(this.weaponShell.transform);
        this.hammer.transform.SetParent(this.weaponShell.transform);
        this.machete.transform.SetParent(this.weaponShell.transform);
 
        // 무기Shell - Hero SetParent
        var dummyRHand = GameObject.Find("DummyRHand");
        this.weaponShell.transform.SetParent(dummyRHand.transform);
 
        this.weaponShell.transform.localPosition = new Vector3(0f, 0f, 0f);
        this.weaponShell.transform.localRotation = Quaternion.Euler(new Vector3(0f, 180f, 0f));
        this.weaponShell.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
 
    }
    private Hero CreateHero(string path)
    {
        var modelPrefab = Resources.Load<GameObject>(path);
        var modelGo = Instantiate<GameObject>(modelPrefab);
        modelGo.transform.position = new Vector3(000);
 
        var heroPrefab = Resources.Load<GameObject>("Prefabs/Hero");
        var heroGo = Instantiate<GameObject>(heroPrefab);
        var hero = modelGo.AddComponent<Hero>();
        modelGo.transform.SetParent(heroGo.transform);
 
        return hero;
    }
    private GameObject CreateEffect(string path)
    {
        var effectPrefab = Resources.Load<GameObject>(path);
        var effectGo = Instantiate<GameObject>(effectPrefab);
        effectGo.transform.position = new Vector3(00.4f, 0);
        return effectGo;
    }
 
    private GameObject CreateWeapon(string path)
    {
        var weaponPrefab = Resources.Load<GameObject>(path);
        var weaponGo = Instantiate<GameObject>(weaponPrefab);
        weaponGo.transform.position = new Vector3(000);
        weaponGo.SetActive(false);
        return weaponGo;
    }
    private void RotateObject(GameObject gameObject)
    {
        gameObject.transform.Rotate(010);
    }
}
 
cs

 

<Hero>

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;
 
public class Hero : MonoBehaviour
{
    public enum eState
    {
        Done = -1,
        Run,
        Idle,
        Attack,
        Die
    }    
    private Animation anim;
    private eState estate;
    private float timer;
    void Start()
    {
        this.anim = this.gameObject.GetComponent<Animation>();        
    }
    void Update()
    {
        switch (this.estate)
        {
            case eState.Run:                
                break;
            case eState.Idle:
                break;
            case eState.Attack:
                this.timer += Time.deltaTime;       // 타이머 시작
                if (this.timer >= this.anim["attack_sword_01"].length + 0.1f) // 3) 타이머에서 흐른 시간이 공격 모션 시간보다 충분히 지났다면 다시 시작
                {
                        this.estate = eState.Done;          // case를 Default로 바꿔서 다른 State를 타지 못하게 함
                    this.anim.Play("attack_sword_01");   // 1) 공격 (공격 모션 시간 Start)
                    this.timer = 0f;                    // 2) 공격 후 Timer = 0
                }
                break;
            case eState.Die:
                break;
            default:
                break;
        }
    }
    public void Run()
    {
        this.anim.Play("run@loop");
        this.estate = eState.Run;
    }
    public void Idle()
    {
        this.anim.Play("idle@loop");
        this.estate = eState.Attack;
    }
    public void Attack()
    {
        this.estate = eState.Attack;
        this.timer = 1f;
    }
    public void Die()
    {
        this.anim.Play("die");
        this.estate = eState.Die;
    }
}
 
cs

 

1. 구조

a. Hero(Shell)

 └ Hero(Model)

    └ Weapon(Shell)

       └ Weapon(Model)

          └ Effect(Model)

b. Hero(Shell)에 AddComponent를 붙인 후 <Hero.cs> 에서 Action 관리

 

2. 주의점

a. Script 내에서 Transform을 셋팅할 때 local로 접근해야 함.

=>Shell로 관리하기 때문

b. Script 순서 유의. GameObject를 Instantiate 한 후에 SetParent를 해야 한다.

 

3. 의문점

 

a. Button의 onClick.AddListener를 for문 안에서 설정할 때, 왜 CaptureIdx를 별도로 지정해주어야 하는가? : 아래 참고

- https://mentum.tistory.com/343

 

for 문에서 AddListener 람다식은 주의해야한다. (AddListener for loop)

버튼을 배열로 선언해놓고 for문에서 AddListener로 할당하려고 했는데, 모두 마지막 값으로 초기화되는 현상이 있었다. for (int i = 0; i < Btns.Length; i++) { Btns[i].onClick.AddListener(() => PressBtnSel..

mentum.tistory.com

 

 

 

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

HudText  (0) 2020.05.26
UnityAction (Delegate)  (0) 2020.05.26
Camera Setting  (0) 2020.05.25
Slider 만들기  (0) 2020.05.21
Scroll 만들기  (0) 2020.05.19