본문 바로가기

Unity/수업내용

2020-05-13 수업내용(무기바꾸기, 이펙트적용, 공격모션)

포토샵으로 아이콘만들기

더보기

아이콘만들기(포토샵에서) --> 뒤로가기는 컨트롤 알트 z 

이미지 불러오기 

레이어탭에서 자물쇠 풀어주고, 마법봉으로 선택 딜렉트로 
알파채널로만들어줌 
(주의사항) 배경색이 검은색이나 빨간색, 물체와 겹치는색이 없어야함 

컨트롤 A 전체영역선택 
컨트롤 시프트 C 선택영역 복사 
컨트롤 n 이미지 사이즈로 새캔버스를 만들어줌 
컨트롤v 

컨트롤 시프트 알트 S로 저장 

컨트롤n 으로 120x120으로 만들고 
배경화면빼고 이미지 새로저장

 

무기바꾸기, 이펙트적용, 공격모션

동영상

:코드가 세계관 최강으로 어거지에 더럽다... 코드정리가 필요하다. 

 

UIStudio.class

더보기
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
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
 
public class UIStudio : MonoBehaviour
{
    public enum eBtnTypes
    {
        MACHETTE, HAMMER, AXE
    }
 
    public Button[] arrBtns;
    public Image weaponIconImage;
    public Sprite[] arrSprites;
    public GameObject[] arrPrefabs;
    public GameObject[] arrEffects;
 
    public float speed;
 
    private GameObject[] arrItems;
    private GameObject currentMyItem;
    private bool isSeted;
 
    // Start is called before the first frame update
    void Start()
    {
        this.arrItems = new GameObject[this.arrPrefabs.Length]; //아이템 배열을 초기화를 안했었음.
 
        this.currentMyItem = new GameObject();
        this.currentMyItem.name = "무기창고";
 
        var hero = this.CreateCloneHero("Hero""Prefabs/ch_05_01");
        hero.Init(new Vector3(000));
 
        for (int i = 0; i < this.arrPrefabs.Length; i++)
        {
            this.arrItems[i] = Instantiate(this.arrPrefabs[i]) as GameObject;
            this.arrEffects[i] = Instantiate(this.arrEffects[i]);
            this.arrEffects[i].gameObject.SetActive(false);
 
            this.arrEffects[i].transform.SetParent(this.arrItems[i].transform);
            this.arrItems[i].transform.SetParent(this.currentMyItem.transform);
            this.arrItems[i].SetActive(false);
        }
 
 
        for (int i = 0; i < this.arrBtns.Length; i++)
        {
            int capturedIdx = i;
            this.arrBtns[i].onClick.AddListener(() =>
            {
                if (capturedIdx != 3)
                {
                    //Debug.LogFormat("{0}", (eBtnTypes)capturedIdx); //버튼을 누르면 제대로 나옴
                    // Debug.LogFormat("{0}", (eBtnTypes)i); // 3밖에 안찍힘
 
                    Debug.LogFormat("{0}, {1}", (eBtnTypes)capturedIdx, this.arrSprites[capturedIdx]);
 
                    this.ChangeImage(capturedIdx);
                    this.ShowItem(capturedIdx);
                    hero.EquipItem(this.Getitem(capturedIdx));
                }
                else
                {
                    hero.AttackAnim();
                }
            });
        }
 
 
 
       
    }
 
    public Hero CreateCloneHero(string name,string path)
    {
        var shellGo = new GameObject();
        shellGo.name = name;
 
        var prefab = Resources.Load(path) as GameObject;
        var modelGo = Instantiate(prefab) as GameObject;
 
        var hero = shellGo.AddComponent<Hero>();
        hero.tag = "Hero";
        modelGo.transform.SetParent(shellGo.transform,false);
 
        return hero;
    }
 
    public void ChangeImage(int index)
    {
        weaponIconImage.sprite = arrSprites[index];
    }
 
    public void ShowItem(int index)
    {
        for (int i = 0; i < this.arrItems.Length; i++)
        {
            if (i == index)
            {
                this.arrItems[i].SetActive(true);
                this.arrEffects[i].gameObject.SetActive(true);
                this.arrEffects[i].transform.position = this.arrItems[i].transform.position;
                this.isSeted = true;
            }
            else
            {
                this.arrItems[i].SetActive(false);
                this.arrEffects[i].gameObject.SetActive(false);
            }
        }
    }
    public GameObject Getitem(int index)
    {
       return this.arrItems[index];
    }
 
