You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
11 KiB
374 lines
11 KiB
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; |
|
/// <summary> |
|
/// 데미지를 받았으며 히트모션을 실행합니다 |
|
/// </summary> |
|
/// <param name="attacker">데미지를 준 캐릭터</param> |
|
/// <param name="dir">히트 방향</param> |
|
/// <param name="knockBackAddRate">넉백 비율</param> |
|
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; |
|
/// <summary> |
|
/// HP 가 0 이 되어 죽는모션을 실행합니다. |
|
/// </summary> |
|
/// <param name="attacker">데미지를 준 캐릭터</param> |
|
/// <param name="dir">히트 방향</param> |
|
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; |
|
/// <summary> |
|
/// 이동 제한을 설정합니다 |
|
/// </summary> |
|
/// <param name="LOCK">true : 이동금지</param> |
|
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); |
|
} |
|
} |
|
/// <summary> |
|
/// 맵블럭 간의 이동시에 사용됩니다. |
|
/// </summary> |
|
/// <param name="data">이동에 필요한 데이터</param> |
|
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); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 투사체를 발사합니다. |
|
/// </summary> |
|
/// <param name="dirFire">발사 방향</param> |
|
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); |
|
} |
|
} |
|
/// <summary> |
|
/// 공격 방향으로 바라봅니다. |
|
/// </summary> |
|
void Look() |
|
{ |
|
if (dirFire.x != 0 || dirMove.x != 0) |
|
motion.LookSet(dirFire.x != 0 ? -dirFire.x : -dirMove.x); |
|
} |
|
}
|
|
|