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