e
This commit is contained in:
142
unity/Assets/Light/scripts/SceneInteraction.cs
Normal file
142
unity/Assets/Light/scripts/SceneInteraction.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user