117 lines
3.7 KiB
C#
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);
|
|
}
|
|
}
|
|
} |