Commit dda3dbc8 authored by 18손재민's avatar 18손재민

Merge branch 'enemy'

parents 5e04126a f8d02add
monsterid,name,itemid,prob
1,몬스터1,2,0.3
2,몬스터2,5,0.5
3,몬스터3,4,1
\ No newline at end of file
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Random = UnityEngine.Random;
public class Enemy : MonoBehaviour { public class Enemy : MonoBehaviour {
// data
// health
private readonly float maxHealth;
private readonly float weight;
public float playerMaxHealth; //다른 스크립트에 있는 플레이어 최대체력 가져와야함
private float currHealth;
// unit distance when get damaged
static readonly float unitDist = 3;
// debuff
float[] immunity_time = new float[5] { 0.0f, 3.0f, 6.0f, 6.0f, 6.0f };//면역 시간
bool[] immunity = new bool[] { false, }; //현재 에너미가 디버프 상태에 대해서 면역인지를 체크하는 변수
enum debuffCase { fire, ice, stun, blind, charm };
// enemy manager
private readonly EnemyManager enemyManager = EnemyManager.Instance;
// action
private EnemyManager.State currState;
private Dictionary<EnemyManager.State, EnemyManager.Action> actionByState;
// drop item
private readonly EnemyManager.DropItemInfo dropItem; // [item ID, probability]
// method
// constructor
public Enemy(int id, float maxHealth, float weight) {
this.maxHealth = maxHealth;
this.weight = weight;
this.currHealth = maxHealth;
EnemyManager.DropItemInfo dropItem_temp;
this.dropItem = (enemyManager.dropTableByID.TryGetValue(id, out dropItem_temp)) ?
dropItem_temp : new EnemyManager.DropItemInfo(-1, -1);
this.actionByState = enemyManager.actionDictByID[id];
this.currState = EnemyManager.State.Idle;
}
// hit by player or debuff
public void GetDamaged(float damage) {
currHealth -= damage;
if(currHealth <= 0) {
if (dropItem.id != -1)
{
float dropProb = Random.Range(0.0f, 1.0f);
if (dropProb < dropItem.prob)
{
// spawn a item that has ID
}
}
Destroy(gameObject);
return;
}
float knockback_dist = damage * unitDist / weight;
// do something - knockback animation
}
struct EnemyDebuffed
{
public debuffCase Case;
public float debuffTime;
}
IEnumerator DebuffCase(EnemyDebuffed sCase)
{
if (sCase.Case == debuffCase.fire)
{
StartCoroutine(OnFire(sCase));
}
else if (sCase.Case == debuffCase.ice && !immunity[(int)debuffCase.ice])
{
//Enemy 정지하는 코드 필요
immunity[(int)debuffCase.ice] = true;
yield return StartCoroutine(DebuffDoing(sCase));
}
else if (sCase.Case == debuffCase.stun && !immunity[(int)debuffCase.stun])
{
//Enemy 정지하는 코드 필요
immunity[(int)debuffCase.stun] = true;
yield return StartCoroutine(DebuffDoing(sCase));
}
else if (sCase.Case == debuffCase.blind && !immunity[(int)debuffCase.blind])
{
//Enemy의 공격이 적중하지 않는 코드 필요
immunity[(int)debuffCase.stun] = true;
yield return StartCoroutine(DebuffDoing(sCase));
}
else if (sCase.Case == debuffCase.charm && !immunity[(int)debuffCase.charm])
{
//Enemy 공격이 플레이어 회복하는 코드 필요
immunity[(int)debuffCase.stun] = true;
yield return StartCoroutine(DebuffDoing(sCase));
}
}
IEnumerator OnFire(EnemyDebuffed sCase)
{
for (int i = 0; i < sCase.debuffTime / 1; i++)
{
yield return new WaitForSeconds(1.0f);
currHealth = currHealth - playerMaxHealth / 10;
}
}
IEnumerator DebuffDoing(EnemyDebuffed sCase)
{
yield return new WaitForSeconds(sCase.debuffTime);
yield return StartCoroutine(DebuffEnd(sCase));
}
IEnumerator DebuffEnd(EnemyDebuffed sCase)
{
//다시 동작하는 코드 필요
yield return StartCoroutine(ImmunityTimer(sCase));
}
IEnumerator ImmunityTimer(EnemyDebuffed sCase)
{
yield return new WaitForSeconds(immunity_time[(int)sCase.Case]);
immunity[(int)sCase.Case] = false;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
} }
//얼음일때 깨어나기
//공격이 적중했을 때 매혹에서 깨어나기
\ No newline at end of file
using System.Collections; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using System.IO;
using System.Text;
public class EnemyManager : MonoBehaviour {
// Use this for initialization public class EnemyManager : Singleton<EnemyManager>
void Start () { {
// static variable
} // about action
public enum State
// Update is called once per frame {
void Update () { Idle,
Track,
} Attack
} // 상속을 통해 수정할 가능성 높음. 염두만 해 두자.
public enum ItemType { None, OneStone, TwoStone, ThreeStone, FourStone,
FiveStone, GoldPotion, AmethystPotion, CommonItem, RareItem,
EpicItem, LegendaryItem, CommonAdd, RareAdd, EpicAdd,
LegendaryAdd }
public delegate void Action();
// data
// dictionary
public readonly Dictionary<int, Dictionary<ItemType, int>> dropTableByID;
public readonly Dictionary<int, Dictionary<State, Action>> actionDictByID;
public readonly Dictionary<int, float[]> enemyDataByID;
// method
// constructor
protected EnemyManager()
{
string dropTableDataPath = "";
string actionTableDataPath = "";
LoadDropTable(dropTableDataPath);
}
// Load Dictionary
private void LoadDropTable(string dataPath)
{
StreamReader strReader = new StreamReader(dataPath, Encoding.UTF8);
string[] cellValue = null;
string tableLine = null;
strReader.ReadLine();
Dictionary<ItemType, int> dropItemInfo = new Dictionary<ItemType, int>();
while ((tableLine = strReader.ReadLine()) != null)
{
if (string.IsNullOrEmpty(tableLine)) return;
cellValue = tableLine.Split(',');
int enemyID = -1;
int[] weight = {-1};
int sum = 0;
int[] cumulatedWeight = { -1 };
int.TryParse(cellValue[0], out enemyID);
for(int i=1;i<17;i++)
{
int.TryParse(cellValue[i+1], out weight[i]);
}
for(int i=0;i<16;i++)
{
sum += weight[i];
cumulatedWeight[i] = sum;
}
for(int i=0;i<16;i++)
{
dropItemInfo.Add((ItemType)i, cumulatedWeight[i]);
}
dropTableByID.Add(enemyID, dropItemInfo);
}
}
// Load ALL CSV Data
private void LoadEnemyData(string dataPath)
{
StreamReader strReader = new StreamReader(dataPath, Encoding.UTF8);
string[] cellValue = null;
string tableLine = null;
strReader.ReadLine();
while ((tableLine = strReader.ReadLine()) != null)
{
cellValue = tableLine.Split(',');
}
}
} }
using UnityEngine;
using System.Collections;
/// <summary>
/// Be aware this will not prevent a non singleton constructor
/// such as `T myT = new T();`
/// To prevent that, add `protected T () {}` to your singleton class.
/// As a note, this is made as MonoBehaviour because we need Coroutines.
/// </summary>
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
private static T _instance = null;
private static object _syncobj = new object();
private static bool appIsClosing = false;
public static T Instance {
get {
if (appIsClosing)
return null;
lock (_syncobj) {
if (_instance == null) {
T[] objs = FindObjectsOfType<T>();
if (objs.Length > 0)
_instance = objs[0];
if (objs.Length > 1)
Debug.LogError("There is more than one " + typeof(T).Name + " in the scene.");
if (_instance == null) {
string goName = typeof(T).ToString();
GameObject go = GameObject.Find(goName);
if (go == null)
go = new GameObject(goName);
_instance = go.AddComponent<T>();
}
}
return _instance;
}
}
}
/// <summary>
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
/// If any script calls Instance after it have been destroyed,
/// it will create a buggy ghost object that will stay on the Editor scene
/// even after stopping playing the Application. Really bad!
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
protected virtual void OnApplicationQuit() {
// release reference on exit
appIsClosing = true;
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: a4301571906f4094aba1a7696df8d3ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment