Files
MRArcadia/Assets/_Arcadia/Scripts/Item/PuzzleFragmentCollectTrigger.cs
2026-04-01 15:53:13 +08:00

298 lines
7.3 KiB
C#

using DG.Tweening;
using UnityEngine;
using DragonLi.Core;
/// <summary>
/// 拼图碎片收集触发器 - 场景中需要收集的碎片
/// </summary>
public class PuzzleFragmentCollectTrigger : MonoBehaviour
{
[Header("碎片标识")]
[SerializeField] private int fragmentId = 0; // 碎片ID (对应PuzzleTable中的碎片)
[Header("收集设置")]
[SerializeField] private float collectDistance = 0.1f; // 收集距离
[SerializeField] private bool autoCollectOnTouch = true; // 触碰时自动收集
[Header("视觉效果")]
[SerializeField] private ParticleSystem glowEffect; // 发光效果(提示可收集)
[SerializeField] private ParticleSystem collectEffect; // 收集时的特效
[SerializeField] private Light fragmentLight; // 碎片光源
[SerializeField] private float glowIntensity = 1f; // 发光强度
[Header("音效")]
[SerializeField] private string touchSound = "1.55"; // 碰触音效
[SerializeField] private string collectSound = "1.56"; // 收集音效
[Header("状态")]
[SerializeField] private bool isCollected = false; // 是否已收集
[SerializeField] private bool isHighlighted = false; // 是否高亮显示
private PuzzleTable puzzleTable;
private RightHand rightHand;
private Collider triggerCollider;
public int FragmentId => fragmentId;
public bool IsCollected => isCollected;
private void Awake()
{
triggerCollider = GetComponent<Collider>();
puzzleTable = FindObjectOfType<PuzzleTable>();
}
private void Start()
{
rightHand = GameManager.Ins?.playerRightHand;
// 初始化发光效果
if (glowEffect != null)
{
glowEffect.Stop();
}
if (fragmentLight != null)
{
fragmentLight.intensity = 0.3f;
}
}
private void Update()
{
if (isCollected) return;
// 检测右手柄接近
CheckHandProximity();
}
/// <summary>
/// 检测手柄接近
/// </summary>
private void CheckHandProximity()
{
if (rightHand == null) return;
float distance = Vector3.Distance(rightHand.transform.position, transform.position);
if (distance < collectDistance)
{
// 高亮显示
if (!isHighlighted)
{
HighlightFragment();
}
// 检测扳机键按下收集
if (rightHand.isTrigger && autoCollectOnTouch)
{
CollectFragment();
}
}
else
{
// 取消高亮
if (isHighlighted)
{
UnhighlightFragment();
}
}
}
/// <summary>
/// 高亮碎片(提示可收集)
/// </summary>
private void HighlightFragment()
{
isHighlighted = true;
// 播放发光效果
if (glowEffect != null)
{
glowEffect.Play();
}
// 增强光源
if (fragmentLight != null)
{
fragmentLight.intensity = glowIntensity;
}
// 播放碰触音效
if (!string.IsNullOrEmpty(touchSound))
{
GameManager.Ins?.PlaySound2DRPC(touchSound);
}
Debug.Log($"碎片 {fragmentId} 高亮显示");
}
/// <summary>
/// 取消高亮
/// </summary>
private void UnhighlightFragment()
{
isHighlighted = false;
// 停止发光效果
if (glowEffect != null)
{
glowEffect.Stop();
}
// 恢复光源
if (fragmentLight != null)
{
fragmentLight.intensity = 0.3f;
}
}
/// <summary>
/// 收集碎片
/// </summary>
public void CollectFragment()
{
if (isCollected) return;
isCollected = true;
// 播放收集特效
if (collectEffect != null)
{
collectEffect.Play();
}
// 播放收集音效
if (!string.IsNullOrEmpty(collectSound))
{
GameManager.Ins?.PlaySound2DRPC(collectSound);
}
// 通知拼图台
if (puzzleTable != null)
{
puzzleTable.OnFragmentCollectedFromScene(fragmentId);
}
// 隐藏碎片模型
HideFragment();
Debug.Log($"碎片 {fragmentId} 已收集!");
}
/// <summary>
/// 隐藏碎片(收集后)
/// </summary>
private void HideFragment()
{
// 淡出动画
var renderer = GetComponent<Renderer>();
if (renderer != null)
{
renderer.material.DOFade(0f, 0.5f).OnComplete(() =>
{
gameObject.SetActive(false);
});
}
else
{
gameObject.SetActive(false);
}
// 禁用碰撞器
if (triggerCollider != null)
{
triggerCollider.enabled = false;
}
// 停止所有效果
if (glowEffect != null) glowEffect.Stop();
if (fragmentLight != null) fragmentLight.enabled = false;
}
/// <summary>
/// 重置碎片(可再次收集)
/// </summary>
public void ResetFragment()
{
isCollected = false;
isHighlighted = false;
gameObject.SetActive(true);
if (triggerCollider != null)
{
triggerCollider.enabled = true;
}
if (fragmentLight != null)
{
fragmentLight.enabled = true;
fragmentLight.intensity = 0.3f;
}
// 恢复材质透明度
var renderer = GetComponent<Renderer>();
if (renderer != null)
{
var color = renderer.material.color;
color.a = 1f;
renderer.material.color = color;
}
}
/// <summary>
/// 设置碎片ID
/// </summary>
public void SetFragmentId(int id)
{
fragmentId = id;
}
#region
private void OnTriggerEnter(Collider other)
{
if (isCollected) return;
RightHand hand = other.GetComponent<RightHand>();
if (hand != null)
{
rightHand = hand;
HighlightFragment();
if (autoCollectOnTouch && hand.isTrigger)
{
CollectFragment();
}
}
}
private void OnTriggerExit(Collider other)
{
if (isCollected) return;
RightHand hand = other.GetComponent<RightHand>();
if (hand != null)
{
UnhighlightFragment();
}
}
#endregion
#region
private void OnDrawGizmos()
{
Gizmos.color = isCollected ? Color.gray : Color.yellow;
Gizmos.DrawWireSphere(transform.position, collectDistance);
if (!isCollected)
{
Gizmos.color = Color.green;
Gizmos.DrawSphere(transform.position, 0.02f);
}
}
#endregion
}