using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; public class InputController : MonoBehaviour { public Rigidbody rigi; public Character character; public Inventory inven; private void Awake() { character.OnDie += OnDie; character.OnHit += OnHit; } public bool PAD = false; void FixedUpdate() { if (!LOCK) { if (PAD) { InputMove_Pad(); InputFire_Pad(); } else { InputMove(); InputFire(); } } } [Header("모션")] public Motion motion; /// /// 데미지를 받았으며 히트모션을 실행합니다 /// /// 데미지를 준 캐릭터 /// 히트 방향 /// 넉백 비율 public void OnHit(Character attacker, Vector3 dir, float knockBackAddRate, bool MOTION_FORCE, System.Action OnEnd) { //MoveLocked(true);//맞았음 //KnockBack(dir); //motion.Play(Motion.Type.Hit, false, () => //{ // rigi.velocity = Vector3.zero; // MoveLocked(false);//히트 모션 종료 //}); motion.Play(Motion.Type.Hit, false, null); } public GameObject prefabEffDeath; /// /// HP 가 0 이 되어 죽는모션을 실행합니다. /// /// 데미지를 준 캐릭터 /// 히트 방향 public void OnDie(Character attacker, Vector3 dir) { MoveLocked(true);//죽음 motion.Play(Motion.Type.Die, true, () => { Debug.LogWarning("플레이어 죽음"); character.map.MapCleared(true);//클리어 실패 }); } [Space(5)] public float knockBack = 0.5f; void KnockBack(Vector3 dir) { dir.y = 0; rigi.velocity = dir * knockBack; } [Header("이동")] [HideInInspector] public Vector3 dirMove = Vector3.zero; public float stopRange = 0.04f; void InputMove() { if (Input.GetKey(KeyCode.A)) { dirMove.x = Vector3.left.x; } else if (Input.GetKey(KeyCode.D)) { dirMove.x = Vector3.right.x; } else dirMove.x = 0; if (Input.GetKey(KeyCode.W)) { dirMove.z = Vector3.forward.z; } else if (Input.GetKey(KeyCode.S)) { dirMove.z = Vector3.back.z; } else dirMove.z = 0; dirMove = dirMove.normalized; if (rigi) { if (dirMove.x != 0 && dirMove.z != 0) rigi.AddForce(dirMove * character.CalculateMoveSpeed()); else rigi.AddForce(dirMove * character.CalculateMoveSpeed()); if (dirMove.x != 0 || dirMove.z != 0) { if (dirFire.x == dirMove.x || dirFire.x == 0) motion.Play(Motion.Type.Run); else motion.Play(Motion.Type.RunBack); } else { if (rigi.velocity.sqrMagnitude < stopRange) { rigi.velocity = Vector3.zero; if (motion.isATK) motion.Play(Motion.Type.Idle2); else motion.Play(Motion.Type.Idle); } } } } void InputMove_Pad() { dirMove.x = Input.GetAxis("Horizontal"); dirMove.z = Input.GetAxis("Vertical"); if (rigi) { rigi.AddForce(dirMove * character.CalculateMoveSpeed()); if (dirMove.x != 0 || dirMove.z != 0) { if (dirFire.x == dirMove.x || dirFire.x == 0) motion.Play(Motion.Type.Run); else motion.Play(Motion.Type.RunBack); } else { if (rigi.velocity.sqrMagnitude < stopRange) { rigi.velocity = Vector3.zero; if (motion.isATK) motion.Play(Motion.Type.Idle2); else motion.Play(Motion.Type.Idle); } } } } public bool LOCK = false; /// /// 이동 제한을 설정합니다 /// /// true : 이동금지 public void MoveLocked(bool LOCK) { this.LOCK = LOCK; if (this.LOCK) { dirFire = dirMove = Vector3.zero; //motion.Play(Motion.Type.AttackEnd); if (motion.typeBefore != Motion.Type.Get) motion.Play(Motion.Type.Idle); } } /// /// 맵블럭 간의 이동시에 사용됩니다. /// /// 이동에 필요한 데이터 public void Teleport(MapDoor.Teleport data) { MoveLocked(true);//문을 통과하는 중 ItemUseRegister register = new ItemUseRegister(); register.OnItemUse = inven.ItemUse; register.OnTeleport = Teleport; register.OnLock = MoveLocked; if (data.blk == null) { Debug.LogWarning("마지막 방"); character.map.MapCleared();//클리어 성공 } else { data.blk.ecMapBlock.Invoke((int)MapEvent.Register_OnItemUse, register); if (data.door == null) { data.blk.manager.MapBlockChanged(data.blk, () => { //transform.position = data.blk.transform.position;//캐릭터 transform.localPosition = new Vector3(-0.5f, 0, -3f);//캐릭터 data.blk.TypeSetting(); MoveLocked(false);//맵 생성 완료 data.blk.manager.MapBlockHide(); }); } else { data.blk.manager.MapBlockChanged(data.blk, () => { transform.position = data.door.way.transform.position;//캐릭터 data.blk.TypeSetting(); MoveLocked(false);//캐릭터, 카메라 가 블럭으로 이동 완료 }); } } } [Header("공격")] public Fire fire; float fireLastTime = 0; public float fireDirDivision = 0.3f; [Header("공격->대기 모션 대기 시간")] public float atkPosture = 3f;//공격 후 대기모션으로 넘어가는 대기시간 Vector3 dirFire = Vector3.zero; Vector3 dirFire2 = Vector3.zero; void InputFire() { if (character.CalculateAttackDelay() < Time.realtimeSinceStartup - fireLastTime) { if (Input.GetKey(KeyCode.LeftArrow)) { dirFire.x = Vector3.left.x; dirFire2.z = dirMove.z * fireDirDivision; } else if (Input.GetKey(KeyCode.RightArrow)) { dirFire.x = Vector3.right.x; dirFire2.z = dirMove.z * fireDirDivision; } else { dirFire.x = 0; dirFire2.z = 0; } if (dirFire.x == 0) { if (Input.GetKey(KeyCode.UpArrow)) { dirFire.z = Vector3.forward.z; dirFire2.x = dirMove.x * fireDirDivision; } else if (Input.GetKey(KeyCode.DownArrow)) { dirFire.z = Vector3.back.z; dirFire2.x = dirMove.x * fireDirDivision; } else { dirFire.z = 0; dirFire2.x = 0; } } else { dirFire.z = 0; dirFire2.x = 0; } Fire(dirFire); } } void InputFire_Pad() { if (character.CalculateAttackDelay() < Time.realtimeSinceStartup - fireLastTime) { if (Input.GetButton("X")) { dirFire.x = Vector3.left.x; dirFire2.z = dirMove.z * fireDirDivision; } else if (Input.GetButton("B")) { dirFire.x = Vector3.right.x; dirFire2.z = dirMove.z * fireDirDivision; } else { dirFire.x = 0; dirFire2.z = 0; } if (dirFire.x == 0) { if (Input.GetButton("Y")) { dirFire.z = Vector3.forward.z; dirFire2.x = dirMove.x * fireDirDivision; } else if (Input.GetButton("A")) { dirFire.z = Vector3.back.z; dirFire2.x = dirMove.x * fireDirDivision; } else { dirFire.z = 0; dirFire2.x = 0; } } else { dirFire.z = 0; dirFire2.x = 0; } Fire(dirFire); } } /// /// 투사체를 발사합니다. /// /// 발사 방향 void Fire(Vector3 dirFire) { Look(); if (dirFire != Vector3.zero) { fireLastTime = Time.realtimeSinceStartup; Motion.Type type = dirFire.x != 0 ? Motion.Type.Attack : (dirFire.z < 0 ? Motion.Type.AttackDown : Motion.Type.AttackUp); Vector3 dir = dirFire + dirFire2; motion.Play(Motion.Type.AttackEnd); motion.Play(type, false, null, data => { float rate = (dir.x != 0 && dir.x == dirMove.x) || (dir.z != 0 && dir.z == dirMove.z) ? 1.3f : 1f; fire.OnFire(dir * rate); dirFire = Vector3.zero; }); } else if (motion.isATK && atkPosture < Time.realtimeSinceStartup - fireLastTime) { motion.Play(Motion.Type.AttackEnd); } } /// /// 공격 방향으로 바라봅니다. /// void Look() { if (dirFire.x != 0 || dirMove.x != 0) motion.LookSet(dirFire.x != 0 ? -dirFire.x : -dirMove.x); } }