[Unity] Coroutine 사용해서 공격 애니메이션 실행시 문제, 공격 타이밍이 맞지 않음
APP 2019. 11. 15. 08:38문제 해결
https://koolwin1.tistory.com/249
코루틴 사용시 Attack()메서드 안에 elapsedTime을 계산해서 몬스터와 상호작용하고 있다.
이걸 각각의 코루틴을 사용하도록 고치면 될듯하다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Newtonsoft.Json;
public class App : MonoBehaviour
{
public Button btnStage;
public Button btnHero;
public Button btnMonster;
public Button btnAttack;
public Dictionary<int, CharacterData> dicCharacterData;
public Dictionary<int, StageData> dicStageData;
Dictionary<int, GameObject> dicPrefab;
private Stage stage;
private Dictionary<int, Character> dicCharacter;
private Vector3 heroPos;
private float speed = 0.05f;
private Hero hero;
private Monster monster;
private Animation heroAnim;
private Animation monsterAnim;
private bool IsHeroAnimPlaying = false;
private bool IsMonsterAnimPlaying = false;
float elapsedTime;
float monsterDmgElapsedTime;
int cnt;
Coroutine coMoveCharacter;
private void Awake()
{
this.dicCharacterData = new Dictionary<int, CharacterData>();
this.dicStageData = new Dictionary<int, StageData>();
this.dicPrefab = new Dictionary<int, GameObject>();
this.dicCharacter = new Dictionary<int, Character>();
CharacterData[] arrCharacterData = JsonConvert.DeserializeObject<CharacterData[]>(Resources.Load<TextAsset>("Data/character_data").text);
foreach (CharacterData data in arrCharacterData)
{
this.dicCharacterData.Add(data.id, data);
}
StageData[] arrStageData = JsonConvert.DeserializeObject<StageData[]>(Resources.Load<TextAsset>("Data/stage_data").text);
foreach (StageData data in arrStageData)
{
this.dicStageData.Add(data.id, data);
}
LoadCharacterPrefabs();
LoadStagePrefabs();
}
public void LoadCharacterPrefabs()
{
foreach (KeyValuePair<int, CharacterData> keyValuePair in dicCharacterData)
{
this.dicPrefab.Add(keyValuePair.Key, Resources.Load<GameObject>($"Prefabs/{keyValuePair.Value.prefab_name}"));
}
}
public void LoadStagePrefabs()
{
foreach (KeyValuePair<int, StageData> keyValuePair in dicStageData)
{
this.dicPrefab.Add(keyValuePair.Key, Resources.Load<GameObject>($"Prefabs/{keyValuePair.Value.prefab_name}"));
}
}
//Start is called before the first frame update
void Start()
{
btnStage.onClick.AddListener(() =>
{
Debug.Log("Stage버튼");
this.CreateStage(dicStageData[1000]);
});
btnHero.onClick.AddListener(() =>
{
Debug.Log("Hero버튼");
this.hero = this.CreateCharacter<Hero>(dicCharacterData[100]);
this.heroAnim = this.hero.GetComponentInChildren<Animation>();
dicCharacter[100].transform.SetParent(GameUtils.SearchHierarchyForBone(this.stage.transform, "HeroInitPos"), false);
this.btnAttack.gameObject.SetActive(true);
});
btnMonster.onClick.AddListener(() =>
{
Debug.Log("Monster버튼");
this.monster = this.CreateCharacter<Monster>(dicCharacterData[200]);
dicCharacter[200].transform.SetParent(GameUtils.SearchHierarchyForBone(this.stage.transform, "MonsterInitPos"), false);
this.monsterAnim = this.monster.GetComponentInChildren<Animation>();
});
btnAttack.onClick.AddListener(() =>
{
Debug.Log("Attack버튼");
//Debug.Log(Time.deltaTime);
coMoveCharacter = StartCoroutine("MoveCharacter");
StartCoroutine(Attack());
});
}
//Coroutine coroutine1;
//Coroutine coroutine2;
//float el1;
//float el2;
//public void Start()
//{
// coroutine1 = StartCoroutine(LoopA());
// coroutine2 = StartCoroutine(LoopB());
// // StartCoroutine(Stopp());
//}
//IEnumerator LoopA()
//{
// for (int i = 0; i < 20; i++)
// {
// print("i의 값 = " + i);
// print($" i: {el1 += Time.deltaTime}");
// yield return new WaitForEndOfFrame();
// }
//}
//IEnumerator LoopB()
//{
// for (int x = 0; x < 20; x++)
// {
// print("x의 값 = " + x);
// print($" x: {el2+=Time.deltaTime}");
// yield return new WaitForSeconds(1f);
// }
//}
//IEnumerator Stopp()
//{
// yield return new WaitForSeconds(1f);
// StopCoroutine(coroutine1);
// yield return new WaitForSeconds(2f);
// StopCoroutine(coroutine2);
//}
public void CreateStage(StageData stageData)
{
GameObject go = new GameObject(stageData.name);
Stage stage = go.AddComponent<Stage>();
GameObject model = Instantiate(dicPrefab[stageData.id]);
model.transform.SetParent(stage.transform, false);
model.transform.localPosition = Vector3.zero;
this.stage = stage;
}
public T CreateCharacter<T>(CharacterData characterData) where T : Character
{
GameObject go = new GameObject(characterData.name);
T character = go.AddComponent<T>();
GameObject model = Instantiate(dicPrefab[characterData.id]);
model.transform.SetParent(character.transform, false);
model.transform.localPosition = Vector3.zero;
dicCharacter.Add(characterData.id, character);
return character;
}
IEnumerator MoveCharacter()
{
while (true)
{
yield return new WaitForSeconds(0.02f);
//Debug.Log($"{Time.deltaTime}{Vector3.Distance(hero.transform.position, monster.transform.position) > dicCharacterData[100].atk_range} {Vector3.Distance(hero.transform.position, monster.transform.position)} {dicCharacterData[100].atk_range}");
if(Vector3.Distance(hero.transform.position, monster.transform.position) > dicCharacterData[100].atk_range)
{
this.hero.transform.position = Vector3.MoveTowards(this.hero.transform.position, this.monster.transform.position, speed);
if (IsHeroAnimPlaying == false)
{
this.heroAnim.Play("run@loop");
IsHeroAnimPlaying = true;
}
//Debug.LogFormat("Distance: {0}", Vector3.Distance(hero.transform.position, monster.transform.position));
if (Vector3.Distance(hero.transform.position, monster.transform.position) <= dicCharacterData[100].atk_range)
{
IsHeroAnimPlaying = false;
StopCoroutine(coMoveCharacter);
Debug.Log("StopCoroutine");
}
}
}
}
IEnumerator Attack()
{
while(true)
{
yield return new WaitForSeconds(0.02f);
if(Vector3.Distance(hero.transform.position, monster.transform.position) <= dicCharacterData[100].atk_range)
{
if (IsHeroAnimPlaying == false)
{
this.heroAnim.Play("attack_sword_02");
elapsedTime += Time.deltaTime;
}
if(IsHeroAnimPlaying==true)
{
elapsedTime += Time.deltaTime;
}
if (0.59f < elapsedTime && elapsedTime < 0.61f)
{
this.monsterAnim.Play("Anim_Damage");
IsMonsterAnimPlaying = true;
monsterDmgElapsedTime += Time.deltaTime;
//Debug.LogFormat("몬스터 애니메이션 ElapsedTime2 : {0}", elapsedTime2);
}
if(IsMonsterAnimPlaying)
{
monsterDmgElapsedTime += Time.deltaTime;
}
if (0.79f < elapsedTime && elapsedTime < 0.81f)
{
IsHeroAnimPlaying = false;
elapsedTime = 0;
}
if (0.447f < monsterDmgElapsedTime && monsterDmgElapsedTime < 0.477f)
{
//Debug.LogFormat("초기화시간 {0}", elapsedTime2);
this.monsterAnim.Play("Anim_Idle");
monsterDmgElapsedTime = 0;
}
}
}
}
//IEnumerator MoveCharacter()
//{
// while (true)
// {
// yield return new WaitForSeconds(0.02f);
// //Debug.Log($"Dist:{Vector3.Distance(hero.transform.position, monster.transform.position)} atk_range:{dicCharacterData[100].atk_range}");
// if (Vector3.Distance(hero.transform.position, monster.transform.position) > dicCharacterData[100].atk_range)
// {
// this.hero.transform.position = Vector3.MoveTowards(this.hero.transform.position, this.monster.transform.position, speed);
// if (IsHeroAnimPlaying == false)
// {
// IsHeroAnimPlaying = true;
// this.heroAnim.Play("run@loop");
// }
// }
// else if (Vector3.Distance(hero.transform.position, monster.transform.position) <= dicCharacterData[100].atk_range)
// {
// if (IsMonsterAnimPlaying == true)
// {
// elapsedTime2 += Time.deltaTime;
// }
// if (cnt == 0)
// {
// cnt++;
// this.heroAnim.Play("attack_sword_01");
// elapsedTime += Time.deltaTime;
// }
// elapsedTime += Time.deltaTime;
// if (0.256f < elapsedTime && elapsedTime < 0.276f)
// {
// this.monsterAnim.Play("Anim_Damage");
// IsMonsterAnimPlaying = true;
// elapsedTime2 += Time.deltaTime;
// Debug.LogFormat("맞는시간{0}", elapsedTime2);
// }
// if (0.447f < elapsedTime2 && elapsedTime2 < 0.477f)
// {
// Debug.LogFormat("초기화시간{0}", elapsedTime2);
// this.monsterAnim.Play("Anim_Idle");
// elapsedTime2 = 0;
// Debug.LogFormat("Time2초기화되었다");
// }
// if (0.723f < elapsedTime && elapsedTime < 0.743f)
// {
// IsHeroAnimPlaying = false;
// elapsedTime = 0;
// cnt = 0;
// }
// }
// }
//}
// Update is called once per frame
//void Update()
//{
// if (hero != null && monster != null)
// {
// if (Vector3.Distance(hero.transform.position, monster.transform.position) <= dicCharacterData[100].atk_range)
// {
// monsterDmgElapsedTime += Time.deltaTime;
// this.heroAnim.Play("attack_sword_02");
// IsHeroAnimPlaying = true;
// elapsedTime += Time.deltaTime;
// Debug.Log($"첫번째elapsedTime:{elapsedTime}");
// if (IsHeroAnimPlaying == true)
// {
// Debug.Log(elapsedTime);
// elapsedTime += Time.deltaTime;
// }
// if (IsHeroAnimPlaying == false)
// {
// if (cnt < 5)
// {
// cnt++;
// this.heroAnim.Play("attack_sword_02");
// IsHeroAnimPlaying = true;
// elapsedTime += Time.deltaTime;
// Debug.Log($"첫번째elapsedTime:{elapsedTime}");
// }
// }
// 영웅이 칼을 타점에 맞추는 시간
// if (0.59f < elapsedTime && elapsedTime < 0.61f)
// {
// monsterDmgElapsedTime = 0;
// IsMonsterAnimPlaying = true;
// Debug.LogFormat("몬스터 애니메이션 ElapsedTime2 : {0}", elapsedTime2);
// }
// if (IsMonsterAnimPlaying)
// {
// this.monsterAnim.Play("Anim_Damage");
// monsterDmgElapsedTime += Time.deltaTime;
// }
// 영웅의 공격 동작이 끝나는 시간
// if (0.79f < elapsedTime/* && elapsedTime < 0.81f*/)
// {
// IsHeroAnimPlaying = false;
// elapsedTime = 0;
// IsMonsterAnimPlaying = false;
// }
// 몬스터의 피격 동작이 끝나는 시간
// if (0.467f < monsterDmgElapsedTime)
// {
// this.monsterAnim.Play("Anim_Idle");
// IsMonsterAnimPlaying = false;
// monsterDmgElapsedTime = 0;
// if (IsMonsterAnimPlaying != true)
// {
// IsMonsterAnimPlaying = true;
// }
// }
// }
// }
//}
}
'APP' 카테고리의 다른 글
[Unity] Delegate와 Coroutine사용 영웅과 몬스터 공격/피격 애니메이션 (0) | 2019.11.27 |
---|---|
[Unity] 코루틴을 사용, 캐릭터의 이동과 공격, 몬스터의 피격 애니메이션 실행 (0) | 2019.11.15 |
[Unity] 2019-11-14 코루틴 사용 (0) | 2019.11.14 |
[Unity] 코루틴으로 이동하는것 해볼것 (0) | 2019.11.13 |
[Unity] 2019-11-13 Study_002 역직렬화(캐릭터,웨폰) 인게임(캐릭터,웨폰 생성) (0) | 2019.11.13 |