    // Update is called once per frame
    void Update()
    {
        //if (this.isSeted == true)
        //{
        //    this.currentMyItem.transform.Rotate(Vector3.up, this.speed * Time.deltaTime);
        //}
    }
}
 
 
 

 

 

Hero.Class

더보기
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
using UnityEngine;
 
public class Hero : MonoBehaviour
{
    public Animation anim;
    private GameObject dummyRhands;
    private bool isEquiped;
 
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GameObject.Find("ch_05_01(Clone)").GetComponent<Animation>();
    }
 
    public void Init(Vector3 initPos)
    {
        this.transform.SetParent(this.transform,false);
        this.transform.transform.position = initPos;
        //target.transform.SetParent();
    }
 
    public void EquipItem(GameObject item)
    {
        var target = GameObject.Find("DummyRHand");
        item.transform.SetParent(target.transform,false);
        item.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
    }
 
    public void AttackAnim()
    {
        this.anim.Play("attack_sword_01");
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}
 
 
 

 

 

코딩중 오류 참고

 

오브젝트 풀링기법 구현하기

참고

강사님 코드 분석

더보기
 
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPool : MonoBehaviour
{
    //정적 객체로 instance 정의
    //why? 우선 오브젝트 풀의 경우 오브젝트를 생성하는 어떤 코드에서든 접근이 가능해야하는 경우가 많기 때문에 싱글톤 패턴으로 구현되는 경우가 많다. 
 
    private static ObjectPool instance;
 
    //assetList 리스트생성
    //why?
    private List<GameObject> assetList;
 
    //그리고 생성해야할 오브젝트의 프리팹을 가지고 있다. 
    //프리팹을 가지고 있어야 하는 이유는 처음 생성해둔 오브젝트를 모두 꺼내주고 나서, 꺼내준 오브젝트를 미처 돌려받기 전에, 
    //오브젝트를 요청받았을 때, 새로운 오브젝트를 생성해서 꺼내주기 위한 것이다.
 
 
    //assetNames 문자열 배열에 무기이름과, 이펙트 이름을 문자열로 저장해 놓은 것으로 추측됨
    //why?
    //guess: id값처럼 쓰기위해서?
    private string[] assetNames = { "Axe""Hammer""Machete""fx_00""fx_01""fx_02" };   
    private void Awake()
    {
        //싱글톤 스크립트로 사용하기 위해 정의
        ObjectPool.instance = this;
        //로드되어진 어셋을 관리하기 위해 리스트 인스턴스화
        this.assetList = new List<GameObject>();
    }
 
    public static ObjectPool GetInstance()  //싱글톤 패턴으로 구현됨 = 싱글톤 스크립트
    {
        return ObjectPool.instance;
    }
 
   
    //어셋리스트에 담는다.
    //문자열배열에 담아놓은 이름으로 이름을 초기화
    //오브젝트풀에 자식으로 넣어둠
    //비활성화
    public void LoadAllAssets()
    {
        foreach (var assetName in this.assetNames)
        {
            var path = string.Format("Prefabs/{0}", assetName);     //문자열배열에 있는 이름으로 프리팹 로컬주소 만듬      
            var prefab = Resources.Load(path) as GameObject;        //프리팹을 가져와서 로드         
            var asset = Instantiate<GameObject>(prefab);            //실체화 한다
            this.assetList.Add(asset);      //어셋 리스트에 담는다.
            asset.name = assetName;         //문자열배열에 있는 이름으로 오브젝트이름을 초기화
            asset.transform.SetParent(this.transform);  //오브젝트풀의 자식들로 넣음
            asset.SetActive(false); //로드시 비활성화
        }
    }
 
    public GameObject GetAsset(string name)
    {
        Debug.LogFormat("name: {0}", name);
        var asset = this.assetList.Find(x => x.name == name); //이름으로 어셋리스트에서 어셋을 찾는다.
        if (asset != null)      //어셋이 null이 아니면 오브젝트풀에서 떼어낸다.
        {
            asset.transform.parent = null;  //그리고 떼어낸 자리에 null값으로 채운다.
        }
        return asset;   //어셋을 반환
    }
 
    public void ReleaseAsset(GameObject asset)  //매개변수로 받아온 어셋
    {
        asset.SetActive(false);     //먼저 비활성화한다.
        asset.transform.parent = null// 먼저 떼고 초기화해야 정위치로됨
        asset.transform.localPosition = Vector3.zero;   //위치 초기화
        asset.transform.SetParent(this.transform); //다시 오브젝트풀의 자식으로 넣어둠
        //asset.transform.localRotation = Quaternion.Euler(Vector3.zero); //다시 가져올때 칼등으로 때려서 주석
    }
}
 
 
 

 

 

