Files
Loong/Assets/_Loong/Scripts/Bow/FireBow.cs
2025-10-30 10:16:52 +08:00

133 lines
4.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using DarkTonic.MasterAudio;
using UnityEngine;
public class FireBow : Bow
{
private Arrow arrowUp;
private Arrow arrowDown;
private Transform targetEnemy; // 检测到的敌人目标
private Vector3 arrowUpLocalOffset;
private Vector3 arrowDownLocalOffset;
public override void Start()
{
base.Start();
type = GunType.FireBow;
GunInfo gunInfo = GameManager.Ins.GunInfos[type][1];
shootRate = gunInfo.ShootRate;
recoil = maxForce;
}
public override void CreateArrowInHand()
{
base.CreateArrowInHand();
if (arrowUp != null) Destroy(arrowUp.gameObject);
if (arrowDown != null) Destroy(arrowDown.gameObject);
if (nowArrow != null) Destroy(nowArrow.gameObject);
// 上下偏移
Vector3 upOffset = bulletPoint.up * 0.05f;
Vector3 downOffset = -bulletPoint.up * 0.05f;
Quaternion rot = bulletPoint.rotation;
// 创建两支箭
GameObject arrowUpObj = Instantiate(normalArrowPrefab, bulletPoint.position + upOffset, rot, bulletPoint);
GameObject arrowDownObj = Instantiate(normalArrowPrefab, bulletPoint.position + downOffset, rot, bulletPoint);
GameObject arrowObj = Instantiate(normalArrowPrefab, bulletPoint);
nowArrow = arrowObj.GetComponent<Arrow>();
arrowUp = arrowUpObj.GetComponent<Arrow>();
arrowDown = arrowDownObj.GetComponent<Arrow>();
// 保存局部偏移量
arrowUpLocalOffset = bulletPoint.InverseTransformPoint(arrowUpObj.transform.position);
arrowDownLocalOffset = bulletPoint.InverseTransformPoint(arrowDownObj.transform.position);
// 禁用物理模拟
if (arrowUp.TryGetComponent<Rigidbody>(out var rb1)) rb1.isKinematic = true;
if (arrowDown.TryGetComponent<Rigidbody>(out var rb2)) rb2.isKinematic = true;
if (nowArrow.TryGetComponent<Rigidbody>(out var rb3)) rb3.isKinematic = true;
}
public override void ShootArrow()
{
base.ShootArrow();
if (arrowUp == null || arrowDown == null)
return;
MasterAudio.PlaySound(arrowShoot);
// 计算力度
float curvedStrength = Mathf.Pow(currentDrawStrength, 1.8f);
float actualForce = Mathf.Lerp(minForce, maxForce, curvedStrength) * forceMultiplier;
// 发射三箭
FireArrow(arrowUp, actualForce);
FireArrow(arrowDown, actualForce);
FireArrow(arrowDown, actualForce);
arrowUp = null;
arrowDown = null;
nowArrow = null;
Reset();
}
private void FireArrow(Arrow arrow, float actualForce)
{
if (arrow == null) return;
arrow.transform.SetParent(null);
if (arrow.TryGetComponent<Rigidbody>(out var rb))
{
rb.isKinematic = false;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
// 直接用箭当前的forward方向作为发射方向
Vector3 dir = arrow.transform.forward;
rb.AddForce(dir * actualForce, ForceMode.VelocityChange);
arrow.OnSpawn(dir, actualForce);
}
}
public override void UpdateArrowStatus()
{
base.UpdateArrowStatus();
if (arrowUp != null && arrowDown != null)
{
// 根据弓的旋转实时更新箭位置
Vector3 arrowUpPos = bulletPoint.TransformPoint(arrowUpLocalOffset);
Vector3 arrowDownPos = bulletPoint.TransformPoint(arrowDownLocalOffset);
// 箭头方向:从弓到拉弦方向
Vector3 drawDir = bulletPoint.forward;
arrowUp.transform.position = arrowUpPos;
arrowUp.transform.rotation = Quaternion.LookRotation(drawDir, bulletPoint.up);
arrowDown.transform.position = arrowDownPos;
arrowDown.transform.rotation = Quaternion.LookRotation(drawDir, bulletPoint.up);
}
if (nowArrow != null)
{
// 箭尾固定点(通常是弓上挂箭点)
Transform tailPoint = bulletPoint; // 保证箭尾贴在弓上
// 箭头方向:从箭尾指向左手
Vector3 direction = (transform.position - tailPoint.position).normalized;
// 更新箭的位置与旋转
nowArrow.transform.position = tailPoint.position;
nowArrow.transform.rotation = Quaternion.LookRotation(direction, transform.up);
}
}
}