캐릭터 선택해서 무기 고르고 씬전환하면 생성한 캐릭터 전달까지 완료
ObjectPool 사용해서 무기랑 캐릭터 반환시켜서 코드 다시 작성하느라 좀 오래걸림
DataManger로 Json 파일 불러와서 관리하는 건 이제 괜찮은 것 같다
이제 캐릭터와 몬스터 포탈 등 위치 정해서 보이게하고
몬스터 달려가고 애니메이션 설정하고 타격시점 맞춰서 효과만들고 몬스터 없으면
포탈로 가야하는 거 해야함
움직이는 시간과 프레임 계산해서 타격때 효과 넣는게 좀 헷갈림
더 연습해야함
InGame 코드
ObjectPool 사용해서 필요한 프리팹을 붙였다 떼었다 함
버튼에 따라서 캐릭터 5, 무기 3 선택할 수 있고 캐릭터 선택 후에 무기 선택하면
캐릭터의 dummyRHand 찾아서 무기를 붙여줌
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;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class InGame : MonoBehaviour
{
public Button[] weaponBtns;
public Button[] characterBtn;
public Button nextBtn;
public GameObject character;
public GameObject characterEffect;
public GameObject stage;
public Character hero;
private DataManger dataManger;
private ObjectPool objectPool;
private void Awake()
{
dataManger = DataManger.GetInstance();
dataManger.LoadDatas();
this.objectPool = ObjectPool.GetInstance();
this.objectPool.LoadAllAssets();
}
void Start()
{
for (int j = 0; j < this.characterBtn.Length; j++)
{
int idIdx = j + 100;
this.characterBtn[j].onClick.AddListener(() =>
{
this.characterEffect.SetActive(true);
if(this.character != null)
{
this.objectPool.ReleaseAsset(this.character);
}
this.character = this.objectPool.GetCharacter(dataManger.GetCharacterData(idIdx).res_name);
this.character.transform.SetParent(hero.transform);
this.character.SetActive(true);
hero.dummyRHand = GameObject.FindWithTag("dummy");
});
}
for (int i = 0; i < this.weaponBtns.Length; i++)
{
int idIdx = i + 200;
this.weaponBtns[i].onClick.AddListener(() =>
{
if(this.hero.weapon != null)
{
this.objectPool.ReleaseAsset(this.hero.weapon);
}
this.hero.weapon = this.objectPool.GetWeapon(dataManger.GetWeaponData(idIdx).res_name);
this.hero.weapon.transform.SetParent(hero.dummyRHand.transform);
this.hero.weapon.SetActive(true);
this.hero.weapon.transform.localPosition = hero.dummyRHand.transform.localPosition;
this.hero.weapon.transform.rotation = hero.dummyRHand.transform.localRotation;
});
}
this.nextBtn.onClick.AddListener(() =>
{
this.hero.model = this.character;
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
SceneManager.LoadScene("Stage_01");
});
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
Stage_01 stage = GameObject.FindObjectOfType<Stage_01>();
stage.Init();
}
}
|
cs |
ObjectPool 코드
캐릭터와 무기 프리팹을 전부 붙여놓았다가
밖에서 필요하면 해당 프리팹을 찾아서 떼어내 반환시켜준다
밖에서 필요없어진 프리팹은 다시 받아서 비활성화 후 다시 붙임
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool : MonoBehaviour
{
private static ObjectPool instance;
private string[] weaponNames = {"axe", "hammer", "machete"}; //프리팹 이름 배열
private List<GameObject> weaponList; //나중에 찾아서 반환시켜야하니까 배열 만들어서 찾기 편하게 한 것
private string[] characterNames = {"ch_01_01", "ch_02_01" , "ch_03_01" , "ch_04_01" , "ch_05_01" };
private List<GameObject> characterList;
private void Awake()
{
ObjectPool.instance = this;
this.weaponList = new List<GameObject>();
this.characterList = new List<GameObject>();
}
public static ObjectPool GetInstance()//싱글톤
{
return ObjectPool.instance;//인스턴스는 하나만 만들어서 한개의 인스턴스만 반환
}
public void LoadAllAssets() //프리팹을 찾아서 게임오브젝트로 만들어서 로드
{
foreach(var weaponName in this.weaponNames)
{
//프리팹 이름 배열을 이용하여 경로를 만든다
string path = "Prefab/" + weaponName;
//경로를 이용하여 Resources 안에 있는 프리팹을 변수에 할당(게임오브젝트로 타입 변경)
var prefab = Resources.Load(path) as GameObject;
//찾은 프리팹을 게임오브젝트로 만들어서 할당
var asset = Instantiate<GameObject>(prefab);
//찾기 편하게 만든 무기오브젝트 배열에 만든 프리팹 게임오브젝트를 추가
this.weaponList.Add(asset);
//위에서 찾은 프리팹을 게임오브젝트 만든 것의 이름을 설정
asset.name = weaponName;
//게임오브젝트 만든 것의 부모로 지금 오브젝트로 설정
asset.transform.SetParent(this.transform);
//만든 게임오브젝트 비활성화 => 나중에 쓸때 따로 활성화 시켜서 사용
asset.SetActive(false);
}
foreach(var characterName in this.characterNames)
{
string path = "Prefab/" + characterName;
var prefab = Resources.Load(path) as GameObject;
var asset = Instantiate<GameObject>(prefab);
this.characterList.Add(asset);
asset.name = characterName;
asset.transform.localScale = new Vector3 (2, 2, 2);
asset.transform.SetParent(this.transform);
asset.SetActive(false);
}
}
public GameObject GetWeapon(string name) //이름을 전달받으면 게임오브젝트 찾아서 반환시켜 줌
{
//무기오브젝트 배열에서 전달받은 매개변수와 같은 게임오브젝트를 찾는다.
var asset = this.weaponList.Find(x => x.name == name);
//찾은 게임오브젝트를 떼어서 반환시켜줘야하기 때문에
//지금 오브젝트에서 찾은 자식을 떼어준다
if(asset != null)
{
asset.transform.SetParent(null);
}
//붙여준 부모에서 떼어냈으니 값을 반환시킨다
return asset;
}
public GameObject GetCharacter(string name)
{
var asset = this.characterList.Find(x => x.name == name);
if (asset != null)
{
asset.transform.SetParent(null);
}
return asset;
}
public void ReleaseAsset(GameObject asset) //다 사용하고 떼어 낼 매개변수인 게임오브젝트를 전달받아 자식으로 다시 붙여준다
{
//게임오브젝트를 비활성화 시킨다
asset.SetActive(false);
//비활성화 시킨 게임오브젝트를 다시 붙여준다
//지금 오브젝트를 부모로 전달 받은 걸 자식으로 넣기
//하지만 바로 부모로 붙히고 위치를 바꾸면 초기화가 안됨
//먼저 떼어준다
asset.transform.parent = null;
//오브젝트의 위치를 다시 원상태로 초기화시킨다 Vector3 (0, 0, 0)
asset.transform.localPosition = Vector3.zero;
//Rotation을 바꿔주면 칼등으로 때린다 함, 밑에는 안해도되므로 주석
//asset.transform.localRotation = Quaternion.Euler(Vector3.zero);
//위치도 초기화 시켰으니 다시 전달받은 오브젝트를 자식으로 지금 오브젝트를 부모로 설정
asset.transform.SetParent(this.transform);
}
}
|
cs |
DataManger 코드
Json 파일 업로드 후 사전에 담아서 데이터 필요한 것만 반환시켜 줌
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 Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine;
public class DataManger
{
private static DataManger instance;
private Dictionary<int, CharacterData> dicCharacterDatas;
private Dictionary<int, WeaponData> dicWeaponDatas;
private Dictionary<int, EffectData> dicEffectDatas;
private DataManger()
{
this.dicCharacterDatas = new Dictionary<int, CharacterData>();
this.dicWeaponDatas = new Dictionary<int, WeaponData>();
this.dicEffectDatas = new Dictionary<int, EffectData>();
}
public static DataManger GetInstance()
{
if( DataManger.instance == null)
{
DataManger.instance = new DataManger();
}
return DataManger.instance;
}
public void LoadDatas()
{
var characterJson = Resources.Load<TextAsset>("character_data");
this.dicCharacterDatas = JsonConvert.DeserializeObject<CharacterData[]>(characterJson.ToString()).ToDictionary(x => x.id);
var weaponJson = Resources.Load<TextAsset>("weapon_data");
this.dicWeaponDatas = JsonConvert.DeserializeObject<WeaponData[]>(weaponJson.ToString()).ToDictionary(x => x.id);
var effectJson = Resources.Load<TextAsset>("effect_data");
this.dicEffectDatas = JsonConvert.DeserializeObject<EffectData[]>(effectJson.ToString()).ToDictionary(x => x.id);
}
public CharacterData GetCharacterData(int id)
{
return this.dicCharacterDatas[id];
}
public WeaponData GetWeaponData(int id)
{
return this.dicWeaponDatas[id];
}
}
|
cs |
Character 코드
DontDestroyOnLoad 사용해서 안사라지게 한다
왜냐하면 생성한 캐릭터를 반환시켜야하기 때문
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
public GameObject dummyRHand;
public GameObject weapon;
public GameObject model;
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
|
cs |
Stage_01 코드
안사라지게 한 Character 게임오브젝트를 찾아서 캐릭터를 할당한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stage_01 : MonoBehaviour
{
public Transform hero;
public void Init()
{
var hero = GameObject.Find("Character");
this.hero = hero.transform.GetChild(1);
Debug.Log(this.hero);
}
|
cs |
'c# > 수업내용' 카테고리의 다른 글
캐릭터 얼굴 따기 (0) | 2020.05.21 |
---|---|
2020.05.15 책 진도 449페이지까지 (0) | 2020.05.15 |
캡쳐해서 아이콘 따는 법 (0) | 2020.05.14 |
2020.05.13 ObjectPool을 왜 사용한 것인가? (0) | 2020.05.13 |
2020.05.01 이차원 배열 움직이기 (0) | 2020.05.01 |