261 lines
6.8 KiB
C#
261 lines
6.8 KiB
C#
using UnityEngine;
|
|
|
|
public class PlayerMovement : MonoBehaviour
|
|
{
|
|
[Header("Movement")]
|
|
public float moveSpeed = 4f;
|
|
public Rigidbody2D rb;
|
|
public Animator animator;
|
|
|
|
[Header("Analog Joystick")]
|
|
public JoystickController joystick;
|
|
|
|
[Header("UI Interaksi")]
|
|
public GameObject buttonInteraksiUI;
|
|
public GameObject buttonAmbilUI;
|
|
public GameObject promptInteraksiUI;
|
|
|
|
[Header("Status")]
|
|
[HideInInspector] public bool canMove = true;
|
|
[HideInInspector] public InteractionTrigger objekTerdekat;
|
|
|
|
private Vector2 inputGerak;
|
|
private Vector2 mobileInput;
|
|
private Vector2 lastMoveDirection = Vector2.down;
|
|
|
|
private enum TipeTarget
|
|
{
|
|
TidakAda,
|
|
NPC,
|
|
ObjekMisi
|
|
}
|
|
|
|
private TipeTarget tipeTargetSekarang = TipeTarget.TidakAda;
|
|
|
|
private void Start()
|
|
{
|
|
if (rb == null)
|
|
rb = GetComponent<Rigidbody2D>();
|
|
|
|
if (animator == null)
|
|
animator = GetComponent<Animator>();
|
|
|
|
SembunyikanSemuaTombolAksi();
|
|
UpdateAnimasi(Vector2.zero);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!canMove)
|
|
{
|
|
inputGerak = Vector2.zero;
|
|
mobileInput = Vector2.zero;
|
|
UpdateAnimasi(Vector2.zero);
|
|
return;
|
|
}
|
|
|
|
// Input keyboard untuk testing di laptop/PC.
|
|
Vector2 keyboardInput = new Vector2(
|
|
Input.GetAxisRaw("Horizontal"),
|
|
Input.GetAxisRaw("Vertical")
|
|
);
|
|
|
|
// Input dari analog joystick.
|
|
Vector2 joystickInput = Vector2.zero;
|
|
|
|
if (joystick != null)
|
|
{
|
|
joystickInput = joystick.arahInput;
|
|
}
|
|
|
|
// Prioritas input:
|
|
// 1. Joystick analog
|
|
// 2. Tombol arah lama jika masih dipakai
|
|
// 3. Keyboard
|
|
if (joystickInput.magnitude > 0.1f)
|
|
{
|
|
inputGerak = joystickInput.normalized;
|
|
}
|
|
else if (mobileInput.magnitude > 0.1f)
|
|
{
|
|
inputGerak = mobileInput.normalized;
|
|
}
|
|
else
|
|
{
|
|
inputGerak = keyboardInput.normalized;
|
|
}
|
|
|
|
UpdateAnimasi(inputGerak);
|
|
|
|
// Tombol keyboard untuk testing interaksi di PC.
|
|
if (Input.GetKeyDown(KeyCode.E) || Input.GetKeyDown(KeyCode.Space))
|
|
{
|
|
if (tipeTargetSekarang == TipeTarget.NPC)
|
|
{
|
|
TombolAksiInteraksi();
|
|
}
|
|
else if (tipeTargetSekarang == TipeTarget.ObjekMisi)
|
|
{
|
|
TombolAksiAmbil();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (!canMove)
|
|
{
|
|
rb.velocity = Vector2.zero;
|
|
return;
|
|
}
|
|
|
|
rb.velocity = inputGerak * moveSpeed;
|
|
}
|
|
|
|
private void UpdateAnimasi(Vector2 arahGerak)
|
|
{
|
|
if (animator == null) return;
|
|
|
|
if (arahGerak != Vector2.zero)
|
|
{
|
|
lastMoveDirection = arahGerak;
|
|
|
|
animator.SetFloat("MoveX", arahGerak.x);
|
|
animator.SetFloat("MoveY", arahGerak.y);
|
|
animator.SetBool("IsMoving", true);
|
|
}
|
|
else
|
|
{
|
|
animator.SetFloat("MoveX", lastMoveDirection.x);
|
|
animator.SetFloat("MoveY", lastMoveDirection.y);
|
|
animator.SetBool("IsMoving", false);
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// FUNGSI TOMBOL AKSI
|
|
// =========================
|
|
|
|
public void TombolAksiInteraksi()
|
|
{
|
|
if (objekTerdekat != null && canMove && tipeTargetSekarang == TipeTarget.NPC)
|
|
{
|
|
objekTerdekat.AktifkanInteraksi();
|
|
}
|
|
}
|
|
|
|
public void TombolAksiAmbil()
|
|
{
|
|
if (objekTerdekat != null && canMove && tipeTargetSekarang == TipeTarget.ObjekMisi)
|
|
{
|
|
objekTerdekat.AktifkanInteraksi();
|
|
}
|
|
}
|
|
|
|
private void TampilkanTombolInteraksi()
|
|
{
|
|
if (buttonInteraksiUI != null)
|
|
buttonInteraksiUI.SetActive(true);
|
|
|
|
if (buttonAmbilUI != null)
|
|
buttonAmbilUI.SetActive(false);
|
|
|
|
if (promptInteraksiUI != null)
|
|
promptInteraksiUI.SetActive(true);
|
|
}
|
|
|
|
private void TampilkanTombolAmbil()
|
|
{
|
|
if (buttonInteraksiUI != null)
|
|
buttonInteraksiUI.SetActive(false);
|
|
|
|
if (buttonAmbilUI != null)
|
|
buttonAmbilUI.SetActive(true);
|
|
|
|
if (promptInteraksiUI != null)
|
|
promptInteraksiUI.SetActive(true);
|
|
}
|
|
|
|
private void SembunyikanSemuaTombolAksi()
|
|
{
|
|
if (buttonInteraksiUI != null)
|
|
buttonInteraksiUI.SetActive(false);
|
|
|
|
if (buttonAmbilUI != null)
|
|
buttonAmbilUI.SetActive(false);
|
|
|
|
if (promptInteraksiUI != null)
|
|
promptInteraksiUI.SetActive(false);
|
|
}
|
|
|
|
// =========================
|
|
// INPUT TOMBOL ARAH LAMA
|
|
// =========================
|
|
// Fungsi ini tetap saya sisakan jika tombol arah lama masih ingin dipakai.
|
|
// Kalau sudah memakai analog, Btn_Atas/Btn_Bawah/Btn_Kiri/Btn_Kanan boleh dinonaktifkan.
|
|
|
|
public void JalanAtas()
|
|
{
|
|
mobileInput = Vector2.up;
|
|
}
|
|
|
|
public void JalanBawah()
|
|
{
|
|
mobileInput = Vector2.down;
|
|
}
|
|
|
|
public void JalanKiri()
|
|
{
|
|
mobileInput = Vector2.left;
|
|
}
|
|
|
|
public void JalanKanan()
|
|
{
|
|
mobileInput = Vector2.right;
|
|
}
|
|
|
|
public void BerhentiJalan()
|
|
{
|
|
mobileInput = Vector2.zero;
|
|
}
|
|
|
|
public void SetInputAnalog(Vector2 arah)
|
|
{
|
|
mobileInput = arah.magnitude > 0.1f ? arah.normalized : Vector2.zero;
|
|
}
|
|
|
|
// =========================
|
|
// DETEKSI NPC / OBJEK MISI
|
|
// =========================
|
|
|
|
private void OnTriggerEnter2D(Collider2D collision)
|
|
{
|
|
if (collision.CompareTag("NPC"))
|
|
{
|
|
objekTerdekat = collision.GetComponent<InteractionTrigger>();
|
|
tipeTargetSekarang = TipeTarget.NPC;
|
|
TampilkanTombolInteraksi();
|
|
}
|
|
else if (collision.CompareTag("ObjekMisi"))
|
|
{
|
|
objekTerdekat = collision.GetComponent<InteractionTrigger>();
|
|
tipeTargetSekarang = TipeTarget.ObjekMisi;
|
|
TampilkanTombolAmbil();
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit2D(Collider2D collision)
|
|
{
|
|
if (collision.CompareTag("NPC") || collision.CompareTag("ObjekMisi"))
|
|
{
|
|
InteractionTrigger triggerKeluar = collision.GetComponent<InteractionTrigger>();
|
|
|
|
if (triggerKeluar == objekTerdekat)
|
|
{
|
|
objekTerdekat = null;
|
|
tipeTargetSekarang = TipeTarget.TidakAda;
|
|
SembunyikanSemuaTombolAksi();
|
|
}
|
|
}
|
|
}
|
|
} |