fix: 火山玩法本地化问题
This commit is contained in:
@@ -2222,6 +2222,44 @@ namespace AibisDream.MiniGame.Language
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只恢复当前演出短语使用的粒子;超出短语长度的旧词保持隐藏。
|
||||
/// </summary>
|
||||
public void SetCurrentPresentationPhraseAlpha(
|
||||
float targetAlpha,
|
||||
float duration = 0f)
|
||||
{
|
||||
List<CandidateParticle> particles = GetPresentationPhraseParticles();
|
||||
int visibleCount = finalTargetUnits.Count > 0
|
||||
? Mathf.Min(finalTargetUnits.Count, particles.Count)
|
||||
: particles.Count;
|
||||
float alphaValue = Mathf.Clamp01(targetAlpha);
|
||||
|
||||
for (int i = 0; i < particles.Count; i++)
|
||||
{
|
||||
CandidateParticle particle = particles[i];
|
||||
if (particle == null)
|
||||
continue;
|
||||
|
||||
DOTween.Kill(particle);
|
||||
float destinationAlpha = i < visibleCount ? alphaValue : 0f;
|
||||
if (duration <= 0f)
|
||||
{
|
||||
particle.alpha = destinationAlpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
DOTween.To(
|
||||
() => particle.alpha,
|
||||
value => particle.alpha = value,
|
||||
destinationAlpha,
|
||||
duration)
|
||||
.SetEase(Ease.OutQuad)
|
||||
.SetTarget(particle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将已完成聚焦的目标粒子改排为红色攻击词。文字必须完整放进现有目标粒子,
|
||||
/// 超长时拒绝播放,避免演出层静默删字。
|
||||
@@ -2433,10 +2471,12 @@ namespace AibisDream.MiniGame.Language
|
||||
/// </summary>
|
||||
public IEnumerator SettleTruthPhraseAndWait(string text, float duration)
|
||||
{
|
||||
List<CandidateParticle> particles = GetPresentationPhraseParticles();
|
||||
List<string> units = TokenizeActiveText(text);
|
||||
List<CandidateParticle> particles = GetPresentationPhraseParticles(
|
||||
units.Count,
|
||||
allowExpansion: true);
|
||||
if (!ValidatePresentationPhrase(text, particles, "真话稳定"))
|
||||
yield break;
|
||||
List<string> units = TokenizeActiveText(text);
|
||||
|
||||
PreparePresentationPhraseControl();
|
||||
|
||||
@@ -2555,19 +2595,74 @@ namespace AibisDream.MiniGame.Language
|
||||
}
|
||||
}
|
||||
|
||||
private List<CandidateParticle> GetPresentationPhraseParticles()
|
||||
private List<CandidateParticle> GetPresentationPhraseParticles(
|
||||
int requiredCount = 0,
|
||||
bool allowExpansion = false)
|
||||
{
|
||||
List<CandidateParticle> particles = orderedRedParticles
|
||||
.Where(particle => particle != null)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
if (particles.Count > 0)
|
||||
if (particles.Count == 0)
|
||||
{
|
||||
particles = targetParticles
|
||||
.Where(particle => particle != null)
|
||||
.OrderBy(particle => particle.transform.position.x)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
if (!allowExpansion || requiredCount <= particles.Count)
|
||||
return particles;
|
||||
|
||||
return targetParticles
|
||||
.Where(particle => particle != null)
|
||||
.OrderBy(particle => particle.transform.position.x)
|
||||
.ToList();
|
||||
// 最终稳定文案可能比本轮目标句更长(英文和俄文尤其常见)。
|
||||
// 此时玩法已经结束,干扰粒子也已淡出,可以安全复用它们补足展示容量,
|
||||
// 避免容量校验跳过整段收尾并把上一句攻击词留在红色失稳状态。
|
||||
if (candidateParticles.Count < requiredCount)
|
||||
EnsureCandidatePoolSize(requiredCount);
|
||||
|
||||
var existing = new HashSet<CandidateParticle>(particles);
|
||||
CandidateParticle[] sourceParticles = particles.ToArray();
|
||||
Vector3 phraseCenter = sourceParticles.Length > 0
|
||||
? ComputeCentroid(particles)
|
||||
: (worldCanvas != null ? worldCanvas.transform.position : transform.position);
|
||||
|
||||
foreach (CandidateParticle particle in candidateParticles
|
||||
.Where(particle => particle != null && !existing.Contains(particle))
|
||||
.OrderBy(particle =>
|
||||
(particle.transform.position - phraseCenter).sqrMagnitude))
|
||||
{
|
||||
int sourceIndex = particles.Count - sourceParticles.Length;
|
||||
Vector3 sourcePosition = sourceParticles.Length > 0
|
||||
? sourceParticles[sourceIndex % sourceParticles.Length].transform.position
|
||||
: phraseCenter;
|
||||
|
||||
particle.transform.DOKill();
|
||||
DOTween.Kill(particle);
|
||||
particle.transform.position = sourcePosition;
|
||||
particle.transform.localScale = Vector3.one * ResolvedFocusScale;
|
||||
particle.velocity = Vector2.zero;
|
||||
particle.isRed = true;
|
||||
particle.isTemporaryRed = true;
|
||||
particle.isOrange = false;
|
||||
particle.hasEffect = false;
|
||||
particle.isCalmed = true;
|
||||
particle.isStatic = true;
|
||||
particle.anxietyShakeIntensity = 0f;
|
||||
particle.ClearFocusInterference();
|
||||
particle.alpha = 0f;
|
||||
|
||||
particles.Add(particle);
|
||||
existing.Add(particle);
|
||||
if (!targetParticles.Contains(particle))
|
||||
targetParticles.Add(particle);
|
||||
if (!orderedRedParticles.Contains(particle))
|
||||
orderedRedParticles.Add(particle);
|
||||
|
||||
if (particles.Count >= requiredCount)
|
||||
break;
|
||||
}
|
||||
|
||||
return particles;
|
||||
}
|
||||
|
||||
private bool ValidatePresentationPhrase(
|
||||
@@ -2698,7 +2793,7 @@ namespace AibisDream.MiniGame.Language
|
||||
activeSnapshot?.Profile?.MinimumReadablePhraseScale ?? 0.65f;
|
||||
if (activePhraseScale < minimumReadable)
|
||||
{
|
||||
Debug.LogError(
|
||||
Debug.LogWarning(
|
||||
$"[LanguageParticleManager] 表达文字需要缩放到 {activePhraseScale:0.00}," +
|
||||
$"低于 Locale Profile 最小可读值 {minimumReadable:0.00};" +
|
||||
"运行时仍会缩放以保证文字完整显示。");
|
||||
@@ -2770,6 +2865,8 @@ namespace AibisDream.MiniGame.Language
|
||||
nonTargetParticleFontSize,
|
||||
false,
|
||||
nonTargetParticleBold);
|
||||
particle.anxietyShakeIntensity = 0f;
|
||||
particle.ClearFocusInterference();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -901,7 +901,7 @@ namespace AibisDream.MiniGame.Language
|
||||
|
||||
particleManager?.PrepareTruthReleaseFromLie();
|
||||
particleManager?.ApplyPresentationResolvedVisuals(presentationResolvedColor);
|
||||
particleManager?.SetTargetParticlesAlpha(1f, 0f);
|
||||
particleManager?.SetCurrentPresentationPhraseAlpha(1f, 0f);
|
||||
Bounds truthBounds = particleManager != null
|
||||
? particleManager.GetFinalTruthWorldBounds()
|
||||
: new Bounds(GetScreenBounds().center, Vector3.one);
|
||||
|
||||
Reference in New Issue
Block a user