CharacterData, EffectData, RawData, WeaponData에 대한 소스코드는 생략하겠습니다.
모든 데이터는 RawData를 상속받습니다.
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;
public class AttackEffect : MonoBehaviour
{
private GameObject model;
public void Init(int id)
{
var data = DataManager.Instance.GetDataById<EffectData>(id);
this.model = ObjectPool.GetInstance().GetAsset(data.res_name);
this.model.transform.SetParent(this.transform);
this.model.transform.localPosition = Vector3.zero;
this.model.transform.localRotation = Quaternion.Euler(Vector3.zero);
}
}
|
cs |
AttackEffect.cs 입니다.
ObjectPool에서 데이터의 res_name을 가져와 붙이고 초기화 합니다.
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.Runtime.CompilerServices;
using System.Linq;
public class DataManager
{
private static DataManager dataManager;
private static Dictionary<int, RawData> dataDict;
public static DataManager Instance
{
get
{
if (dataManager == null)
dataManager = new DataManager();
return dataManager;
}
}
private DataManager()
{
dataDict = new Dictionary<int, RawData>();
}
public void LoadData()
{
JsonConvert.DeserializeObject<CharacterData[]>(Resources.Load<TextAsset>("Data/character_data").text)
.ToList().ForEach(x => dataDict.Add(x.id, x));
JsonConvert.DeserializeObject<EffectData[]>(Resources.Load<TextAsset>("Data/effect_data").text)
.ToList().ForEach(x => dataDict.Add(x.id, x));
JsonConvert.DeserializeObject<WeaponData[]>(Resources.Load<TextAsset>("Data/weapon_data").text)
.ToList().ForEach(x => dataDict.Add(x.id, x));
}
public T GetDataById<T>(int id) where T : RawData
{
return dataDict[id] as T;
}
public List<T> GetAllDatasByType<T>() where T : RawData
{
return dataDict.OfType<T>().ToList();
}
}
|
cs |
DataManager.cs 입니다.
딕셔너리의 밸류 타입을 RawData로 넣어 일반화 시켰습니다.
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
|
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class Hero : MonoBehaviour
{
public enum eState
{
Idle,
Attack,
Move
}
public Weapon weapon;
public eState state;
public AttackEffect AttackEffect;
public int id;
private GameObject model;
private GameObject dummyRHand;
private Animation anim;
private float time;
private string attackName;
private Monster target;
private bool isEffect;
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
void Start()
{
}
public void Init(int id)
{
this.id = id;
if (this.model != null)
ObjectPool.GetInstance().ReleaseAsset(this.model);
string res_name = DataManager.Instance.GetDataById<CharacterData>(id).res_name;
this.model = ObjectPool.GetInstance().GetAsset(res_name);
this.model.transform.SetParent(this.transform);
this.anim = this.model.GetComponent<Animation>();
this.dummyRHand = GameObject.Find("DummyRHand");
this.weapon.transform.SetParent(this.dummyRHand.transform, false);
this.AttackEffect.Init(304);
}
public void EquipWeapon(int weaponId)
{
this.weapon.ChangeWeapon(weaponId);
}
public void Attack()
{
}
public void Attack(string attackName)
{
this.attackName = attackName;
this.state = eState.Attack;
this.anim.Play(this.attackName);
this.time = 0.0f;
this.isEffect = false;
}
public void Move()
{
if(this.target != null)
{
this.transform.LookAt(target.transform);
this.state = eState.Move;
}
}
public void DrawEffect()
{
this.AttackEffect.gameObject.SetActive(false);
this.AttackEffect.gameObject.SetActive(true);
}
public void SetTarget(Monster target)
{
this.target = target;
}
void Update()
{
var characterData = DataManager.Instance.GetDataById<CharacterData>(this.id);
var weaponData = DataManager.Instance.GetDataById<WeaponData>(this.weapon.id);
this.time += Time.deltaTime;
if (this.state == eState.Attack)
{
if(!this.isEffect)
{
float effectTime = this.attackName == "attack_sword_01" ? 0.3f : 0.6f;
if (this.time >= effectTime)
{
this.isEffect = true;
if(target != null)
target.Die();
this.DrawEffect();
}
}
if (this.time > this.anim[attackName].length)
{
this.state = eState.Idle;
}
}
else if (this.state == eState.Idle)
{
this.anim.Play("idle@loop");
}
else if(this.state == eState.Move)
{
if (Vector3.Distance(this.transform.position, target.transform.position) <= characterData.attack_range + weaponData.attack_range)
{
this.Attack("attack_sword_01");
}
else
{
this.transform.position += this.transform.forward * Time.deltaTime * characterData.move_speed;
this.anim.Play("run@loop");
}
}
}
}
|
cs |
Hero.cs 입니다.
착용하는 weapon, 타격 이펙트, 공격할 target을 가지고 있습니다. state enum변수에 따라 업데이트시 행동을 달리 합니다.
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
|
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class InGame : MonoBehaviour
{
public Map map;
public Button battleBtn;
private Hero hero;
private List<Monster> monsters;
public void Init()
{
this.monsters = new List<Monster>();
this.map.Init();
this.hero = GameObject.Find("Hero").GetComponent<Hero>();
}
private void Start()
{
//전투 시작 버튼
this.battleBtn.onClick.AddListener(() =>
{
if (monsters.Count != 0)
{
this.monsters = this.monsters
.OrderBy(x => Vector3.Distance(this.transform.position, x.transform.position)).ToList();
var target = monsters.Find(x => x.gameObject.activeSelf);
if (target != null)
{
hero.SetTarget(target);
hero.Move();
}
}
});
//몬스터 생성.
{
var monsterGo = ObjectPool.GetInstance().GetAsset("chicken");
var rand = new System.Random();
int monsterCount = rand.Next(4) + 2;
for (int i = 0; i < monsterCount; i++)
{
var monGo = Instantiate(monsterGo);
float xPos = (float)(rand.NextDouble() * 8 - 4);
float zPos = (float)(rand.NextDouble() * 8 - 4);
float yPos = 0;
monGo.transform.position = new Vector3(xPos, yPos, zPos);
var compo = monGo.AddComponent<Monster>();
monsters.Add(compo);
}
ObjectPool.GetInstance().ReleaseAsset(monsterGo);
}
}
}
|
cs |
InGame.cs 입니다.
맵 Init의 호출, 전투시작 버튼 onClick 정의 및 몬스터를 동적으로 랜덤한 갯수로 생성합니다.
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
|
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Map : MonoBehaviour
{
private GameObject ground;
private void Awake()
{
}
public void Init()
{
this.ground = ObjectPool.GetInstance().GetAsset("ground");
this.ground.transform.position = Vector3.zero;
this.ground.transform.rotation = Quaternion.Euler(Vector3.zero);
this.ground.transform.localScale = Vector3.one;
var rand = new System.Random(DateTime.Now.Millisecond);
int grassCount = rand.Next(5, 10);
var grassGo = ObjectPool.GetInstance().GetAsset("grass");
for (int i = 0; i < grassCount; i++)
{
var createdGo = Instantiate(grassGo);
float xPos = (float)(rand.NextDouble() * 8 - 4);
float yPos = 0;
float zPos = (float)(rand.NextDouble() * 8 - 4);
createdGo.transform.position = new Vector3(xPos, yPos, zPos);
createdGo.transform.SetParent(this.gameObject.transform, false);
rand = new System.Random(DateTime.Now.Millisecond);
}
ObjectPool.GetInstance().ReleaseAsset(grassGo);
}
}
|
cs |
Map.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;
public class Monster : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
public void Die()
{
this.gameObject.SetActive(false);
}
}
|
cs |
Monster.cs 입니다.
공격 받을시 Die호출, Disable합니다.
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
|
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ObjectPool : MonoBehaviour
{
private static ObjectPool instance;
private static List<GameObject> objectList;
private static string[] prefabNames = {
"Character/ch_01_01",
"Character/ch_02_01",
"Character/ch_03_01",
"Character/ch_04_01",
"Character/ch_05_01",
"Weapon/axe",
"Weapon/hammer",
"Weapon/machete",
"Effect/ErekiBall",
"Effect/ErekiBall2",
"Effect/frameBall",
"Effect/skillAttack",
"Effect/skillAttack2",
"Effect/Spark",
"Map/bone",
"Map/grass",
"Map/ground",
"Map/rock",
"Map/well",
"Monster/chicken"
};
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
gameObject.SetActive(false);
this.gameObject.transform.position = new Vector3(0, 0, 0);
ObjectPool.instance = this;
ObjectPool.objectList = new List<GameObject>();
}
public static ObjectPool GetInstance()
{
return ObjectPool.instance;
}
public void LoadAssets()
{
foreach(var name in prefabNames)
{
var source = Resources.Load<GameObject>("Prefabs/" + name);
objectList.Add(Instantiate<GameObject>(source));
objectList.Last().SetActive(false);
objectList.Last().name = name.Substring(name.LastIndexOf('/') + 1);
objectList.Last().transform.SetParent(this.transform);
objectList.Last().transform.localPosition = Vector3.zero;
objectList.Last().transform.localScale = Vector3.one;
objectList.Last().transform.rotation = Quaternion.Euler(0, 0, 0);
this.gameObject.SetActive(false);
}
}
public GameObject GetAsset(string name)
{
var obj = ObjectPool.objectList.Find(x => x.name == name);
if (obj != null)
{
obj.SetActive(true);
obj.transform.parent = null;
obj.transform.position = Vector3.zero;
obj.transform.rotation = Quaternion.Euler(Vector3.zero);
obj.transform.localScale = Vector3.one;
}
return obj;
}
public void ReleaseAsset(GameObject obj)
{
obj.transform.SetParent(null);
obj.transform.position = Vector3.zero;
obj.transform.rotation = Quaternion.Euler(Vector3.zero);
obj.transform.localScale = Vector3.one;
obj.SetActive(false);
obj.transform.SetParent(this.transform);
}
}
|
cs |
ObjectPool.cs입니다.
실행시 이름으로 등록한 오브젝트를 전부 생성해 하위로 붙여두며 가져오거나 다시 반납할 수 있습니다.
가져오고 붙일때 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
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class UIStudio : MonoBehaviour
{
public enum eBtnTypes
{
Axe,
Hammer,
Machete
}
public Button[] btns;
public Button[] attackBtn;
public Button[] characterBtn;
public Button nextBtn;
public Image weaponIconImage;
public Sprite[] sprites;
public Hero hero;
private int capture;
private void Awake()
{
ObjectPool.GetInstance().LoadAssets();
DataManager.Instance.LoadData();
}
void Start()
{
this.hero.Init(100);
this.hero.EquipWeapon(200);
for(int i = 0; i < this.btns.Length; i++)
{
int captured = i;
this.btns[captured].onClick.AddListener(() =>
{
this.weaponIconImage.sprite = sprites[captured];
hero.EquipWeapon(captured + 200);
});
this.attackBtn[captured].onClick.AddListener(() =>
{
this.hero.Attack("attack_sword_0" + (captured + 1));
});
}
for(int i = 0; i < this.characterBtn.Length; i++)
{
int captured = i;
this.characterBtn[captured].onClick.AddListener(() =>
{
this.hero.Init(100 + captured);
});
}
this.nextBtn.onClick.AddListener(() =>
{
SceneManager.LoadScene("InGame");
});
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
GameObject.Find("InGame").GetComponent<InGame>().Init();
}
void Update()
{
//this.weapons[capture].transform.Rotate(Vector3.up * Time.deltaTime * speed);
}
}
|
cs |
UIStudio.cs입니다.
Hero 인스턴스 외에 이미지, 버튼 등의 멤버를 가지고 있습니다.
누르는 버튼에 따라 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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour
{
public WeaponEffect effect;
public int id;
private GameObject model;
public void Init()
{
this.transform.localScale = Vector3.one * 0.8f;
effect.Init();
effect.transform.SetParent(this.transform, false);
}
public void DetatchModel()
{
if (this.model != null)
ObjectPool.GetInstance().ReleaseAsset(model);
}
public void InsertModel(int id)
{
this.id = id;
string modelName = DataManager.Instance.GetDataById<WeaponData>(id).res_name;
this.model = ObjectPool.GetInstance().GetAsset(modelName);
this.model.transform.SetParent(this.transform);
this.model.transform.localPosition = Vector3.zero;
this.model.transform.localScale = Vector3.one;
this.model.transform.localRotation = Quaternion.Euler(Vector3.zero);
if (modelName == "machete")
this.model.transform.Rotate(Vector3.up * 180);
}
public void ChangeWeapon(int id)
{
this.DetatchModel();
this.InsertModel(id);
this.effect.ChangeEffect(DataManager.Instance.GetDataById<WeaponData>(id).weapon_effect_id);
this.effect.SetPosition(id);
}
}
|
cs |
Weapon.cs 입니다.
무기에 붙을 이펙트를 가지고 있습니다. 손에 있는 무기를 떼는 Detatch, 무기를 착용하는 InsertModel이 있습니다.
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
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponEffect : MonoBehaviour
{
private GameObject model;
public void Init()
{
this.transform.localPosition = Vector3.zero;
this.transform.localRotation = Quaternion.Euler(Vector3.zero);
this.transform.localScale = Vector3.one / 2f;
}
public void DetatchEffect()
{
if (this.model != null)
ObjectPool.GetInstance().ReleaseAsset(this.model);
}
public void InsertModel(int effectId)
{
var data = DataManager.Instance.GetDataById<EffectData>(effectId);
this.model = ObjectPool.GetInstance().GetAsset(data.res_name);
model.transform.SetParent(this.transform, false);
}
public void ChangeEffect(int effectId)
{
this.DetatchEffect();
this.InsertModel(effectId);
}
public void SetPosition(int weaponId)
{
var weapon = DataManager.Instance.GetDataById<WeaponData>(weaponId);
this.transform.localPosition = new Vector3(weapon.effect_xpos, weapon.effect_ypos, 0);
this.transform.rotation = Quaternion.Euler(Vector3.zero);
}
}
|
cs |
WeaponEffect.cs 입니다.
무기에 붙을 이펙트 오브젝트를 가지고 있습니다.
이 역시 무기처럼 붙였다 뗐다 하며 무기 변경시 json에 등록된 이펙트 번호를 찾아가 해당 이펙트로 변경
하도록 했습니다.
Unity Study_013-2 마우스 클릭 좌표 이동 (0) | 2020.05.26 |
---|---|
Unity Study_013-1 로그인 구현 (0) | 2020.05.22 |
Unity Study_006 Effect and WeaponChange (0) | 2020.05.13 |
Study_004 - UnityActionExmaple (0) | 2020.05.11 |
Unity Study_003 5Run (0) | 2020.05.08 |