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);
}
}