Files
gold_dolphin/unity/Assets/Light/scripts/SceneInteraction.cs
2026-06-27 03:37:16 +08:00

143 lines
5.0 KiB
C#
Raw Permalink 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 UnityEngine;
using System.Collections;
namespace IndianOceanAssets.Engine2_5D
{
/// <summary>
/// 场景交互点 —— 玩家走到指定物体附近,按 Q 触发过场。
/// 触发后主角的光圈逐渐扩大最终点亮整个场景PPT式过渡
///
/// 挂载位置场景中的交互物件如祭坛、机关、特殊NPC等
/// 需要:物体上有 Collider + 勾选 IsTrigger
/// 玩家需要 Tag = "Player"
/// </summary>
public class SceneInteraction : MonoBehaviour
{
[Header("交互设置")]
[SerializeField] private KeyCode interactKey = KeyCode.Q;
[Tooltip("玩家进入此范围才能交互")]
[SerializeField] private float interactionRadius = 3f;
[Header("过场参数")]
[Tooltip("光圈扩大的持续时间类似PPT过场")]
[SerializeField] private float transitionDuration = 5f;
[Tooltip("最终光圈半径(要覆盖整个场景的话设大一点)")]
[SerializeField] private float finalLightRadius = 60f;
[Tooltip("最终全局最小亮度0.6=全场景可见但偏暗, 1.0=全亮)")]
[SerializeField, Range(0f, 1f)] private float finalMinBrightness = 0.7f;
[Header("引用")]
[Tooltip("玩家的 LightSource 组件(必须已挂载)")]
[SerializeField] private LightSource playerLightSource;
[Tooltip("交互提示 UI可选玩家靠近时显示")]
[SerializeField] private GameObject interactionPrompt;
[Header("音效(可选)")]
[SerializeField] private AudioSource interactionSFX;
// 状态
private bool _triggered = false;
private bool _playerInRange = false;
private Transform _player;
private void Start()
{
// 自动查找玩家
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
if (playerObj != null)
{
_player = playerObj.transform;
if (playerLightSource == null)
playerLightSource = playerObj.GetComponent<LightSource>();
}
if (interactionPrompt != null)
interactionPrompt.SetActive(false);
}
private void Update()
{
if (_triggered) return;
// 检测玩家是否在范围内
if (_player != null)
{
float dist = Vector3.Distance(transform.position, _player.position);
_playerInRange = dist <= interactionRadius;
}
// 显示/隐藏交互提示
if (interactionPrompt != null)
interactionPrompt.SetActive(_playerInRange);
// 检测 Q 键
if (_playerInRange && Input.GetKeyDown(interactKey))
{
StartCoroutine(ExpandLightTransition());
}
}
/// <summary>
/// 过场协程:光圈逐渐扩大 + 全局亮度提升
/// </summary>
private IEnumerator ExpandLightTransition()
{
_triggered = true;
// 隐藏交互提示
if (interactionPrompt != null)
interactionPrompt.SetActive(false);
// 播放音效
if (interactionSFX != null)
interactionSFX.Play();
// 记录初始值
float startRadius = playerLightSource != null ? playerLightSource.Radius : 5f;
float startBrightness = LightMaskSystem.Instance != null ? 0f : 0f;
float elapsed = 0f;
// 过程:平滑插值扩大
while (elapsed < transitionDuration)
{
elapsed += Time.deltaTime;
float t = elapsed / transitionDuration;
// SmoothStep 插值(开始和结束都柔和)
float smoothT = t * t * (3f - 2f * t);
// 扩大玩家光圈半径
if (playerLightSource != null)
playerLightSource.SetRadius(Mathf.Lerp(startRadius, finalLightRadius, smoothT));
// 提升全局最小亮度(让黑暗区域也逐渐可见)
if (LightMaskSystem.Instance != null)
LightMaskSystem.Instance.SetMinBrightness(Mathf.Lerp(startBrightness, finalMinBrightness, smoothT));
yield return null;
}
// 确保最终值
if (playerLightSource != null)
playerLightSource.SetRadius(finalLightRadius);
if (LightMaskSystem.Instance != null)
LightMaskSystem.Instance.SetMinBrightness(finalMinBrightness);
Debug.Log("[SceneInteraction] 过场完成,场景已全部点亮");
}
// ===== 编辑器可视化 =====
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(0f, 1f, 0f, 0.3f);
Gizmos.DrawWireSphere(transform.position, interactionRadius);
}
}
}