/** 8. 우박: 하늘에서 우박이 떨어진다. * @param Distance Distance 플레이어와 HailStoneSpawner 사이의 거리 * @param Height HailStoneSpawner의 높이 */ private void _Skill_NORMAL_SPW_01(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { //distance랑 height 값도 나중엔 whichSkill에서 긁어오거나 PMS_Math에서 긁어올 것 float distance = 10.0f; float height = 10.0f; bool isPlayerUsing; //플레이어면 플레이어가 사용했다는 정보를 전달 if (playerController != null) { isPlayerUsing = true; } //플레이어가 아니면 Enemy가 사용했다는 정보를 전달 else { isPlayerUsing = false; } // 스포너 프리팹 가져오기 GameObject spawnerPrefab = (GameObject)Resources.Load("Prefabs/SpawnArea/Hailstone Spawner"); Vector3 spawnPosition = transform.position + transform.forward * distance + new Vector3(0, height, 0); GameObject spawned_Area; spawned_Area = (GameObject)(Instantiate(spawnerPrefab, spawnPosition, transform.rotation)); spawned_Area.GetComponent <HailStoneSpawner>().__Init_HailStoneSpawner(whichSkill, _unit_Stat.__PUB_ATK__Val, isPlayerUsing); }
//public IEnumerator HealPowerRepeat(float duringTime, float freqTime, int Amount, int isHit_OR_Heal) //{ // // 파워를 올리고 내리고를 얼마나 반복할 것인지 계산 // int howMany = (int)(duringTime / freqTime); // for (int i = 0; i < howMany; i++) // { // //올리고자 하는 값을 올린다. (isHit_OR_Heal 값에 따라 딜 또는 힐로 연산된다.) // HealPower(Amount, isHit_OR_Heal); // Debug.Log("Get Mana Healed"); // //위의 작업을 일정 시간 마다 반복한다. // yield return new WaitForSeconds(freqTime); // } // //해당 코루틴 자동 종료 // yield break; //} //마나를 사용할 때, 마나가 충분한지 확인하는 함수 OR 궁극기를 사용할 때 궁극기 게이지가 충분한지 확인하는 함수 public bool __Is_Mana_Enough(SkillBaseStat whichSkill) { bool result; //궁극기가 아닐 때 if (whichSkill.__GET_Skill_Code_M != SkillBaseCode._SKILL_CODE_Main.FIN) { if (__Mana_Point >= whichSkill.__GET_Skill_Use_Amount) { result = true; } else { result = false; } } //궁극기일 때 else { if (__Power_Point >= whichSkill.__GET_Skill_Use_Amount) { result = true; } else { result = false; } } return(result); }
//산탄(5번, "00000005") 스킬과 속사(6번, "00000006") 스킬을 통합한 것 private void _Skill_NORMAL_ATK_00(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { Vector2 valueVec2 = Rotation_Math.Rotation_AND_Position(attacker.rotation, 0.58f, 0.0f); float posX = attacker.position.x; float posZ = attacker.position.z; //나중엔 int indexMax = whichSkill.ammoAmount; int indexMax = (int)(whichSkill.__GET_Skill_Rate); int posHelper = -1; //산탄 스킬이면 1, 속사스킬이면 -1 int isShotGun_OR_FastGun = 1; //보정된 x, z 좌표값 float newX; float newZ; //일단 지정된 attacker(캐릭터의 전면부)에서 3개의 기본 탄환을 서로 각 사선에 평행하도록 발사할 것. //탄환을 몇 개 발사할 것인지는 나중에 SkillBaseStat에서 읽어올 것 //일단 3개니까 이렇게 작성할 것 //본 함수의 0.58f와 1.16f, 이 두 수치에 대해서는 나중에 namespace ConstValueCollection에서 const float spawnDist 변수를 만들어서 관리할 것 //indexMax 값 변형 -> 홀수여야만 정상작동 indexMax = (indexMax - 1) / 2; //속사 스킬이면 if (whichSkill.__Get_Skill_ID == "00000006") { //속사 스킬의 경우, 앞에서 발사하는 경우 좌표 값 보정 예시 (탄환 개수가 최대 3개일때, 보정해야 되는 지점) //_unit_Combat_Engine.Default_ATK(ref attacker, new Vector3(posX + valueVec2.y, attacker.position.y, posZ + valueVec2.x), attacker.rotation, whichSkill); //_unit_Combat_Engine.Default_ATK(ref attacker, new Vector3(posX - valueVec2.y, attacker.position.y, posZ - valueVec2.x), attacker.rotation, whichSkill); //값을 바꿔치기 해서 위의 보정 예시가 아래 반복문에서 적용되도록 한다. valueVec2.Set(valueVec2.y, valueVec2.x); //z 좌표 보정 수식의 부호를 바꿔준다. isShotGun_OR_FastGun = -1; } //산탄 스킬의 경우, 앞에서 발사하는 경우 좌표 값 보정 예시 (탄환 개수가 최대 3개일 때, 보정해야 되는 지점) //_unit_Combat_Engine.Default_ATK(ref attacker, new Vector3(posX + valueVec2.x, attacker.position.y, posZ - valueVec2.y), attacker.rotation, whichSkill); //_unit_Combat_Engine.Default_ATK(ref attacker, new Vector3(posX - valueVec2.x, attacker.position.y, posZ + valueVec2.y), attacker.rotation, whichSkill); //음수부터 반복문을 돌린다 for (int index = -indexMax; index < indexMax + 1; index++) { //x, z 좌표값 보정 newX = posX - (valueVec2.x * posHelper * index); //속사 (6번, "00000006")스킬인 경우 //newZ = posZ - (valueVec.y * posHelper * index)가 된다 (isShotGun_OR_FastGun == -1) newZ = posZ + (valueVec2.y * posHelper * index) * isShotGun_OR_FastGun; _unit_Combat_Engine.Default_ATK(ref attacker, new Vector3(newX, attacker.position.y, newZ), attacker.rotation, whichSkill); posHelper *= (-1); } }
//스킬 이름으로 특정 SkillBaseStat을 찾는 함수 private SkillBaseStat Search_SkillBaseStat_BY_Name_IN_List(string skillName, List <SkillBaseStat> searchedList) { SkillBaseStat resultSBSt = new SkillBaseStat(); foreach (SkillBaseStat sBSt in searchedList) { if (skillName == sBSt.__GET_Skill_Name) { resultSBSt = sBSt; break; } } return(resultSBSt); }
//스피드 버프 또는 디버프에 대한 함수 (이동속도 값을 직접적으로 제어) public void __GET_BUFF__About_Speed(int isBuff_OR_DeBuff, SkillBaseStat whichSkill) { try { //whichSkill의 _Skill_Rate 값을 곱한만큼으로 이동속도와 회전속도를 증감한다. //(적용될 이동속도) += (유닛의 원래 이동속도) * (스킬 계수) //(적용될 회전속도) += (유닛의 원래 회전속도) * (스킬 계수) _unit_Base_Engine._unit_Stat.__PUB_Move_Speed += _unit_Base_Engine._unit_Stat.__GET_FOriginalMoveSpeed * whichSkill.__GET_Skill_Rate * isBuff_OR_DeBuff; _unit_Base_Engine._unit_Stat.__PUB_Rotation_Speed += _unit_Base_Engine._unit_Stat.__GET_FOriginalRotateSpeed * whichSkill.__GET_Skill_Rate * isBuff_OR_DeBuff; //지속시간 계산 //player인 경우 if (_unit_Base_Engine.playerController != null) { _unit_Base_Engine.StartCoroutine( _unit_Base_Engine.playerController.__PLY_CoolTimer.Timer_Do_Once( whichSkill.__GET_Skill_ING_Time, (input) => { _unit_Base_Engine.coolTimeCheck = input; }, _unit_Base_Engine.coolTimeCheck, _unit_Base_Engine.TimeCodeToINT(COOL_TIME_CODE.SP) ) ); } //enemy인 경우 else if (_unit_Base_Engine.enemyController != null) { _unit_Base_Engine.StartCoroutine( _unit_Base_Engine.enemyController.GET_enemyAIEngine.enemyCoolTimer.Timer_Do_Once( whichSkill.__GET_Skill_ING_Time, (input) => { _unit_Base_Engine.coolTimeCheck = input; }, _unit_Base_Engine.coolTimeCheck, _unit_Base_Engine.TimeCodeToINT(COOL_TIME_CODE.SP) ) ); } //오류 else { } } //isBuff_OR_DeBuff 값이 1 또는 -1이 아니면 적용되는 Exception으로 대체 예정 //또는 _unit_Base_Engine.playerController == null && _unit_Base_Engine.enemyController == null 인 경우 catch (System.Exception) { //아무것도 안 한다. } }
public void Initialize_U_Skill(SkillBaseStat whichSkill, bool isPlayerUsingThis_Input) { thisSkillStat = whichSkill; //나중엔 UltimateSkill DB를 따로 만들거나 기존의 SKill DB에 부가 효과에 대한 정보를 입력하고 거기서 읽어올 것. //아래 조치는 임시 조치 //이속 디버프 추가 subSkillStats.Add(IO_CSV.__Get_Searched_SkillBaseStat("NORMAL_SP_01")); //차이 확인을 위해 임의로 값을 변경한다. (상대 이속 & 회전속도를 70% 감소시키는 디버프) subSkillStats[0].__SET_Skill_Rate = 0.7f; isPlayerUsingThis = isPlayerUsingThis_Input; Destroy(gameObject, whichSkill.__GET_Skill_ING_Time); }
//SP(이동속도)에 관여하는 스킬들 private void _Skill_NORMAL_SP_00(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { int isBuFF_OR_DeBuff = 0; //SP(이동속도) 버프 스킬 OR 플레이어가 SP(이동속도) 디버프를 받았을 때 if (whichSkill.__GET_Skill_Code_M == _SKILL_CODE_Main.BUF || !(isUnitUsingThis)) { //이미 이동속도 버프나 디버프를 받는 중이 아니면 if (!(CoolTimeCheck(COOL_TIME_CODE.SP))) { //유닛이 사용한 거면 if (isUnitUsingThis) { //__GET_BUFF__About_Speed가 SP(이동속도) 버프를 수행한다. isBuFF_OR_DeBuff = 1; } //유닛이 SP(이동속도) 디버프 스킬에 피격된 거면 else if (!(isUnitUsingThis)) { //__GET_BUFF__About_Speed가 SP(이동속도) 디버프를 수행한다. isBuFF_OR_DeBuff = -1; } //오류 else { } //이동속도 버프 OR 디버프를 수행한다. _unit_Move_Engine.__GET_BUFF__About_Speed(isBuFF_OR_DeBuff, whichSkill); } //이미 이동속도 버프나 디버프를 받고 있는 중이면 else { //Debug.Log("이동속도 버프, 디버프 중첩 방지"); } } //유닛이 상대에게 SP(이동속도) 디버프를 걸 때 스킬 else if (whichSkill.__GET_Skill_Code_M == _SKILL_CODE_Main.DBF) { _unit_Combat_Engine.Default_ATK(ref attacker, whichSkill); } //오류 else { } }
//투사체가 수행하는 연산을 위한 값 초기화 public void __Init_Ammo(EnemyController _enemy, float speed, string tag, int damage, float criRate, float criPoint, SkillBaseStat skillStat = null) { __Ammo_Speed = speed; __Who_Shot = tag; __Ammo_Damage = damage; enemyAI = _enemy.PUB_enemyAI; if (_enemy.PUB_enemyAI == null) { Debug.Log(_enemy.GetInstanceID()); } if (enemyAI == null) { Debug.Log(enemyAI.GetInstanceID()); } //디버프가 딸린 투사체면 if (skillStat != null) { //디버프 정보를 가져온다. whichSkill = skillStat; } //평범한 투사체면 else { //해당 정보를 비운다. whichSkill = null; } //투사체가 생성되는 시점에서 크리티컬 여부를 판별한다. if (Random.Range(0.0f, 1.0f) <= criRate) { __Ammo_Damage = (int)(__Ammo_Damage * criPoint); isItCritical = true; } else { isItCritical = false; } }
//지형 소환 //Enemy의 경우 마우스를 이용한 투사체가 아닌 물체 소환을 수행할 이유가 없으므로 신경쓰지 않는다. //7번 스킬 지형소환처럼 마우스로 투사체가 아닌 물체를 소환하는 스킬 private void _Skill_NORMAL_SPW_00(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { //player인 경우 if (playerController != null) { playerController._Set_SPW_MOS_Skill_Activated = true; } //따로 만들어둔 SampleConstructedOBJ를 소환하도록 한다. GameObject constructedOBJ = Resources.Load(_unit_Combat_Engine.__GET_prefabBulletPath + "SampleConstructedOBJ") as GameObject; //소환할 오브젝트 소환하고 값 설정 GameObject spawned_OBJ; spawned_OBJ = (GameObject)(MonoBehaviour.Instantiate(constructedOBJ, playerController.transform.position, playerController.transform.rotation)); spawned_OBJ.GetComponent <ConstructedOBJ>().__Init_ConstructedOBJ(whichSkill, playerController); //SpawnHailstoneSpawner 내용을 여기로 이식할 것 //또는 별도 함수로 독립 시키고 이 함수를 간략화할 것 }
//void OnTriggerExit(Collider other) //{ // if (other.transform.tag == "Boundary") // { // //StartCoroutine(enemyController.enemyCoolTimer.Timer_Do_Once(6.0f, (input) => { isEnd_OF_Stage = input; }, true)); // } //} private void EnemyUsingSkill(int index, Transform enemyAttacker, SkillBaseStat whichSkill) { //쿨타임이 지났을 때 if (_enemyAIEngine._PUB_enemy_Is_ON_CoolTime[index]) { //마나가 충분할 때 if (enemyStat.__Is_Mana_Enough(whichSkill)) { //필요한 마나 또는 궁극기 게이지 소모 if (whichSkill.__GET_Skill_Code_M != SkillBaseCode._SKILL_CODE_Main.FIN) { enemyStat.__Get_HIT__About_Mana(whichSkill.__GET_Skill_Use_Amount, 1); } else { enemyStat.__Get_HIT__About_Power(whichSkill.__GET_Skill_Use_Amount, 1); } //UnitBaseEngine.Using_Skill에서 스킬 기능 처리 _enemyAIEngine._unitBaseEngine._unit_Combat_Engine.Using_Skill(ref enemyAttacker, whichSkill, true); //쿨타임 관련 처리 StartCoroutine( enemyController.enemyCoolTimer.Timer(whichSkill.__GET_Skill_Cool_Time, (input) => { _enemyAIEngine._PUB_enemy_Is_ON_CoolTime[index] = input; }, _enemyAIEngine._PUB_enemy_Is_ON_CoolTime[index]) ); } //마나가 부족할 때 else { Debug.Log("Not Enough Mana"); } } //쿨타임이 아직 안 지났을 때 else { //Debug.Log("CoolTime is not Over"); } }
//궁극기 - 폭풍우 (광범위 이속 디버프) private void _Skill_FIN000(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { bool isPlayerUsingThis; //플레이어면 if (playerController != null) { isPlayerUsingThis = true; } //플레이어가 아니면 else { isPlayerUsingThis = false; } //프리팹을 소환하고 필요한 정보들을 프리팹에 보낸다. GameObject ultimateSkillPrefab = (GameObject)(Resources.Load("Prefabs/SpawnArea/UltimateSkill_Storm")); GameObject spawnedUltimateSkill; spawnedUltimateSkill = Instantiate(ultimateSkillPrefab, transform.position, new Quaternion()) as GameObject; spawnedUltimateSkill.GetComponent <UltimateSkillBase>().Initialize_U_Skill(whichSkill, isPlayerUsingThis); }
/** 기에 관여하는 스킬 * @param duringTime 회복 또는 감소 지속시간 * @param freqTime 다음 회복 또는 감소까지의 시간 * @param Amount 한 번 회복하거나 감소하는 기의 양 * @param isUnitUsingThis 기 회복(true), 기 감소(false) */ private void _Skill_NORMAL_PP_00(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { int isHIT_OR_Heal; if (isUnitUsingThis) { isHIT_OR_Heal = -1; } else { isHIT_OR_Heal = 1; } //기가 주기적으로 상승/감소한다. // 후에 SkillBaseStat에 _Skill_FREQ_Time 변수를 새로 만들것 StartCoroutine( _unit_Stat.__Get_HIT__About_Power_FREQ( whichSkill.__GET_Skill_ING_Time, 1.0f, (int)(whichSkill.__GET_Skill_Rate), isHIT_OR_Heal) ); }
//투사체를 발사할 때 발사 위치와 발사 방향을 따로 지정할 필요가 없는 경우 public void Default_ATK(ref Transform attacker, SkillBaseStat whichSkill) { //GameObject threw_Ammo =; GameObject spawned_OBJ, effect; spawned_OBJ = (GameObject)(MonoBehaviour.Instantiate(Resources.Load(prefabBulletPath + "SampleBullet") as GameObject, attacker.position, attacker.rotation)); //effect effect = (GameObject)(MonoBehaviour.Instantiate(Resources.Load("Prefabs/Effect/Explosion") as GameObject, attacker.position, attacker.rotation)); effect.GetComponent <Explosion>().source = unit_Base_Engine.transform; MonoBehaviour.Instantiate(Resources.Load("Prefabs/Effect/Explo") as GameObject, attacker.position, attacker.rotation); //투사체가 날아가는 속도를 특정 값으로 설정. 나중엔 DB에서 긁어올 것 if (unit_Base_Engine.enemyController != null) { spawned_OBJ.GetComponent <AmmoBase>().__Init_Ammo( unit_Base_Engine.enemyController, 55.0f, attacker.tag, unit_Base_Engine._unit_Stat.__PUB_ATK__Val, unit_Base_Engine._unit_Stat.__PUB_Critical_Rate, unit_Base_Engine._unit_Stat.__PUB_Critical_P, whichSkill ); } else { spawned_OBJ.GetComponent <AmmoBase>().__Init_Ammo( 55.0f, attacker.tag, unit_Base_Engine._unit_Stat.__PUB_ATK__Val, unit_Base_Engine._unit_Stat.__PUB_Critical_Rate, unit_Base_Engine._unit_Stat.__PUB_Critical_P, whichSkill ); } }
//나중엔 DB에서 긁어온 값을 여기서 초기화할 것. void Awake() { //이속, 회전속도, 체력, 마나, 파워 게이지, 공격력, 크리확률, 크리계수 //__PLY_Stat.SampleInit(10.0f, 30.0f, 10, 10, 10, 1, 0.1f, 2.0f); //UnitBaseEngine에 Player라고 알려준다. __PLY_Engine = transform.GetComponent <UnitBaseEngine>(); //Unit__Base_Combat_Engine이 Unit__Base_Movement_Engine과 __PLY_SKill_Engine에 접근 할 수 있도록 한다. __PLY_Engine.playerController = this; __PLY_Engine._unit_Combat_Engine.__SET_unit_Base_Engine = __PLY_Engine; __PLY_Engine._unit_Move_Engine._SET_unit_Base_Engine = __PLY_Engine; __PLY_Engine._unit_Move_Engine.movingEffect = this.movingEffect; //UnitBaseEngine이 Unit__Base_Stat 내용에 접근할 수 있도록 한다. __PLY_Engine._unit_Stat = __PLY_Stat; //---------------------------------------------------------------------------------------- ////확인용. 정상적으로 작동함. //foreach (SkillBaseStat forDebug in __PLY_Selected_Skills) //{ // Debug.Log("ID: " + forDebug.__Get_Skill_ID + ", Name: " + forDebug.__GET_Skill_Name + ", Rate:" + forDebug.__GET_Skill_Rate); // Debug.Log("CoolT: " + forDebug.__GET_Skill_Cool_Time + ", IngT: " + forDebug.__GET_Skill_ING_Time + ", UseAmount:" + forDebug.__GET_Skill_Use_Amount); // Debug.Log("Code_Main: " + forDebug.__GET_Skill_Code_M + ", Code_Sub: " + forDebug.__GET_Skill_Code_S + ", Code_Time:" + forDebug.__GET_Skill_Code_T); //} //궁극기 임시 조치 debugUltimateSkill = File_IO.IO_CSV.__Get_Searched_SkillBaseStat("FIN000"); _Is_On_CoolTime__Default_ATK = true; for (int i = 0; i < _Is_On_CoolTime_Skill.Length; i++) { _Is_On_CoolTime_Skill[i] = true; } }
//투사체가 수행하는 연산을 위한 값 초기화 public void __Init_Ammo(float speed, string tag, int damage, float criRate, float criPoint, SkillBaseStat skillStat = null) { __Ammo_Speed = speed; __Who_Shot = tag; __Ammo_Damage = damage; //디버프가 딸린 투사체면 if (skillStat != null) { //디버프 정보를 가져온다. whichSkill = skillStat; if (whichSkill.__Get_Skill_ID == "NORMAL_HP_01") { __Ammo_Damage = (int)(whichSkill.__GET_Skill_Rate); } } //평범한 투사체면 else { //해당 정보를 비운다. whichSkill = null; } //투사체가 생성되는 시점에서 크리티컬 여부를 판별한다. if (Random.Range(0.0f, 1.0f) <= criRate) { __Ammo_Damage = (int)(__Ammo_Damage * criPoint); isItCritical = true; } else { isItCritical = false; } }
public void __Init_HailStoneSpawner(SkillBaseStat whichSkill, int damage, bool isPlayerUsing_input) { FSpawnNumber = (int)(whichSkill.__GET_Skill_ING_Time / FSpawnTime); skill_Damage = (int)(damage * whichSkill.__GET_Skill_Rate); isPlayerUsing = isPlayerUsing_input; }
//스킬 사용 버튼을 누르자마자 필요한 정보 받아올 것 public void __Init_ConstructedOBJ(SkillBaseStat _whichSkill, PlayerController _player) { whichSkill = _whichSkill; player = _player; }
//Enemy가 디버프 스킬에 피격받았을 때의 함수 public void _Enemy__GET_DeBuff(SkillBaseStat whichDeBuffSkill_Hit_Enemy) { enemyAIEngine._unitBaseEngine._unit_Combat_Engine.Using_Skill(ref enemy_Front, whichDeBuffSkill_Hit_Enemy, false); //_unitBaseEngine.__ENE_C_Engine.Using_Skill_ENE(ref enemy_Front, whichDeBuffSkill_Hit_Enemy, enemyStat, this, false); }
//플레이어가 디버프 스킬에 피격받았을 때의 함수 public void _Player_GET_DeBuff(SkillBaseStat whichDeBuffSkill_Hit_Player) { //Debug.Log("================================================================"); __PLY_Engine._unit_Combat_Engine.Using_Skill(ref playerAttacker, whichDeBuffSkill_Hit_Player, false); isPlayerHitUltimateSkill = true; }
//================================================================================================================================================================================= //이하 스킬 함수들 //================================================================================================================================================================================= //Unit__Combat_Engine에 있는 스킬 함수들 이식, 스킬 함수 호출 방법을 Reflection으로 통일 //HP쪽 스킬들처럼 한 함수가 두 가지 이상의 일을 하는 경우에는 일단 "00000000" || "00000001" 인 경우 모두 "00000000"으로 해석하도록 임시 조치를 취할 것 //HP에 관여하는 스킬들 private void _Skill_NORMAL_HP_00(Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { int isHit_OR_Heal = 0; //도트 힐 OR 도트 딜 if (whichSkill.__GET_Skill_Code_T == _SKILL_CODE_Time.FREQ) { //도트 힐 스킬을 사용할 때 OR 도트 딜 디버프를 받았을 때 if (whichSkill.__GET_Skill_Code_M == _SKILL_CODE_Main.BUF || !(isUnitUsingThis)) { //이미 체력 버프나 디버프를 받는 중이 아니면 if (!(CoolTimeCheck(COOL_TIME_CODE.HP))) { //플레이어가 사용한 HP 도트 힐 스킬이면 if (isUnitUsingThis) { //__Get_HIT__About_Health_FREQ가 HP 도트 힐을 수행하도록 한다. isHit_OR_Heal = -1; } //플레이어가 HP 도트 딜 스킬에 피격된 거면 else if (!(isUnitUsingThis)) { //__Get_HIT__About_Health_FREQ가 HP 도트 딜을 수행하도록 한다. isHit_OR_Heal = 1; } //오류 else { } //StartCoroutine 때문에 PlayerController를 받아와서 이렇게 이상한 형태로 작업함. 후에 다른 방법 알아낸다면 수정 필요 //차선책으로 클래스 간 상속 구조를 뜯어고치고 UnitBaseEngine을 각 Object에 직접 추가하여 StartCoroutine함수를 this.StartCoroutine(...)으로 개편하고 //__PLY_Stat은 UnitBaseEngine에 변수를 따로 만들어서 함수 인자로 전달받지 말고 클래스 내에서 직접 가져다 쓸 것 => Enemy와 Player 간의 함수 통합 이슈 자체가 사라짐 StartCoroutine( _unit_Stat.__Get_HIT__About_Health_FREQ( whichSkill.__GET_Skill_ING_Time, 1.0f, (int)(whichSkill.__GET_Skill_Rate), isHit_OR_Heal ) ); } //이미 체력 버프나 디버프를 받고 있는 중이면 else { Debug.Log("체력 버프, 디버프 중첩 방지"); } } //상대에게 도트 딜을 넣을 스킬 else if (whichSkill.__GET_Skill_Code_M == _SKILL_CODE_Main.DBF) { //디버프가 담긴 하나의 투사체를 발사한다. //투사체의 외형 바꾸기는 일단 넘어갈 것. _unit_Combat_Engine.Default_ATK(ref attacker, whichSkill); } //오류 else { } } }
//하나의 투사체를 일직선 상으로 발사하는 기본 공격 (디버프 유무를 나중에 추가할 것) //투사체를 발사할 때 발사 위치와 발사 방향을 따로 지정해줘야 되는 경우 public void Default_ATK(ref Transform attacker, Vector3 spawnPosition, Quaternion spawnRotation, SkillBaseStat whichSkill) { //"Assets/Resources/Prefabs/Bullets" 경로에서 직접 Prefab을 뽑아쓰는 쪽으로 변경 //Resources.Load를 쓸 때는 "Assets/Resources" 경로 내부의 파일에만 접근할 수 있으며 //Resources.Load("Assets/Resources/<임의폴더0>/<임의폴더1>/<읽으려는거>") 이렇게 쓰면 안 되고 //Resources.Load("<임의폴더0>/<임의폴더1>/<읽으려는거>") as <자료형> 이런 식으로 써야 된다. //읽으려는게 "Assets/Resources" 안에 있지만 그 하위 폴더에 없는 거면 //Resources.Load("<읽으려는거>") as <자료형> 이렇게 쓰면 된다. //GameObject threw_Ammo = ; //나중에는 SkillBaseStat에 private string bulletName 변수를 만들고 그것을 읽어오도록 할 것 //예시) GameObject threw_Ammo = Resources.Load(prefabBulletPath + whichSkill.bulletName) as GameObject; //private string bulletName 변수는 Sample__SkillDataBase.csv에서 읽어오도록 만들것 GameObject spawned_OBJ, effect; spawned_OBJ = (GameObject)(MonoBehaviour.Instantiate(Resources.Load(prefabBulletPath + "SampleBullet") as GameObject, spawnPosition, spawnRotation)); //effect effect = (GameObject)(MonoBehaviour.Instantiate(Resources.Load("Prefabs/Effect/Explosion") as GameObject, spawnPosition, spawnRotation)); effect.GetComponent <Explosion>().source = unit_Base_Engine.transform; MonoBehaviour.Instantiate(Resources.Load("Prefabs/Effect/Explo") as GameObject, spawnPosition, spawnRotation); //투사체가 날아가는 속도를 특정 값으로 설정. 나중엔 DB에서 긁어올 것 if (unit_Base_Engine.enemyController != null) { spawned_OBJ.GetComponent <AmmoBase>().__Init_Ammo( unit_Base_Engine.enemyController, 55.0f, attacker.tag, unit_Base_Engine._unit_Stat.__PUB_ATK__Val, unit_Base_Engine._unit_Stat.__PUB_Critical_Rate, unit_Base_Engine._unit_Stat.__PUB_Critical_P, whichSkill ); } else { spawned_OBJ.GetComponent <AmmoBase>().__Init_Ammo( 55.0f, attacker.tag, unit_Base_Engine._unit_Stat.__PUB_ATK__Val, unit_Base_Engine._unit_Stat.__PUB_Critical_Rate, unit_Base_Engine._unit_Stat.__PUB_Critical_P, whichSkill ); } }
//스킬 사용시 모두 이 함수를 통함. public void Using_Skill(ref Transform attacker, SkillBaseStat whichSkill, bool isUnitUsingThis) { string funcName = "_Skill_"; //---------------------------------------------------------------- //아래 코드를 이용하여 player와 enemy 구분을 확인함 //Debug.Log(controller.ToString()); //Debug.Log(controller.GetType().ToString()); //스킬 통합이 완료되기 전까지 //if (_playerController != null) //{ // Debug.Log("Nogada_P"); //} //else if (_enemyController != null) //{ // Debug.Log("Enemy"); //} ////---------------------------------------------------------------- //임시 조치. 코드 정리 도중 ID 체계화 과정에서 수정 필수 //체력 회복(00000000), 디버프(00000001) if (whichSkill.__Get_Skill_ID == "NORMAL_HP_01") { funcName += "NORMAL_HP_00"; //Debug.Log("This is HP DeBuff Skill"); } //이동 속도 버프, 디버프 묶기 //이속 버프(00000002), 디버프(00000003) else if (whichSkill.__Get_Skill_ID == "NORMAL_SP_01") { funcName += "NORMAL_SP_00"; //Debug.Log("This is SP DeBuff Skill"); } //임시 조치. 코드 정리 중 ID 체계화 과정에서 수정 필수 //산탄(00000005), 속사(00000006) else if (whichSkill.__Get_Skill_ID == "NORMAL_ATK_01") { funcName += "NORMAL_ATK_00"; } else { funcName += whichSkill.__Get_Skill_ID; } //funcName = "_Skill_" + whichSkill.__Get_Skill_ID; //Reflection 기법에 대해선 아래 주소들 참고 //0. Reflection 기본 사용법 : http://www.vcskicks.com/call-function.php //1. private나 protected 함수에 대한 Reflection 사용법 : https://stackoverflow.com/questions/8413524/how-to-get-an-overloaded-private-protected-method-using-reflection System.Type type = unit_Base_Engine.GetType(); MethodInfo method = type.GetMethod(funcName); //protected나 private 함수에 접근할 수 있도록 하는 조치 BindingFlags eFlags = BindingFlags.Instance | BindingFlags.NonPublic; //접근을 위한 조치를 반영한다. method = typeof(UnitBaseEngine).GetMethod(funcName, eFlags); //funcName과 동일한 이름을 가진 함수를 unit_Skill_Engine에서 호출한다. method.Invoke(unit_Base_Engine, new object[] { attacker, whichSkill, isUnitUsingThis }); }