Files
VRProject/Assets/_Scripts/VRPunchAttack.cs
ohgushiyuga 52341100ed otamesi
2026-08-27 12:51:15 +09:00

117 lines
3.7 KiB
C#

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR;
[RequireComponent(typeof(Collider))]
[RequireComponent(typeof(Rigidbody))]
public class VRInputPunch : MonoBehaviour
{
[SerializeField] private InputActionProperty velocityAction;
[SerializeField] private XRNode controllerNode = XRNode.RightHand;
[SerializeField] private VRInputPoseDetector poseDetector;
[Header("パンチパラメータ")]
[SerializeField] private float minPunchSpeed = 1.0f;
[SerializeField] private float damageMultiplier = 10.0f;
[SerializeField] private float hapticAmplitude = 0.5f;
[SerializeField] private float hapticDuration = 0.1f;
[Header("パリィパラメータ")]
[SerializeField] private float parryStunDuration = 3.0f;
[SerializeField] private float parryHapticAmplitude = 0.9f;
[SerializeField] private float parryHapticDuration = 0.25f;
private const string EnemyFistTag = "EnemyFist";
private void OnEnable()
{
if (velocityAction.action != null) velocityAction.action.Enable();
}
private void OnDisable()
{
if (velocityAction.action != null) velocityAction.action.Disable();
}
private void Start()
{
Rigidbody rb = GetComponent<Rigidbody>();
rb.isKinematic = true;
rb.useGravity = false;
GetComponent<Collider>().isTrigger = true;
}
private void OnTriggerEnter(Collider other)
{
Vector3 velocity = velocityAction.action != null ? velocityAction.action.ReadValue<Vector3>() : Vector3.zero;
float speed = velocity.magnitude;
if (other.CompareTag(EnemyFistTag))
{
if (poseDetector != null && poseDetector.IsPosing)
{
if (TryProcessParry(other)) return;
}
}
if (speed >= minPunchSpeed)
{
ProcessPunchAttack(other, speed, velocity);
}
}
private bool TryProcessParry(Collider other)
{
EnemyAI enemyAI = other.GetComponentInParent<EnemyAI>();
if (enemyAI != null)
{
enemyAI.TriggerParryStun(parryStunDuration);
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
return true;
}
BossController boss = other.GetComponentInParent<BossController>();
if (boss != null && boss.TriggerParryStun())
{
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
return true;
}
return false;
}
private void ProcessPunchAttack(Collider other, float speed, Vector3 velocity)
{
IDamageable damageable = other.GetComponentInParent<IDamageable>();
if (damageable == null) return;
bool isPosing = poseDetector != null && poseDetector.IsPosing;
DamageInfo info = new DamageInfo
{
amount = speed * damageMultiplier * (isPosing ? 2f : 1f),
isPoseBonus = isPosing,
hitPosition = other.transform.position,
punchDirection = velocity.normalized
};
if (PlayerStatusManager.Instance != null)
{
PlayerStatusManager.Instance.AddGauge(isPosing ? 20f : 10f);
info.amount *= PlayerStatusManager.Instance.Buffs.CurrentAttackMultiplier;
}
damageable.TakeDamage(info);
TriggerHaptics(hapticAmplitude, hapticDuration);
}
private void TriggerHaptics(float amplitude, float duration)
{
// 明示的に UnityEngine.XR.InputDevice と指定して型衝突を回避
UnityEngine.XR.InputDevice device = InputDevices.GetDeviceAtXRNode(controllerNode);
if (device.isValid)
{
device.SendHapticImpulse(0, amplitude, duration);
}
}
}