Files
Loong/Assets/_Loong/Scripts/Bow/Bow.cs

177 lines
5.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using DarkTonic.MasterAudio;
using UnityEngine;
public class Bow : Launcher
{
public Transform bowString;
public Arrow nowArrow;
[SoundGroup] public string arrowShoot;
[Header("箭矢类型管理")]
public BulletType currentArrowType = BulletType.WoodArrow;
private float specialArrowTimeRemaining = 0f;
[Header("箭矢预制体")]
public GameObject normalArrowPrefab;
public GameObject smokePrefab;
[Header("弓弦力度参数")]
public float minForce = 20f;//最小力度
public float maxForce = 45f;//最大力度
public float forceMultiplier = 1.2f;//力度倍增系数
public float maxPullDistance = 0.5f;//弓弦可拉最大距离
public float forceCurveExponent = 1.5f;//力度曲线指数
public float currentDrawStrength = 0f;//当前力度0-1
[Header("弓弦视觉反馈")]
public LineRenderer bowStringRenderer;//弓弦的LineRenderer
public Transform stringTopPoint;//弓弦顶端点
public Transform stringBottomPoint;//弓弦末端点
public Transform stringMiddlePoint;//弓弦中间点(手拉动弓弦的位置)
private Vector3 middlePointPos;//初始弓弦初始点
public virtual void Start()
{
//初始化弓弦位置
if (bowStringRenderer != null && stringTopPoint != null && stringBottomPoint != null)
{
//设置LineRenderer位置
bowStringRenderer.positionCount = 3;
bowStringRenderer.SetPosition(0, stringTopPoint.position);
bowStringRenderer.SetPosition(1, stringMiddlePoint.position);
bowStringRenderer.SetPosition(2, stringBottomPoint.position);
//保存中间点初始位置
middlePointPos = stringMiddlePoint.localPosition;
}
smokePrefab.SetActive(false);
}
public void Update()
{
UpdateArrowStatus();
UpdateBowStringVisual();
}
//更新弓弦视觉效果
private void UpdateBowStringVisual()
{
if (bowStringRenderer != null && stringTopPoint != null && stringBottomPoint != null && stringMiddlePoint != null)
{
//更新LineRenderer
bowStringRenderer.SetPosition(0, stringTopPoint.position);
bowStringRenderer.SetPosition(1, stringMiddlePoint.position);
bowStringRenderer.SetPosition(2, stringBottomPoint.position);
}
}
//更新箭矢状态
public virtual void UpdateArrowStatus()
{
}
Vector3 ProjectPointOnPlane(Vector3 point, Vector3 planeOrigin, Vector3 planeNormal)
{
// 单位化法向量
planeNormal.Normalize();
// 计算点到平面上任意一点的向量
Vector3 vectorToPlane = point - planeOrigin;
// 计算投影距离
float distance = Vector3.Dot(vectorToPlane, planeNormal);
// 得到垂足(即点在平面上的投影)
Vector3 projection = point - distance * planeNormal;
return projection;
}
/// <summary>
/// 拉弓弦(由左手位置驱动)
/// </summary>
public void Pull(Transform point)
{
Vector3 planeOrigin = bowString.position;
Vector3 planeNormal = bowString.right;
// 投影手的拉动位置到弓弦平面
Vector3 projectedPoint = ProjectPointOnPlane(point.position, planeOrigin, planeNormal);
// 转换到弓的局部坐标系
Vector3 localPos = transform.InverseTransformPoint(projectedPoint);
// 限制拉弓距离,防止超过最大拉伸范围
float pullDistance = Mathf.Clamp(localPos.z, -maxPullDistance, 0);
// 更新弓弦视觉
if (stringMiddlePoint != null)
{
Vector3 midPos = middlePointPos;
midPos.z = pullDistance;
stringMiddlePoint.localPosition = midPos;
}
// 更新箭尾点位置
if (bulletPoint != null)
{
bulletPoint.localPosition = new Vector3(0, 0, pullDistance);
}
// 力度计算
currentDrawStrength = Mathf.Clamp01(Mathf.Abs(pullDistance) / maxPullDistance);
// -------------------------
// ✅ 新增保护逻辑:超过最大拉距时自动复位
// -------------------------
// if (Mathf.Approximately(pullDistance, -maxPullDistance))
// {
// Reset();
// }
}
/// <summary>
/// 弓弦复位
/// </summary>
public void Reset()
{
// // 拉弓点归零
// if (bulletPoint != null)
// bulletPoint.localPosition = Vector3.zero;
// 弓弦归位
if (stringMiddlePoint != null)
stringMiddlePoint.localPosition = middlePointPos;
// 当前力度清零
currentDrawStrength = 0f;
// 隐藏拉弓烟雾
if (smokePrefab != null)
smokePrefab.SetActive(false);
}
/// <summary>
/// 创建箭矢
/// </summary>
public virtual void CreateArrowInHand()
{
}
/// <summary>
/// 射出箭矢
/// </summary>
public virtual void ShootArrow()
{
}
}