유니티 다크소울 따라만들기 ch_14 무기 교체
이 글은 유튜브 Sebastian Graves Create Dark Souls를 보고 따라 만들면서 헷갈리는 부분을 정리한 글입니다.
구현 개요
무기 교체를 구현한다.
PlayerInventory 수정
지금은 1번 2번칸이 있는 무기로 구현된다.
public class PlayerInventory : MonoBehaviour
{
WeaponSlotManager weaponSlotManager;
public WeaponItem rightWeapon;
public WeaponItem leftWeapon;
public WeaponItem unarmedWeapon; // 아무 무기도 안쥠
public WeaponItem[] weaponsInRightHandSlots = new WeaponItem[1];
public WeaponItem[] weaponsInLeftHandSlots = new WeaponItem[1];
public int currentRightWeaponIndex = 0;
public int currentLeftWeaponIndex = 0;
private void Awake()
{
weaponSlotManager = GetComponentInChildren<WeaponSlotManager>();
}
private void Start()
{
rightWeapon = unarmedWeapon;
leftWeapon = unarmedWeapon;
}
public void ChangeRightWeapon()
{
currentRightWeaponIndex = currentRightWeaponIndex + 1;
if(currentRightWeaponIndex == 0 && weaponsInRightHandSlots[0] != null)
{
rightWeapon = weaponsInRightHandSlots[currentRightWeaponIndex];
weaponSlotManager.LoadWeaponOnSlot(weaponsInRightHandSlots[currentRightWeaponIndex], false);
}
else if(currentRightWeaponIndex == 0 && weaponsInRightHandSlots[0] == null)
{
currentRightWeaponIndex = currentRightWeaponIndex + 1;
}
else if(currentRightWeaponIndex == 1 && weaponsInRightHandSlots[1] != null)
{
rightWeapon = weaponsInRightHandSlots[currentRightWeaponIndex];
weaponSlotManager.LoadWeaponOnSlot(weaponsInRightHandSlots[currentRightWeaponIndex], false);
}
else if(currentRightWeaponIndex == 1 && weaponsInRightHandSlots[1] == null)
{
currentRightWeaponIndex = currentRightWeaponIndex + 1;
}
if(currentRightWeaponIndex > weaponsInRightHandSlots.Length - 1)
{
currentRightWeaponIndex = -1;
rightWeapon = unarmedWeapon;
weaponSlotManager.LoadWeaponOnSlot(unarmedWeapon, false);
}
}
public void ChangeLeftWeapon()
{
currentLeftWeaponIndex = currentLeftWeaponIndex + 1;
if (currentLeftWeaponIndex == 0 && weaponsInLeftHandSlots[0] != null)
{
leftWeapon = weaponsInLeftHandSlots[currentLeftWeaponIndex];
weaponSlotManager.LoadWeaponOnSlot(weaponsInLeftHandSlots[currentLeftWeaponIndex], true);
}
else if (currentLeftWeaponIndex == 0 && weaponsInLeftHandSlots[0] == null)
{
currentLeftWeaponIndex = currentLeftWeaponIndex + 1;
}
else if (currentLeftWeaponIndex == 1 && weaponsInLeftHandSlots[1] != null)
{
leftWeapon = weaponsInLeftHandSlots[currentLeftWeaponIndex];
weaponSlotManager.LoadWeaponOnSlot(weaponsInLeftHandSlots[currentLeftWeaponIndex], true);
}
else if(currentLeftWeaponIndex == 1 && weaponsInLeftHandSlots[1] == null)
{
currentLeftWeaponIndex = currentLeftWeaponIndex + 1;
}
if (currentLeftWeaponIndex > weaponsInLeftHandSlots.Length - 1)
{
currentLeftWeaponIndex = -1;
leftWeapon = unarmedWeapon;
weaponSlotManager.LoadWeaponOnSlot(unarmedWeapon, true);
}
}
}
unarmed 상태의 무기 스크립터블 오브젝트를 생성
비무장 상태를 위해 비무장 스크립터블 오브젝트를 생성한다.
InputAction에 무기 전환 키 추가
InputHandler 수정
새로운 키가 할당되었으니 그 키의 기능을 추가한다.
public class InputHandler : MonoBehaviour
{
public float horizontal;
public float vertical;
public float moveAmount;
public float mouseX;
public float mouseY;
public bool b_Input;
public bool rb_Input;
public bool rt_Input;
public bool d_Pad_Up;
public bool d_Pad_Down;
public bool d_Pad_Left;
public bool d_Pad_Right;
public bool rollFlag;
public bool sprintFlag;
public bool comboFlag;
public float rollInputTimer;
PlayerControls inputActions;
PlayerAttacker playerAttacker;
PlayerInventory playerInventory;
PlayerManager playerManager;
CameraHandler cameraHandler;
Vector2 movementInput;
Vector2 cameraInput;
private void Awake()
{
playerAttacker = GetComponent<PlayerAttacker>();
playerInventory = GetComponent<PlayerInventory>();
playerManager = GetComponent<PlayerManager>();
}
public void OnEnable()
{
if (inputActions == null)
{
inputActions = new PlayerControls();
inputActions.PlayerMovement.Movement.performed +=
inputActions => movementInput = inputActions.ReadValue<Vector2>();
inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
}
// 인풋 액션 활성화
inputActions.Enable();
}
private void OnDisable()
{
inputActions.Disable();
}
public void TickInput(float delta)
{
MoveInput(delta);
HandleRollInput(delta);
HandleAttackInput(delta);
HandleQuickSlotsInput();
}
private void MoveInput(float delta)
{
horizontal = movementInput.x;
vertical = movementInput.y;
moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vertical));
mouseX = cameraInput.x;
mouseY = cameraInput.y;
}
private void HandleRollInput(float delta)
{
//b_Input = inputActions.PlayerActions.Roll.phase == UnityEngine.InputSystem.InputActionPhase.Started;
//b_Input = inputActions.PlayerActions.Roll.triggered;
// 눌릴 때만 true
b_Input = inputActions.PlayerActions.Roll.IsPressed();
if (b_Input)
{
rollInputTimer += delta;
sprintFlag = true;
}
else
{
if (rollInputTimer > 0 && rollInputTimer < 0.5f)
{
sprintFlag = false;
rollFlag = true;
}
rollInputTimer = 0;
}
}
private void HandleAttackInput(float delta)
{
inputActions.PlayerActions.RB.performed += i => rb_Input = true;
inputActions.PlayerActions.RT.performed += i => rt_Input = true;
if (rb_Input)
{
if (playerManager.canDoCombo)
{
comboFlag = true;
playerAttacker.HandleWeaponCombo(playerInventory.rightWeapon);
comboFlag = false;
}
else
{
// 중복 실행 방지
if (playerManager.isInteracting)
return;
playerAttacker.HandleLightAttack(playerInventory.rightWeapon);
}
}
if (rt_Input)
{
playerAttacker.HandleHeavyAttack(playerInventory.rightWeapon);
}
}
private void HandleQuickSlotsInput()
{
inputActions.PlayerQuickSlots.DPadRight.performed += i => d_Pad_Right = true;
inputActions.PlayerQuickSlots.DPadLeft.performed += i => d_Pad_Left = true;
if (d_Pad_Right)
{
playerInventory.ChangeRightWeapon();
}
else if (d_Pad_Left)
{
playerInventory.ChangeLeftWeapon();
}
}
}
PlayerManager 수정
새로 할당된 키들을 갱신시켜주는 부분을 추가한다.
public class PlayerManager : MonoBehaviour
{
InputHandler inputHandler;
Animator anim;
CameraHandler cameraHandler;
PlayerLocomotion playerLocomotion;
public bool isInteracting;
[Header("Player Flags")]
public bool isSprinting;
public bool isInAir;
public bool isGrounded;
public bool canDoCombo;
void Start()
{
inputHandler = GetComponent<InputHandler>();
anim = GetComponentInChildren<Animator>();
playerLocomotion = GetComponent<PlayerLocomotion>();
}
private void Awake()
{
cameraHandler = FindAnyObjectByType<CameraHandler>();
}
void Update()
{
float delta = Time.deltaTime;
isInteracting = anim.GetBool("isInteracting");
canDoCombo = anim.GetBool("canDoCombo");
inputHandler.TickInput(delta);
playerLocomotion.HandleMovement(delta);
playerLocomotion.HandleRollingAndSprinting(delta);
playerLocomotion.HandleFalling(delta, playerLocomotion.moveDirection);
}
private void FixedUpdate()
{
float delta = Time.fixedDeltaTime;
if (cameraHandler != null)
{
cameraHandler.FollowTarget(delta);
cameraHandler.HandleCameraRotation(delta, inputHandler.mouseX, inputHandler.mouseY);
}
}
private void LateUpdate()
{
inputHandler.rollFlag = false;
inputHandler.sprintFlag = false;
inputHandler.rb_Input = false;
inputHandler.rt_Input = false;
inputHandler.d_Pad_Up = false;
inputHandler.d_Pad_Down = false;
inputHandler.d_Pad_Left = false;
inputHandler.d_Pad_Right = false;
if (isInAir)
{
playerLocomotion.inAirTimer = playerLocomotion.inAirTimer + Time.deltaTime;
}
}
}
새로운 무기 추가
전과 똑같은 방식으로 무기를 추가한다.
댓글남기기