이해한대로 짜본 오브젝트풀링 코드

더보기
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 JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPool : MonoBehaviour
{
    private static ObjectPool instance;     //정적으로 ObjectPool형식 instance 인스턴스 정의
    private List<GameObject> assetList;     //어셋을 관리할 리스트 정의
    private string[] arrAssetNames;
    private void Awake()
    {
        ObjectPool.instance = this;         //이 스크립트를 싱글턴 패턴으로 사용하기 위해
        this.assetList = new List<GameObject>();    //어셋 관리 리스트 객체화
        this.arrAssetNames = new string[] { "axe""machete""hammer""effect_1""effect_2""effect_3" };
    }
    public static ObjectPool Getinstance() //싱글턴 패턴
    {
        return ObjectPool.instance;
    }
 
    private void LoadAllAsset()    //어셋을 로드해야지
    {
        foreach (var name in this.arrAssetNames)
        {
            string path = string.Format("Prefabs/{0}", name);   //문자열 배열에 초기화해둔 이름으로 로컬주소생성
            var prefab = Resources.Load(path) as GameObject;    //로컬주소를 기준으로 프리팹로드
            var asset = Instantiate(prefab) as GameObject;      //asset 실체화
            this.assetList.Add(asset); //어셋관리를 위해 어셋리스트에 넣어둠.
 
 
            asset.name = name;      //문자열 배열에서 가져온 이름 = 어셋 이름 초기화
            
            asset.transform.SetParent(this.transform); //이코드를 안넣었었음...
 
            asset.SetActive(false); //비활성화
 
 
        }
    }
 
    public GameObject GetAsset(string name) //이름으로 어셋을 가져옵니다.
    {
        var asset = GameObject.Find(name);
        this.transform.SetParent(asset.transform);
        asset.transform.parent = null;
        asset.SetActive(true);
 
        return asset;
    }
 
    //이름을 매개변수로 가져오는것이 아니라
    //public void ReleaseAsset(string name)   
 
    //asset자체를 매개변수로 받음
    public void ReleaseAsset(GameObject asset)   
    {
        asset.SetActive(false);
        asset.transform.parent = null;
 
        asset.transform.position = Vector3.zero;
        asset.transform.rotation = Quaternion.Euler(000);
        asset.transform.SetParent(instance.transform);       //this.transform? 창고라는생각으로
    }
}
 
 
 

 

 

 

메모

더보기
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
현재버전  2017버전
unpack = break pack
 
fbx파일 = 원본파일
 
----------------------------
아이콘만들기(포토샵에서) --> 뒤로가기는 컨트롤 알트 z
 
이미지 불러오기
 
레이어탭에서 자물쇠 풀어주고, 마법봉으로 선택 딜렉트로
알파채널로만들어줌
(주의사항) 배경색이 검은색이나 빨간색, 물체와 겹치는색이 없어야함
 
컨트롤 A 전체영역선택
컨트롤 시프트 C 선택영역 복사
컨트롤 n 이미지 사이즈로 새캔버스를 만들어줌
컨트롤v
 
컨트롤 시프트 알트 S로 저장
 
컨트롤n 으로 120x120으로 만들고
배경화면빼고 이미지 새로저장
 
----------------------------
 
UIStudio라는 씬에서만 리소스를 다룬다.
안그러면 뒤죽박죽 난리남
 
----------------------------
 
버튼 정렬
캔버스안에 빈오브젝트 grid라고 만들고,
애드컴포넌트해서 Vertical Layout Group 달아주고
grid 오브젝트안에 버튼 3개를 넣는다.(자동정렬&&그룹화)
 
Spacing속성으로 버튼간격 설정가능
 
----------------------------
 
구조는 반드시라는 것은 없음
 
오브젝트풀은 여러개가 될수 있고,
오브젝트풀을 가지치기해서 매니져를 만들어 관리할수도 있음
---------------------------
 
오브젝트풀 공부해야되는 2가지
 
모노를 상속받지만 싱글턴 클래스로 작용되는 게 많아짐
cs

 

 

참고