// 스킬 전담 클래스가 따로 있는게 낫다. // 스킬 사용중에는 상태변화를 막고 싶은데 시간 기준으로 한다 치면 어떻게 시간을 카운트? // 1. Update() // 2. Coroutine protected override void UpdateIdle() { // 이동 상태로 바뀔건지 확인 if (_moveKeyPressed) { State = CreatureState.Moving; // UpdateMoving()으로 넘어감 return; } // 이동상태로 바뀔게 아니면 스킬 사용 가능한 상태가 됨. + 스킬 쿨타임 중이 아님. // 스킬은 Idle 상태일때만 사용가능 // GetDirInput()에 있던 것을 분리 if (_coSkillCooltime == null && Input.GetKey(KeyCode.Space)) { // 서버에 나 쓰킬 쓰고싶다고 전송 // 서버는 스킬사용체크 Debug.Log("Skill"); C_Skill skill = new C_Skill() { Info = new SkillInfo() }; skill.Info.SkillId = 2; // skillId 2, 화살쏘기 Managers.Network.Send(skill); _coSkillCooltime = StartCoroutine("CoInputCoolTime", 0.2f); } }
public static void C_SkillHandler(PacketSession session, IMessage packet) { // 스킬 사용 시도 C_Skill skillPacket = packet as C_Skill; ClientSession clientSession = session as ClientSession; //Console.WriteLine($"{clientSession.MyPlayer.Info.ObjectId} : C_SKILL ({skillPacket.Info.SkillId})"); Player player = clientSession.MyPlayer; if (player == null) { return; } GameRoom room = clientSession.MyPlayer.Room; if (room == null) { return; } // 스킬처리 //room.HandleSkill(player, skillPacket); room.Push(room.HandleSkill, player, skillPacket); }
protected override void UpdateIdle() { // 이동 상태로 갈지 확인 if (_moveKeyPressed) { State = CreatureState.Moving; return; } if (_coSkillCoolTime == null && Input.GetKey(KeyCode.Space)) { //Debug.Log("Skill !"); C_Skill skill = new C_Skill() { Info = new SKillInfo() }; skill.Info.Skillid = 2; Managers.Network.Send(skill); //State = CreatureState.Skill; ////_coSkill = StartCoroutine("coPunchSkill"); //_coSkill = StartCoroutine("coStartShootArrow"); _coSkillCoolTime = StartCoroutine("CoInputCoolTime", 0.2f); } }
// C_Skill public void HandleSkill(Player player, C_Skill skillPacket) { if (player == null) { return; } ObjectInfo info = player.Info; if (info.PosInfo.State != CreatureState.Idle) { return; } // TODO : 스킬 사용가능한지 검증 // 통과 info.PosInfo.State = CreatureState.Skill; S_Skill skill = new S_Skill() { Info = new SkillInfo() }; skill.ObjectId = info.ObjectId; skill.Info.SkillId = skillPacket.Info.SkillId; // 유저가 보내준 스킬 Broadcast(player.CellPos, skill); Data.Skill skillData = null; if (DataManager.SkillDict.TryGetValue(skill.Info.SkillId, out skillData) == false) { return; } // 스킬 종류에 따른 로직 switch (skillData.skillType) { case SkillType.SkillAuto: // 평타 // 데미지 판정 Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir); GameObject target = Map.Find(skillPos); if (target != null) { this.Push(target.OnDamaged, player, player.Info.StatInfo.Attack); } break; case SkillType.SkillProjectile: // 투사체 SpawnProjectile(player, skillData); break; case SkillType.SkillNone: break; default: return; } }
public static void C_SkillHandler(PacketSession session, IMessage packet) { C_Skill skillPacket = packet as C_Skill; ClientSession clientSession = session as ClientSession; Player player = clientSession.MyPlayer; if (player == null) { return; } GameRoom room = player.Room; if (room == null) { return; } room.Push(room.HandleSkill, player, skillPacket); }
protected override void UpdateIdle() { // 이동 상태로 갈지? if (_moveKeyPressed) { State = CreatureState.Moving; return; } // 스킬 상태로 갈지.. if (_coSkillCoolTime == null && Input.GetKey(KeyCode.Space)) { C_Skill skill = new C_Skill() { Info = new SkillInfo() }; skill.Info.SkillId = 2; Managers.Network.Send(skill); _coSkillCoolTime = StartCoroutine(CoInputCooltime(0.2f)); } }
// 가만히 있을때 스킬 버튼을 입력받나? protected override void UpdateIdle() { // 이동이냐? if (_moveKeyPressed) { State = CreatureState.Moving; } // 스킬이냐? if (Input.GetButton("Fire1") && _coSkillCoolTime == null) { //Debug.Log("SKILL !!"); // 스킬 패킷보내기 C_Skill skill = new C_Skill() { Info = new SkillInfo() }; skill.Info.SkillId = 2; // TEST: 1번은 평타 2번은 화살 Managers.Network.Send(skill); _coSkillCoolTime = StartCoroutine("SkillCoolTime", 0.3f); } // 스킬이냐? else if (Input.GetButton("Fire2") && _coSkillCoolTime == null) { //Debug.Log("SKILL !!"); // 스킬 패킷보내기 C_Skill skill = new C_Skill() { Info = new SkillInfo() }; skill.Info.SkillId = 1; // TEST: 1번은 평타 2번은 화살 Managers.Network.Send(skill); _coSkillCoolTime = StartCoroutine("SkillCoolTime", 0.3f); } }
public void HandleSkill(Player player, C_Skill skillPacket) { if (player == null) { return; } ObjectInfo info = player.Info; if (info.PosInfo.State != CreatureState.Idle) { return; } // TODO : 스킬 사용 가능 여부 체크 info.PosInfo.State = CreatureState.Skill; S_Skill skill = new S_Skill() { Info = new SkillInfo() }; skill.ObjectId = info.ObjectId; skill.Info.SkillId = skillPacket.Info.SkillId; Broadcast(skill); Data.Skill skillData = null; if (DataManager.SkillDict.TryGetValue(skillPacket.Info.SkillId, out skillData) == false) { return; } switch (skillData.skillType) { case SkillType.SkillAuto: { Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir); GameObject target = Map.Find(skillPos); if (target != null) { Console.WriteLine("Hit GameObject !"); } } break; case SkillType.SkillProjectile: { Arrow arrow = ObjectManager.Instance.Add <Arrow>(); if (arrow == null) { return; } arrow.Owner = player; arrow.Data = skillData; arrow.PosInfo.State = CreatureState.Moving; arrow.PosInfo.MoveDir = player.PosInfo.MoveDir; arrow.PosInfo.PosX = player.PosInfo.PosX; arrow.PosInfo.PosY = player.PosInfo.PosY; arrow.Speed = skillData.projectile.speed; Push(EnterGame, arrow); } break; } }
// GameRoom의 JobSerilizer에 의해 실행되기 때문에 EnterGame같은거 직접 불러도 됨 public void HandleSkill(Player player, C_Skill skillPacket) { if (player == null) // player가 지금 GameRoom에 소속되었는지도 체크 { return; } // 스킬분기처리.. 몇 개 없다는 가정하에 // 스킬이 많아지면 Skill 클래스를 따로 파서 플레이어에 주입하는게 낫다 ObjectInfo info = player.Info; if (info.PosInfo.State != CreatureState.Idle) { return; } // 스킬 사용 가능 여부 체크 // 스킬 애니메이션 맞춰주는 부분 info.PosInfo.State = CreatureState.Skill; S_Skill skill = new S_Skill() { Info = new SkillInfo() }; // info도 클래스임 skill.ObjectId = info.ObjectId; skill.Info.SkillId = skillPacket.Info.SkillId; // 나중에 시트로 뺄거야 Broadcast(skill); // 에코서버마냥 전파한다 // 이제 DB에서 Id에 해당하는 스킬데이터를 뽑아온다 Data.Skill skillData = null; if (DataManager.SkillDict.TryGetValue(skillPacket.Info.SkillId, out skillData) == false) { return; } // id에 해당하는 스킬이 있다 switch (skillData.skillType) { case SkillType.SkillAuto: { // 주먹질 // 데미지 판정 -> 항상 치팅 대비 // 내 공격방향에 적이 있나 없나 체크 // GetFrontCellPos에 MoveDir.None 처리가 없으니 // 항상 공격자의 위치를 반환해서 아무대나 떄려도 타격이 되는 문제가 있었음 // MoveDir.None이 그냥 키입력 여부를 받는거라 서버에는 필요없으므로 전체적으로 없애기로함 Vector2Int skillPos = player.GetFrontCellPos(info.PosInfo.MoveDir); GameObject target = Map.Find(skillPos); if (target != null) { Console.WriteLine("Hit GameObject!"); } } break; case SkillType.SkillProjectile: { // 화살 생성 // 클라에서도 화살이 날아가는것을 계산하고 있어야 치팅을 방지할수 있다. // 어떤 투사체인지 구분할수 있는게 필요 (지금은 화살만..) Arrow arrow = ObjectManager.Instance.Add <Arrow>(); if (arrow == null) { return; } // 데이터 대입 arrow.Owner = player; arrow.Data = skillData; // 투사체를 생성한 주체(스킬)의 정보를 저장 arrow.PosInfo.State = CreatureState.Moving; arrow.PosInfo.MoveDir = player.PosInfo.MoveDir; arrow.PosInfo.PosX = player.PosInfo.PosX; arrow.PosInfo.PosY = player.PosInfo.PosY; arrow.Speed = skillData.projectile.speed; // 직접 불러서 해도 전혀 문제없긴함 EnterGame(arrow) Push(EnterGame, arrow); // 치팅방지 + 코드재사용(화살이 생성됐음을 모두에게 알림) } break; } }