Files
MRFishingMaster/Assets/_FishingMaster/Scripts/Statue/StatueAssembler.cs

276 lines
8.0 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.Generic;
using DG.Tweening;
using UnityEngine;
/// <summary>
/// 石像拼凑器 - 管理石像碎片的显示和拼凑动画
/// </summary>
public class StatueAssembler : MonoBehaviour
{
[Header("石像配置")]
public int statueIndex; // 石像序号
public string statueName; // 石像名称
[Header("碎片配置")]
public int totalFragments = 10; // 总碎片数
public GameObject[] fragmentMeshes; // 10个碎片模型按顺序
[Header("材质配置")]
public Material grayMaterial; // 未激活时的灰色材质
public Material colorMaterial; // 完成后的彩色材质
public float materialTransitionDuration = 1f; // 材质过渡时间
[Header("完成特效")]
public ParticleSystem completeEffect; // 完成特效
public GameObject glowEffect; // 发光效果
public Light completeLight; // 完成时光照
public float lightIntensity = 2f; // 光照强度
[Header("动画配置")]
public float fragmentAppearDelay = 0.1f; // 碎片出现间隔
public float assembleShakeAmount = 0.1f; // 拼凑完成时的震动幅度
// 私有变量
private HashSet<int> collectedFragments = new HashSet<int>();
private bool isCompleted = false;
private List<MeshRenderer> fragmentRenderers = new List<MeshRenderer>();
public event Action<int> OnStatueCompleted; // 石像完成事件
private void Awake()
{
InitializeFragments();
}
/// <summary>
/// 初始化碎片
/// </summary>
private void InitializeFragments()
{
// 确保所有碎片初始隐藏
for (int i = 0; i < fragmentMeshes.Length; i++)
{
if (fragmentMeshes[i] != null)
{
fragmentMeshes[i].SetActive(false);
// 获取渲染器并设置灰色材质
MeshRenderer renderer = fragmentMeshes[i].GetComponent<MeshRenderer>();
if (renderer != null)
{
fragmentRenderers.Add(renderer);
if (grayMaterial != null)
renderer.material = grayMaterial;
}
}
}
// 关闭完成特效
if (completeEffect != null)
completeEffect.gameObject.SetActive(false);
if (glowEffect != null)
glowEffect.SetActive(false);
if (completeLight != null)
completeLight.enabled = false;
}
/// <summary>
/// 添加碎片
/// </summary>
public void AddFragment(int fragmentIndex)
{
if (isCompleted) return;
if (collectedFragments.Contains(fragmentIndex)) return;
// 计算在这个石像中的本地碎片序号
int localIndex = fragmentIndex % totalFragments;
collectedFragments.Add(fragmentIndex);
// 显示对应碎片
ShowFragment(localIndex);
// 检查是否完成
CheckCompletion();
}
/// <summary>
/// 显示单个碎片
/// </summary>
private void ShowFragment(int localIndex)
{
if (localIndex < 0 || localIndex >= fragmentMeshes.Length) return;
GameObject fragment = fragmentMeshes[localIndex];
if (fragment == null) return;
// 激活碎片
fragment.SetActive(true);
// 从缩放0开始的弹出动画
fragment.transform.localScale = Vector3.zero;
fragment.transform.DOScale(Vector3.one, 0.3f)
.SetEase(Ease.OutBack);
// 轻微旋转动画
fragment.transform.DORotate(new Vector3(0, 360, 0), 0.5f, RotateMode.LocalAxisAdd)
.SetEase(Ease.OutQuad);
// 添加发光效果
MeshRenderer renderer = fragment.GetComponent<MeshRenderer>();
if (renderer != null && grayMaterial != null)
{
renderer.material = grayMaterial;
// 可以添加闪烁效果
renderer.material.DOFloat(1.5f, "_EmissionIntensity", 0.3f)
.SetLoops(2, LoopType.Yoyo);
}
GameManager.Ins.PlaySound3D("雕像碎片堆叠音效",transform);
}
/// <summary>
/// 检查是否完成
/// </summary>
private void CheckCompletion()
{
if (collectedFragments.Count >= totalFragments)
{
CompleteStatue();
}
}
/// <summary>
/// 完成石像
/// </summary>
private void CompleteStatue()
{
if (isCompleted) return;
isCompleted = true;
Debug.Log($"[StatueAssembler] {statueName} 拼凑完成!");
// 播放完成动画
PlayCompleteAnimation();
// 触发事件
OnStatueCompleted?.Invoke(statueIndex);
}
/// <summary>
/// 播放完成动画
/// </summary>
private void PlayCompleteAnimation()
{
// 1. 震动效果
transform.DOShakePosition(0.5f, assembleShakeAmount, 10, 90);
// 2. 所有碎片变色
foreach (var renderer in fragmentRenderers)
{
if (renderer != null && colorMaterial != null)
{
// 材质渐变
Material targetMat = new Material(colorMaterial);
renderer.material = targetMat;
// 发光强度动画
targetMat.SetFloat("_EmissionIntensity", 0);
targetMat.DOFloat(2f, "_EmissionIntensity", materialTransitionDuration)
.SetEase(Ease.OutQuad);
}
}
// 3. 整体缩放动画
transform.DOScale(transform.localScale * 1.1f, 0.2f)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
transform.DOScale(transform.localScale / 1.1f, 0.3f)
.SetEase(Ease.InOutQuad);
});
// 4. 播放粒子特效
if (completeEffect != null)
{
completeEffect.gameObject.SetActive(true);
completeEffect.Play();
}
// 5. 发光效果
if (glowEffect != null)
{
glowEffect.SetActive(true);
glowEffect.transform.localScale = Vector3.zero;
glowEffect.transform.DOScale(Vector3.one, 0.5f)
.SetEase(Ease.OutBack);
}
// 6. 光照效果
if (completeLight != null)
{
completeLight.enabled = true;
completeLight.intensity = 0;
DOTween.To(() => completeLight.intensity, x => completeLight.intensity = x, lightIntensity, 0.5f)
.SetEase(Ease.OutQuad);
}
// 7. 播放音效
GameManager.Ins?.PlaySound3D("雕像堆叠成功", transform,true);
// 8. 延迟后持续特效
DOVirtual.DelayedCall(1f, () =>
{
// 持续的微弱发光动画
if (glowEffect != null)
{
glowEffect.transform.DOScale(Vector3.one * 1.2f, 2f)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
}
GetCoin();
});
}
public void GetCoin()
{
GameObject pileGO = Instantiate(
GameManager.Ins.coinPilePre,
transform.position,
Quaternion.identity
);
pileGO.GetComponent<CoinPileController>()
.Init(
GameInit.Ins.self.RightHand,
10
);
GameInit.Ins.self.AddCoin(500);
GameInit.Ins.self.AddScore(500);
}
/// <summary>
/// 获取收集进度
/// </summary>
public int GetProgress()
{
return collectedFragments.Count;
}
/// <summary>
/// 是否已完成
/// </summary>
public bool IsCompleted()
{
return isCompleted;
}
/// <summary>
/// 获取碎片收集状态
/// </summary>
public bool HasFragment(int fragmentIndex)
{
return collectedFragments.Contains(fragmentIndex);
}
}