后处理+FEEL完全改进

This commit is contained in:
SoulliesOfficial
2025-12-22 18:36:29 -05:00
parent c3914da4ac
commit a2052bfe16
1427 changed files with 193092 additions and 374110 deletions

View File

@@ -10,11 +10,14 @@ using SLSFramework.LeanPoolAssistance;
using SLSFramework.WwiseAssistance;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Cielonos.MainGame
{
public abstract partial class AttackAreaBase : MonoBehaviour
{
private static Dictionary<string, int> areaNameCountDictionary = new Dictionary<string, int>();
[Title("References")]
public CharacterBase creator;
public ItemBase itemSource;
@@ -25,6 +28,7 @@ namespace Cielonos.MainGame
public Dictionary<string, GameObject> functionalParts;
[Title("Status")]
public string areaName;
public bool isEnabling;
public bool canTriggerHitEvent = true;
public Action updateAction;
@@ -79,6 +83,12 @@ namespace Cielonos.MainGame
{
topParent = topParent.parent;
}
if (!areaNameCountDictionary.TryAdd(topParent.name, 1))
{
areaNameCountDictionary[topParent.name]++;
}
areaName = $"{topParent.name}_{areaNameCountDictionary[topParent.name]}";
foreach (TrailRenderer trail in GetComponentsInChildren<TrailRenderer>())
{

View File

@@ -11,8 +11,8 @@ namespace Cielonos.MainGame
{
public bool isOverridingHitEffect;
public GameObject hitVFXPrefab;
public GameObject damageNumberRegularPrefab;
public GameObject damageNumberCriticalPrefab;
public DamageNumber damageNumberRegularPrefab;
public DamageNumber damageNumberCriticalPrefab;
public AttackValue originalAttackValue;
public AttackValue modifiedAttackValue;
@@ -45,9 +45,9 @@ namespace Cielonos.MainGame
public void SpawnDamageNumber(Vector3 position, bool isCritical, float finalDamage)
{
GameObject damageNumberGameObject = isCritical ? damageNumberCriticalPrefab : damageNumberRegularPrefab;
DamageNumber damageNumber = Object.Instantiate(damageNumberGameObject, position, Quaternion.identity).GetComponent<DamageNumber>();
damageNumber.number = finalDamage;
DamageNumber finalDN = isCritical ? damageNumberCriticalPrefab : damageNumberRegularPrefab;
DamageNumber damageNumber = finalDN.Spawn(position, finalDamage);
damageNumber.spamGroup = attackArea.areaName;
}
}
}

View File

@@ -8,14 +8,16 @@ namespace Cielonos.MainGame
{
public partial class HitSubmodule : AttackAreaSubmoduleBase
{
public int hitCount;
public int originalHitCount;
public int currentHitIndex;
public float hitInterval;
private float currentIntervalTime;
public List<GameObject> checkedObjects;
public bool isAutoPlayHitSound;
public List<string> hitSoundList;
public List<Action<CharacterBase, Vector3>> hitEventList;
public List<Action<CharacterBase, Vector3>> generalHitEventList;
public SortedList<int, Action<CharacterBase, Vector3>> specificHitEventList;
public HitSubmodule(AttackAreaBase attackArea) : base(attackArea)
{
@@ -30,15 +32,17 @@ namespace Cielonos.MainGame
}
private void InitializeAsOnceHit()
{
this.hitCount = 1;
{
this.originalHitCount = 1;
this.currentHitIndex = 0;
this.hitInterval = -1;
this.currentIntervalTime = 0;
}
private void InitializeAsMultipleHit(float hitInterval, int hitCount)
{
this.hitCount = hitCount;
this.originalHitCount = hitCount;
this.currentHitIndex = 0;
this.hitInterval = hitInterval;
this.currentIntervalTime = 0;
}
@@ -48,7 +52,8 @@ namespace Cielonos.MainGame
isAutoPlayHitSound = true;
checkedObjects = new List<GameObject>();
hitSoundList = new List<string>();
hitEventList = new List<Action<CharacterBase, Vector3>>();
generalHitEventList = new List<Action<CharacterBase, Vector3>>();
specificHitEventList = new SortedList<int, Action<CharacterBase, Vector3>>();
}
}
@@ -78,7 +83,16 @@ namespace Cielonos.MainGame
public HitSubmodule AddHitEvent(Action<CharacterBase, Vector3> hitEvent)
{
hitEventList.Add(hitEvent);
generalHitEventList.Add(hitEvent);
return this;
}
public HitSubmodule AddHitEvent(Action<CharacterBase, Vector3> hitEvent, params int[] indexes)
{
foreach (int i in indexes)
{
specificHitEventList[i] = hitEvent;
}
return this;
}
}
@@ -87,7 +101,7 @@ namespace Cielonos.MainGame
{
public void Update()
{
if (!isEnabling || hitCount <= 1 || attackArea.timeSm.delayTime > 0)
if (!isEnabling || currentHitIndex >= originalHitCount - 1 || attackArea.timeSm.delayTime > 0)
{
return;
}
@@ -101,10 +115,10 @@ namespace Cielonos.MainGame
//attackArea.attackSm.modifiedAttackValue = attackArea.attackSm.originalAttackValue;
}
currentIntervalTime -= hitInterval;
hitCount--;
currentHitIndex++;
}
if (hitCount <= 0)
if (currentHitIndex >= originalHitCount - 1)
{
attackArea.isEnabling = false;
}
@@ -126,10 +140,16 @@ namespace Cielonos.MainGame
{
if (attackArea.canTriggerHitEvent)
{
foreach (Action<CharacterBase, Vector3> hitEvent in hitEventList)
foreach (Action<CharacterBase, Vector3> hitEvent in generalHitEventList)
{
hitEvent.Invoke(target, hitPosition);
}
Debug.Log($"[HitSubmodule] Invoking specific hit event for hit index {currentHitIndex}.");
if (specificHitEventList.ContainsKey(currentHitIndex))
{
specificHitEventList[currentHitIndex].Invoke(target, hitPosition);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using Sirenix.OdinInspector;
using SLSFramework.General;
using SLSFramework.WwiseAssistance;
using SLSUtilities.FunctionalAnimation;
using UniRx;
@@ -220,4 +221,24 @@ namespace Cielonos.MainGame.Characters
return false;
}
}
public partial class CharacterBase
{
public Vector2 GetNormalizedScreenPosition(Camera cam = null)
{
if (this is Player player)
{
cam ??= player.viewSc.playerCamera;
}
else
{
if (cam == null)
{
throw new ArgumentNullException(nameof(cam), "Camera must be provided for non-player characters.");
}
}
return SpaceConverter.WorldPointToNormalizedScreenPoint(flexibleCenterPoint.position, cam);
}
}
}

View File

@@ -105,7 +105,7 @@ namespace Cielonos.MainGame.Characters
private void BoneShakeLateUpdate()
{
float dt = Time.deltaTime;
float dt = owner.selfTimeSm.DeltaTime;
for (int i = activeShakes.Count - 1; i >= 0; i--)
{
@@ -267,7 +267,7 @@ namespace Cielonos.MainGame.Characters
}
else
{
animator.CrossFade("Empty", 0f, fullBodyActionIndex, 0);
animator.CrossFade("Empty", 0.1f, fullBodyActionIndex, 0);
}
}
}

View File

@@ -13,6 +13,8 @@ namespace Cielonos.MainGame.Characters
{
foreach (var feedbackUnit in feedbacks.Values)
{
float timeScaleMultiplier = owner.selfTimeSm.TimeScale;
feedbackUnit.feedback.ExternalTimeScale = timeScaleMultiplier;
feedbackUnit.Update();
}
}

View File

@@ -141,7 +141,9 @@ namespace Cielonos.MainGame.Characters
{
sourceItem.audioContainer.PlaySoundFX("PerfectBlock");
sourceItem.feedbackSc["PerfectBlock"]?.Play();
sourceItem.blockData.InstantiateBlockEffect(perfectEffectName, blockEffectPosition, Quaternion.identity);
GameObject pObj = sourceItem.blockData.InstantiateBlockEffect(perfectEffectName, sourceCharacter, blockEffectPosition, Quaternion.identity);
pObj.GetComponent<ParticleSystem>().Simulate(0.1f, true, true);
pObj.GetComponent<ParticleSystem>().Play();//TODO: 增加起点时间参数
}
onPerfectBlock?.Invoke(attackArea);
@@ -153,7 +155,7 @@ namespace Cielonos.MainGame.Characters
{
sourceItem.audioContainer.PlaySoundFX("NormalBlock");
sourceItem.feedbackSc["NormalBlock"]?.Play();
sourceItem.blockData.InstantiateBlockEffect(normalEffectName, blockEffectPosition, Quaternion.identity);
sourceItem.blockData.InstantiateBlockEffect(normalEffectName, sourceCharacter, blockEffectPosition, Quaternion.identity);
}
onNormalBlock?.Invoke(attackArea);

View File

@@ -142,23 +142,23 @@ namespace Cielonos.MainGame.Characters
public void PerfectDodge()
{
onPerfectDodge?.Invoke();
if (sourceItem == null)
{
sourceCharacter.feedbackSc["PerfectDodge"].Play();
Debug.Log("Perfect Dodge!");
}
onPerfectDodge?.Invoke();
}
public void NormalDodge()
{
onNormalDodge?.Invoke();
if (sourceItem == null)
{
sourceCharacter.feedbackSc["NormalDodge"].Play();
}
onNormalDodge?.Invoke();
}
}
}

View File

@@ -136,6 +136,11 @@ namespace Cielonos.MainGame.Characters
foreach (Material mat in baseRenderMaterials)
{
if (!mat.HasProperty("_RimParams"))
{
continue;
}
Tweener rimTween = mat.DOVector(new Vector4(1, 1, 4, 1), "_RimParams", 0.5f)
.From(new Vector4(0, 1, 4, 1))
.OnPlay(() =>
@@ -152,33 +157,6 @@ namespace Cielonos.MainGame.Characters
}
getHitBlinkTween.Play();
/*getHitBlinkTween.OnPlay(() =>
{
effectContainers["GetHitBlink"].SetActive(true);
});
foreach (Material mat in effectRenderMaterials["GetHitBlink"])
{
TweenerCore<Color, Color, ColorOptions> matTween = mat.DOColor(Color.white * 0.5f, "_EmissionColor", 0.05f)
.OnStart(() => mat.EnableKeyword("_EMISSION"))
.From(Color.black)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
mat.SetColor("_EmissionColor", Color.black);
mat.DisableKeyword("_EMISSION");
});
getHitBlinkTween.Join(matTween);
}
getHitBlinkTween.SetLoops(2, LoopType.Yoyo);
getHitBlinkTween.OnComplete(() =>
{
effectContainers["GetHitBlink"].SetActive(false);
});*/
getHitBlinkTween.Play();
}
}

View File

@@ -1,35 +1,107 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using UniRx;
using UnityEngine;
using SLSFramework.General;
namespace Cielonos.MainGame.Characters
{
public partial class SelfTimeSubmodule : SubmoduleBase<CharacterBase>
{
public FloatReactiveProperty timeScaleCoefficient;
public float TimeScale => timeScaleCoefficient.Value * Time.timeScale;
public float DeltaTime => timeScaleCoefficient.Value * Time.deltaTime;
private TimeManager timeManager => TimeManager.Instance;
private IObservable<float> timeScaleObservable;
public FloatReactiveProperty localTimeScale;
private float globalTimeScale => timeManager.globalTimeScale.Value;
private float playerTimeScale => timeManager.playerTimeScale.Value;
private float alliedMinionTimeScale => timeManager.alliedMinionTimeScale.Value;
private float enemyTimeScale => timeManager.enemyTimeScale.Value;
private float nonPlayerTimeScale => timeManager.nonPlayerTimeScale.Value;
public float TimeScale => owner.fraction switch
{
Fraction.Player => localTimeScale.Value * globalTimeScale * playerTimeScale,
Fraction.AlliedMinion => localTimeScale.Value * globalTimeScale * alliedMinionTimeScale * nonPlayerTimeScale,
Fraction.Enemy => localTimeScale.Value * globalTimeScale * enemyTimeScale * nonPlayerTimeScale,
Fraction.Neutral => localTimeScale.Value * globalTimeScale * nonPlayerTimeScale,
_ => localTimeScale.Value * globalTimeScale
};
public float DeltaTime => owner.fraction switch
{
Fraction.Player => Time.deltaTime * localTimeScale.Value * globalTimeScale * playerTimeScale,
Fraction.AlliedMinion => Time.deltaTime * localTimeScale.Value * globalTimeScale * alliedMinionTimeScale * nonPlayerTimeScale,
Fraction.Enemy => Time.deltaTime * localTimeScale.Value * globalTimeScale * enemyTimeScale * nonPlayerTimeScale,
Fraction.Neutral => Time.deltaTime * localTimeScale.Value * globalTimeScale * nonPlayerTimeScale,
_ => Time.deltaTime * localTimeScale.Value * globalTimeScale
};
public SelfTimeSubmodule(CharacterBase entity) : base(entity)
{
timeScaleCoefficient = new FloatReactiveProperty(1);
localTimeScale = new FloatReactiveProperty(1);
switch (owner.fraction)
{
case Fraction.Player:
// 依赖: local, global, player
timeScaleObservable =
localTimeScale.CombineLatest(
timeManager.globalTimeScale,
timeManager.playerTimeScale,
(local, global, player) => local * global * player
);
break;
case Fraction.AlliedMinion:
// 依赖: local, global, alliedMinion, nonPlayer
timeScaleObservable =
localTimeScale.CombineLatest(
timeManager.globalTimeScale,
timeManager.alliedMinionTimeScale,
timeManager.nonPlayerTimeScale,
(local, global, minion, nonPlayer) => local * global * minion * nonPlayer
);
break;
case Fraction.Enemy:
// 依赖: local, global, enemy, nonPlayer
timeScaleObservable =
localTimeScale.CombineLatest(
timeManager.globalTimeScale,
timeManager.enemyTimeScale,
timeManager.nonPlayerTimeScale,
(local, global, enemy, nonPlayer) => local * global * enemy * nonPlayer
);
break;
case Fraction.Neutral:
// 依赖: local, global, nonPlayer
timeScaleObservable =
localTimeScale.CombineLatest(
timeManager.globalTimeScale,
timeManager.nonPlayerTimeScale,
(local, global, nonPlayer) => local * global * nonPlayer
);
break;
default:
throw new ArgumentOutOfRangeException();
}
if (entity.animationSc != null)
{
timeScaleCoefficient.Subscribe(x =>
timeScaleObservable.Subscribe(timeScale =>
{
entity.animationSc.fullBodyFuncAnimSm.currentPlaySpeedMultiplier = x;
entity.animationSc.fullBodyFuncAnimSm.currentPlaySpeedMultiplier = timeScale;
});
}
if (entity.animationSc.animator != null)
{
timeScaleCoefficient.Subscribe(x =>
timeScaleObservable.Subscribe(timeScale =>
{
entity.animationSc.animator.speed = x;
entity.animationSc.animator.speed = timeScale;
});
}
}
@@ -59,6 +131,26 @@ namespace Cielonos.MainGame.Characters
() => onComplete?.Invoke() // 4. 流结束时TakeWhile 返回 false执行 Action
).AddTo(owner); // 5. 绑定生命周期到角色,防止内存泄漏
}
public IDisposable AddGlobalTimer(float duration, Action onComplete, Action onUpdate = null)
{
// 用于记录累积时间
float accumulatedTime = 0f;
return Observable.EveryUpdate()
.Select(_ => Time.deltaTime) // 1. 获取每帧的全局 DeltaTime
.TakeWhile(dt =>
{
// 2. 累加时间
accumulatedTime += dt;
// 3. 如果累积时间小于总时长,继续流;否则停止流并触发 OnCompleted
return accumulatedTime < duration;
})
.Subscribe(
_ => onUpdate?.Invoke(), // 每帧更新时执行 Action
() => onComplete?.Invoke() // 4. 流结束时TakeWhile 返回 false执行 Action
).AddTo(owner); // 5. 绑定生命周期到角色,防止内存泄漏
}
}
public partial class SelfTimeSubmodule
@@ -84,7 +176,7 @@ namespace Cielonos.MainGame.Characters
hitStopDisposable?.Dispose();
// 2. 设置当前的缩放倍率
timeScaleCoefficient.Value = targetScale;
localTimeScale.Value = targetScale;
// 3. 开启计时器
// 注意:这里使用 Scheduler.MainThread它是基于 Time.time (全局时间) 的。
@@ -95,7 +187,7 @@ namespace Cielonos.MainGame.Characters
.Subscribe(_ =>
{
// 计时结束,恢复为 1
timeScaleCoefficient.Value = 1f;
localTimeScale.Value = 1f;
hitStopDisposable = null;
})
.AddTo(owner); // 安全性:如果角色在顿帧期间死亡/销毁,自动取消计时器
@@ -105,17 +197,16 @@ namespace Cielonos.MainGame.Characters
/// 使用曲线动态修改本地时间流速
/// </summary>
/// <param name="duration">持续时间(秒)</param>
/// <param name="start">曲线值为0时对应的时间倍率通常是初始值</param>
/// <param name="peak">曲线值为1时对应的时间倍率通常是极值</param>
/// <param name="curve">时间变化曲线归一化X轴0~1Y轴通常0~1。如果为null则使用默认的“先升后降”抛物线。</param>
public void ModifyTimeScale(float duration, float start, float peak, AnimationCurve curve = null)
/// <param name="zeroValue">曲线起点值</param>
/// <param name="oneValue">曲线终点值</param>
/// <param name="easeType">插值曲线(null 则使用默认的 EaseInOut (从0到1) 曲线)</param>
public void ModifyTimeScale(float duration, EaseType easeType, float zeroValue = 0, float oneValue = 1)
{
// 1. 清理旧的计时器
hitStopDisposable?.Dispose();
// 2. 处理默认曲线逻辑
curve ??= DefaultParabola;
AnimationCurve curve = Ease.GetCurve(easeType);
// 3. 记录开始时的累计时间
float timer = 0f;
@@ -125,30 +216,27 @@ namespace Cielonos.MainGame.Characters
.Subscribe(
_ =>
{
// 累加时间 (使用 Time.deltaTime 以响应全局暂停)
timer += Time.deltaTime;
// 累加时间
timer += DeltaTime;
// 计算归一化进度 (0.0 ~ 1.0)
float progress = Mathf.Clamp01(timer / duration);
// 计算归一化时间(0 1
float normalizedTime = Mathf.Clamp01(timer / duration);
// 核心逻辑:
// A. 从曲线获取当前的“强度” (Y轴值)
float curveValue = curve.Evaluate(progress);
// 根据曲线获取当前的插值系数
float curveValue = curve.Evaluate(normalizedTime);
// B. 在 start 和 peak 之间根据强度进行插
// 当 curveValue = 0 时,结果为 start
// 当 curveValue = 1 时,结果为 peak
float currentScale = Mathf.Lerp(start, peak, curveValue);
// 计算当前的时间缩放
float currentScale = curveValue * (oneValue - zeroValue) + zeroValue;
// C. 应用到响应式属性
timeScaleCoefficient.Value = currentScale;
// 应用到 timeScaleCoefficient
localTimeScale.Value = currentScale;
},
() =>
{
// 5. 计时结束后的收尾工作
// 通常为了安全,结束后我们会强制恢复到 1.0 (正常速度)
// 或者你可以恢复到 start视具体需求而定
timeScaleCoefficient.Value = 1f;
localTimeScale.Value = 1f;
hitStopDisposable = null;
}
)
@@ -159,7 +247,7 @@ namespace Cielonos.MainGame.Characters
public void ResetTimeScale()
{
hitStopDisposable?.Dispose();
timeScaleCoefficient.Value = 1f;
localTimeScale.Value = 1f;
}
}
}

View File

@@ -99,9 +99,9 @@ namespace Cielonos.MainGame.Characters
{
if (IsMoving)
{
operation.Dash();
player.landMovementSc.TurnToDirection(new Vector3(Move.x, 0, Move.y));
preinputSubmodule.RegisterPreinputAction(() => operation.Dash(), 10);
Vector3 direction = new Vector3(Move.x, 0, Move.y);
operation.Dash(direction);
preinputSubmodule.RegisterPreinputAction(() => operation.Dash(direction), 10);
}
else
{

View File

@@ -2,6 +2,7 @@ using System;
using System.Linq;
using Cielonos.UI;
using FIMSpace.FProceduralAnimation;
using MoreMountains.FeedbacksForThirdParty;
using RootMotion.FinalIK;
using SLSFramework.General;
using SLSUtilities.FunctionalAnimation;
@@ -20,8 +21,24 @@ namespace Cielonos.MainGame.Characters
public override void Initialize()
{
base.Initialize();
player.operationSc.OnDash += delegate { fullBodyFuncAnimSm.Play("Dash"); };
player.operationSc.OnDodge += delegate { fullBodyFuncAnimSm.Play("Dodge"); };
player.operationSc.OnDash += delegate(Vector3 dashDirection)
{
player.landMovementSc.TurnToDirection(dashDirection);
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
Vector3 dashCameraRotation = CalculateDashAngles(dashDirection, cameraForward);
player.feedbackSc["Dash"].feedback.GetFeedbackOfType<MMF_CinemachineRotation>().RotationAmplitude = dashCameraRotation;
player.feedbackSc["Dash"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
fullBodyFuncAnimSm.Play("Dash");
};
player.operationSc.OnDodge += delegate
{
Vector3 dodgeDirection = Vector3.back;
Vector3 cameraForward = player.viewSc.playerCamera.transform.forward.Flatten();
Vector3 dodgeCameraRotation = CalculateDashAngles(dodgeDirection, cameraForward);
player.feedbackSc["Dodge"].feedback.GetFeedbackOfType<MMF_CinemachineRotation>().RotationAmplitude = dodgeCameraRotation;
player.feedbackSc["Dodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
fullBodyFuncAnimSm.Play("Dodge");
};
}
protected override void Update()
@@ -44,7 +61,7 @@ namespace Cielonos.MainGame.Characters
{
player.landMovementSc.isDashing = true;
player.landMovementSc.dashMoveMultiplier = anim.funcAnimData.variableCollection.GetVariable<float>("DashMoveMultiplier");
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(0.2f);
player.selfTimeSm.ModifyTimeScale(0.1f, 1.25f);
player.audioSc.PlayDashSound();
player.feedbackSc["Dash"]?.Play();
//player.renderSc.dashTrails.ForEach(ds => ds.active = true);
@@ -53,14 +70,8 @@ namespace Cielonos.MainGame.Characters
DodgeSource defaultDodge = new DodgeSource(owner, null, "DefaultDodge", 0, "NormalDodge", "PerfectDodge", Mathf.Infinity, 0.2f);
defaultDodge.onPerfectDodge = () =>
{
PostProcessingManager.Instance.chromaticAberrationSm.SetIntensity(0.5f);
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(0.2f);
PostProcessingManager.Instance.tonemappingSm.SetContrast(1.35f);
PostProcessingManager.Instance.tonemappingSm.SetSaturate(-2f);
player.attributeSm["Energy"] += 25;
player.attributeSm["Energy"] = Mathf.Min(player.attributeSm["Energy"], player.attributeSm["MaximumEnergy"]);
PlayerCanvas.Instance.playerInfoUIArea.UpdateEnergy();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_AdvancedVignette>().Center = player.GetNormalizedScreenPosition();
};
player.reactionSc.dodgeSm.ApplyDodge(defaultDodge);
});
@@ -79,7 +90,6 @@ namespace Cielonos.MainGame.Characters
{
player.landMovementSc.isDashing = true;
player.landMovementSc.dashMoveMultiplier = anim.funcAnimData.variableCollection.GetVariable<float>("DashMoveMultiplier");
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(-0.2f);
player.audioSc.PlayDashSound();
player.feedbackSc["Dodge"]?.Play();
//player.renderSc.dashTrails.ForEach(ds => ds.active = true);
@@ -88,14 +98,8 @@ namespace Cielonos.MainGame.Characters
DodgeSource defaultDodge = new DodgeSource(owner, null, "DefaultDodge", 0, "NormalDodge", "PerfectDodge", Mathf.Infinity, 0.2f);
defaultDodge.onPerfectDodge = () =>
{
PostProcessingManager.Instance.chromaticAberrationSm.SetIntensity(0.5f);
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(-0.2f);
PostProcessingManager.Instance.tonemappingSm.SetContrast(1.35f);
PostProcessingManager.Instance.tonemappingSm.SetSaturate(-2.2f);
player.attributeSm["Energy"] += 25;
player.attributeSm["Energy"] = Mathf.Min(player.attributeSm["Energy"], player.attributeSm["MaximumEnergy"]);
PlayerCanvas.Instance.playerInfoUIArea.UpdateEnergy();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_AdvancedVignette>().Center = player.GetNormalizedScreenPosition();
};
player.reactionSc.dodgeSm.ApplyDodge(defaultDodge);
});
@@ -124,4 +128,31 @@ namespace Cielonos.MainGame.Characters
isAtActionDisruption = lastFrameIntervals.SwitchOut(currentIntervals, (interval) => interval.intervalType == IntervalType.Preinput);
}
}
public partial class PlayerAnimationSubcontroller
{
/// <summary>
/// 计算冲刺时的相机倾斜和俯仰
/// </summary>
/// <param name="dashDir">世界空间的冲刺向量 (如 Vector3.forward)</param>
/// <param name="camForwardNoY">相机的前方 (y被设为0并归一化)</param>
/// <returns>x为Pitch(俯仰), z为Dutch(侧倾)</returns>
public Vector3 CalculateDashAngles(Vector3 dashDir, Vector3 camForwardNoY)
{
// 1. 获取相机的右方
Vector3 camRight = Vector3.Cross(Vector3.up, camForwardNoY);
// 2. 将冲刺方向投影到相机的 前/后 和 左/右 轴上
float forwardDot = Vector3.Dot(dashDir, camForwardNoY); // 1为前-1为后
float rightDot = Vector3.Dot(dashDir, camRight); // 1为右-1为左
// 3. 计算目标侧倾值
float targetDutch = forwardDot * 1f;
// 4. 计算目标俯仰值(注意取反,使得向前冲刺时相机向下俯仰)
float targetPitch = -rightDot * 2.0f;
return new Vector3(targetPitch, 0, targetDutch);
}
}
}

View File

@@ -20,7 +20,7 @@ namespace Cielonos.MainGame.Characters
{
public event Action OnInteract;
public event Action OnDash;
public event Action<Vector3> OnDash;
public event Action OnDodge;
public event Action OnLockOnTarget;
@@ -63,7 +63,7 @@ namespace Cielonos.MainGame.Characters
{
public void Interact() => OnInteract?.Invoke();
public void Dash() => OnDash?.Invoke();
public void Dash(Vector3 direction) => OnDash?.Invoke(direction);
public void Dodge() => OnDodge?.Invoke();

View File

@@ -5,6 +5,7 @@ using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;
using Ease = DG.Tweening.Ease;
namespace Cielonos.MainGame.Characters
{
@@ -25,14 +26,11 @@ namespace Cielonos.MainGame.Characters
public CameraRotationSubmodule cameraRotationSm;
public OcclusionFadeSubmodule occlusionFadeSm;
public LerpFloat cameraDistance;
public override void Initialize()
{
base.Initialize();
cameraRotationSm = new CameraRotationSubmodule(this, player.transform.eulerAngles.y);
occlusionFadeSm = new OcclusionFadeSubmodule(this);
cameraDistance = new LerpFloat(10f, 1f);
}
private void Start()
@@ -54,10 +52,6 @@ namespace Cielonos.MainGame.Characters
SwitchToFreeLook();
}
}
cameraDistance.Update(player.selfTimeSm.DeltaTime);
freeLookCamera.GetComponent<CinemachineThirdPersonFollow>().CameraDistance = cameraDistance.currentValue;
lockOnCamera.GetComponent<CinemachinePositionComposer>().CameraDistance = cameraDistance.currentValue;
}
private void LateUpdate()

View File

@@ -0,0 +1,19 @@
using DamageNumbersPro;
using UnityEngine;
namespace Cielonos.MainGame
{
public class DamageNumberText : MonoBehaviour
{
public DamageNumber main;
}
public static class DamageNumberTextExtensions
{
public static DamageNumberText Spawn(this DamageNumberText prefab)
{
prefab.main.Spawn();
return prefab;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 39efce2b6a5b2b74e9f95573a238547c

View File

@@ -1,30 +0,0 @@
using SLSFramework.General;
using Beautify.Universal;
namespace Cielonos.MainGame.Effects
{
public partial class ChromaticAberrationSubmodule : PostProcessingSubmoduleBase
{
public LerpFloat intensity;
public ChromaticAberrationSubmodule(PostProcessingManager owner) : base(owner)
{
this.intensity = new LerpFloat(0, 0.05f);
}
public override void Update(float factor)
{
intensity.Update(factor);
if (owner.GetVolumeComponent<Beautify.Universal.Beautify>(out var beautify))
{
beautify.chromaticAberrationIntensity.value = intensity.currentValue * 0.1f;
}
}
}
public partial class ChromaticAberrationSubmodule
{
public void ModifyIntensity(float value) => ModifyCurrentValue(intensity, value);
public void SetIntensity(float value) => SetCurrentValue(intensity, value);
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 4c4d822e0b008874595c833896ced6b8

View File

@@ -1,51 +0,0 @@
using SLSFramework.General;
using UnityEngine;
namespace Cielonos.MainGame.Effects
{
public partial class TonemappingSubmodule : PostProcessingSubmoduleBase
{
public LerpFloat saturate;
public LerpFloat contrast;
public LerpFloat brightness;
public LerpColor tintColor;
public TonemappingSubmodule(PostProcessingManager owner) : base(owner)
{
this.saturate = new LerpFloat(1.2f, 0.05f);
this.brightness = new LerpFloat(1f, 0.05f);
this.contrast = new LerpFloat(1.15f, 0.05f);
this.tintColor = new LerpColor(new Color(0.9411765f, 1, 1), 0.05f);
}
public override void Update(float factor)
{
saturate.Update(factor);
brightness.Update(factor);
contrast.Update(factor);
tintColor.Update(factor);
if(owner.GetVolumeComponent<Beautify.Universal.Beautify>(out var beautify))
{
beautify.saturate.value = saturate.currentValue;
beautify.brightness.value = brightness.currentValue;
beautify.contrast.value = contrast.currentValue;
beautify.tintColor.value = tintColor.currentValue;
}
}
}
public partial class TonemappingSubmodule
{
public void ModifySaturate(float value) => ModifyCurrentValue(saturate, value);
public void SetSaturate(float value) => SetCurrentValue(saturate, value);
public void ModifyBrightness(float value) => ModifyCurrentValue(brightness, value);
public void SetBrightness(float value) => SetCurrentValue(brightness, value);
public void ModifyContrast(float value) => ModifyCurrentValue(contrast, value);
public void SetContrast(float value) => SetCurrentValue(contrast, value);
public void ModifyTintColor(Color value) => ModifyCurrentValue(tintColor, value);
public void SetTintColor(Color value) => SetCurrentValue(tintColor, value);
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: b40b17602d6f8fe4f86ca42ae86514e4

View File

@@ -15,9 +15,7 @@ namespace Cielonos
public RadialBlurSubmodule radialBlurSm;
public SpeedLinesSubmodule speedLinesSm;
public ChromaticAberrationSubmodule chromaticAberrationSm;
public RGBSplitGlitchSubmodule rgbSplitGlitchSm;
public TonemappingSubmodule tonemappingSm;
[Tooltip("主要的后处理 Volume")]
[SerializeField]
@@ -32,9 +30,7 @@ namespace Cielonos
base.Awake();
radialBlurSm = new RadialBlurSubmodule(this);
speedLinesSm = new SpeedLinesSubmodule(this);
chromaticAberrationSm = new ChromaticAberrationSubmodule(this);
rgbSplitGlitchSm = new RGBSplitGlitchSubmodule(this);
tonemappingSm = new TonemappingSubmodule(this);
if (volume != null)
{
profile = volume.profile;
@@ -48,11 +44,11 @@ namespace Cielonos
private void Update()
{
radialBlurSm.Update(MainGameManager.PlayerTimeScale);
speedLinesSm.Update(MainGameManager.PlayerTimeScale);
rgbSplitGlitchSm.Update(MainGameManager.PlayerTimeScale);
chromaticAberrationSm.Update(MainGameManager.PlayerTimeScale);
tonemappingSm.Update(MainGameManager.PlayerTimeScale);
//radialBlurSm.Update(MainGameManager.PlayerTimeScale);
speedLinesSm.Update(MainGameManager.Player.selfTimeSm.TimeScale);
//rgbSplitGlitchSm.Update(MainGameManager.PlayerTimeScale);
//chromaticAberrationSm.Update(MainGameManager.PlayerTimeScale);
//tonemappingSm.Update(MainGameManager.PlayerTimeScale);
}
/// <summary>

View File

@@ -13,10 +13,11 @@ namespace Cielonos.MainGame
[NonSerialized]
public CharacterBase creator;
public bool affectedByCreatorTimeScale = true;
public List<ParticleSystem> particles = new List<ParticleSystem>();
[NonSerialized]
public List<ParticleSystem.MainModule> particleMainModules = new List<ParticleSystem.MainModule>();
[NonSerialized] private List<ParticleSystem.MainModule> particleMainModules;
public static GameObject Spawn(GameObject vfxPrefab, CharacterBase creator, Transform parent = null)
{
@@ -45,10 +46,14 @@ namespace Cielonos.MainGame
}
base.OnSpawn();
particleMainModules = new List<ParticleSystem.MainModule>();
foreach (var ps in particles)
if (particleMainModules == null)
{
particleMainModules.Add(ps.main);
particleMainModules = new List<ParticleSystem.MainModule>();
foreach (var ps in particles)
{
particleMainModules.Add(ps.main);
}
}
}
@@ -63,22 +68,25 @@ namespace Cielonos.MainGame
particles.Add(ps);
}
}
protected override void Update()
{
float deltaTime = Time.deltaTime;
float timeScale = 1f;
if (creator != null)
{
deltaTime = creator.selfTimeSm.DeltaTime;
timeScale = creator.selfTimeSm.timeScaleCoefficient.Value;
timeScale = creator.selfTimeSm.TimeScale;
}
UpdateTimer(deltaTime);
particleMainModules.ForEach(main => main.simulationSpeed = timeScale);
if (affectedByCreatorTimeScale)
{
particleMainModules.ForEach(main => main.simulationSpeed = timeScale);
}
}
public void SetCreator(CharacterBase character)
{
creator = character;

View File

@@ -1,4 +1,5 @@
using Cielonos.MainGame.Characters;
using MoreMountains.Feedbacks;
using MoreMountains.FeedbacksForThirdParty;
using UnityEngine;
@@ -98,18 +99,36 @@ namespace Cielonos.MainGame.Inventory
public partial class MainWeaponBase
{
protected void Swing(string swingAudio = "", string feedBackName = "", Vector3 force = default)
protected void Swing(string swingAudio, string feedBackName)
{
if (!string.IsNullOrEmpty(swingAudio))
{
audioContainer.PlaySoundFX(swingAudio, null, true);
}
if (force != default)
feedbackSc[feedBackName].Play();
}
protected void Swing(string swingAudio, string feedBackName, Vector3 swingRotation, Vector3 swingVelocity = default)
{
if (!string.IsNullOrEmpty(swingAudio))
{
feedbackSc[feedBackName].feedback.GetFeedbackOfType<MMF_CinemachineImpulse>().Velocity = force;
feedbackSc[feedBackName].Play();
audioContainer.PlaySoundFX(swingAudio, null, true);
}
MMF_CinemachineRotation cinemachineRotation = feedbackSc[feedBackName].feedback.GetFeedbackOfType<MMF_CinemachineRotation>();
if (cinemachineRotation != null)
{
cinemachineRotation.RotationAmplitude = swingRotation != default ? swingRotation : Vector3.zero;
}
MMF_CinemachineImpulse cinemachineImpulse = feedbackSc[feedBackName].feedback.GetFeedbackOfType<MMF_CinemachineImpulse>();
if (cinemachineImpulse != null)
{
cinemachineImpulse.Velocity = swingVelocity != default ? swingVelocity : Vector3.zero;
}
feedbackSc[feedBackName].Play();
}
}
}

View File

@@ -43,11 +43,12 @@ namespace Cielonos.MainGame.Inventory
"NormalBlock", "PerfectBlock", defaultBlockTime, perfectTime);
}
public GameObject InstantiateBlockEffect(string effectName, Vector3 position, Quaternion rotation)
public GameObject InstantiateBlockEffect(string effectName, CharacterBase creator, Vector3 position, Quaternion rotation)
{
if (blockEffects.TryGetValue(effectName, out GameObject effect))
{
return LeanPool.Spawn(effect, position, rotation);
GameObject obj = VFXObject.Spawn(effect, creator, position, rotation);
return obj;
}
return null;

View File

@@ -1,7 +1,7 @@
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.Characters.Buffs;
using SLSFramework.General;
using SLSUtilities.FunctionalAnimation;
using Unity.Cinemachine;
using UnityEngine;
namespace Cielonos.MainGame.Inventory
@@ -110,7 +110,7 @@ namespace Cielonos.MainGame.Inventory
fullBodyFuncAnimSm.Stop(DisruptionType.ForcedAction);
}
RemoveBlock();
player.selfTimeSm.AddLocalTimer(0.1f, RemoveBlock);
player.movementSc.canMove.Modify(true);
player.movementSc.canRotate.Modify(true);
}
@@ -118,22 +118,22 @@ namespace Cielonos.MainGame.Inventory
public partial class Polychrome
{
private void LightAttack0() => GenerateNormalSlash("LightAttack0", new Vector3(1f, 0.6f, 0).normalized * 0.1f);
private void LightAttack1() => GenerateNormalSlash("LightAttack1", new Vector3(-1f, -0.6f, 0).normalized * 0.1f);
private void LightAttack2() => GenerateNormalSlash("LightAttack2", new Vector3(-1f, 0.6f, 0).normalized * 0.1f);
private void LightAttack3() => GenerateNormalSlash("LightAttack3", Vector3.right * 0.1f);
private void TripleAttack_0() => GenerateFastSlash("TripleAttack_0", new Vector3(1f, 0.6f, 0).normalized * 0.2f);
private void TripleAttack_1() => GenerateFastSlash("TripleAttack_1", new Vector3(-1f, -0.6f, 0).normalized * 0.2f);
private void TripleAttack_2() => GenerateFastSlash("TripleAttack_2", Vector3.right * 0.2f);
private void HeavyAttack() => GenerateHeavySlash("HeavyAttack", new Vector3(1f, 0.6f, 0).normalized * 0.4f);
private void RunAttack() => GenerateMoveSlash("RunAttack", new Vector3(1f, 0.6f, 0).normalized * 0.1f, player.transform.forward * 10f);
private void ParryAttack() => GenerateParrySlash("ParryAttack", new Vector3(-1f, -0.6f, 0).normalized * 0.4f);
private void LightAttack0() => GenerateNormalSlash("LightAttack0", new Vector3(0.5f, 1f, 0));
private void LightAttack1() => GenerateNormalSlash("LightAttack1", new Vector3(-0.5f, -1f, 0));
private void LightAttack2() => GenerateNormalSlash("LightAttack2", new Vector3(0.8f, -1.2f, 0));
private void LightAttack3() => GenerateNormalSlash("LightAttack3", new Vector3(0.5f, 1.5f, 0));
private void TripleAttack_0() => GenerateFastSlash("TripleAttack_0", new Vector3(1f, 0.6f, 0));
private void TripleAttack_1() => GenerateFastSlash("TripleAttack_1", new Vector3(-1f, -0.6f, 0));
private void TripleAttack_2() => GenerateFastSlash("TripleAttack_2", Vector3.right);
private void HeavyAttack() => GenerateHeavySlash("HeavyAttack", new Vector3(3, -2, -5));
private void RunAttack() => GenerateMoveSlash("RunAttack", new Vector3(1f, 0.6f, 0), player.transform.forward * 10f);
private void ParryAttack() => GenerateParrySlash("ParryAttack", new Vector3(5, 3, -8));
private void DisruptAttack() => GenerateDisruptSlash("DisruptAttack", new Vector3(1f, 0, 0).normalized * 0.4f);
}
public partial class Polychrome
{
private NormalArea GenerateNormalSlash(string vfxName, Vector3 swingForce)
private NormalArea GenerateNormalSlash(string vfxName, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
@@ -148,12 +148,10 @@ namespace Cielonos.MainGame.Inventory
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.06f);
enemy.selfTimeSm.ModifyTimeScale(0.06f);
new ElectronicDisturbance(2).Apply(enemy);
});
Swing("Swing", "Swing", swingForce);
Swing("NormalSwing", "NormalSwing", swingRotation);
return slash;
}
@@ -168,13 +166,14 @@ namespace Cielonos.MainGame.Inventory
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
string hitFeedbackName = vfxName != "TripleAttack_2" ? "FastHitFirsts" : "FastHitFinal";
slash.hitSm
.AddHitSound("NormalHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.06f);
enemy.selfTimeSm.ModifyTimeScale(0.06f);
feedbackSc[hitFeedbackName].Play();
new ElectronicDisturbance(2).Apply(enemy);
if (enemy.statusSm.HasStatus(StatusType.Incapacitation))
@@ -183,33 +182,35 @@ namespace Cielonos.MainGame.Inventory
}
});
Swing("Swing", "Swing", swingForce);
Swing("NormalSwing", "NormalSwing", swingForce);
return slash;
}
private NormalArea GenerateHeavySlash(string vfxName, Vector3 swingForce)
private NormalArea GenerateHeavySlash(string vfxName, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["HeavyAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.16f)
.SetHitSubmodule<NormalArea>()
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.2f)
.SetHitSubmodule<NormalArea>(0.04f, 4)
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.12f);
enemy.selfTimeSm.ModifyTimeScale(0.12f);
player.viewSc.cameraDistance.currentValue -= 2f;
feedbackSc["HeavyHitFirst"].Play();
new ElectronicDisturbance(5).Apply(enemy);
});
}, 0)
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHitFollows"].Play();
new ElectronicDisturbance(5).Apply(enemy);
}, 1, 2, 3);
Swing("Swing", "Swing", swingForce);
Swing("HeavySwing", "HeavySwing", swingRotation);
return slash;
}
@@ -228,13 +229,18 @@ namespace Cielonos.MainGame.Inventory
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHit"].Play();
feedbackSc["ParryHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.12f);
enemy.selfTimeSm.ModifyTimeScale(0.12f);
player.selfTimeSm.AddGlobalTimer(0.12f, () =>
{
player.selfTimeSm.ModifyTimeScale(0.2f, 0.3f);
enemy.selfTimeSm.ModifyTimeScale(0.2f, 0.3f);
});
new ElectronicDisturbance(5).Apply(enemy);
});
Swing("Swing", "Swing", swingForce);
Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
@@ -253,13 +259,11 @@ namespace Cielonos.MainGame.Inventory
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.12f);
enemy.selfTimeSm.ModifyTimeScale(0.12f);
feedbackSc["DisruptHit"].Play();
new ElectronicDisturbance(5).Apply(enemy);
});
Swing("Swing", "Swing", swingForce);
Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
@@ -280,12 +284,10 @@ namespace Cielonos.MainGame.Inventory
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.06f);
enemy.selfTimeSm.ModifyTimeScale(0.06f);
new ElectronicDisturbance(2).Apply(enemy);
});
Swing("Swing", "Swing", swingForce);
Swing("NormalSwing", "NormalSwing", swingForce);
}
string parryAnimName = "ParryL";
@@ -295,10 +297,20 @@ namespace Cielonos.MainGame.Inventory
BlockSource blockSource = blockData.CreateBlockSource(player, this);
blockSource.onNormalBlock = (attackArea) =>
{
PostProcessingManager.Instance.chromaticAberrationSm.ModifyIntensity(0.2f);
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(0.2f);
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
if (parryAnimName == "ParryL")
{
feedbackSc["NormalBlockLeft"].Play();
}
else
{
feedbackSc["NormalBlockRight"].Play();
}
if (attackArea is NormalArea)
{
new ElectronicDisturbance(2).Apply(attackArea.creator);
@@ -306,15 +318,27 @@ namespace Cielonos.MainGame.Inventory
};
blockSource.onPerfectBlock = (attackArea) =>
{
PostProcessingManager.Instance.chromaticAberrationSm.ModifyIntensity(0.5f);
PostProcessingManager.Instance.radialBlurSm.ModifyBlurRadius(0.5f);
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
if (parryAnimName == "ParryL")
{
feedbackSc["PerfectBlockLeft"].Play();
}
else
{
feedbackSc["PerfectBlockRight"].Play();
}
perfectBlockedTimer = 0.5f;
if (attackArea is NormalArea)
{
new ElectronicDisturbance(10).Apply(attackArea.creator);
}
//Debug.Break();
};
player.reactionSc.blockSm.ApplyBlock(blockSource);
//blockDisposable?.Dispose();

View File

@@ -15,6 +15,8 @@ namespace Cielonos.MainGame.Inventory
{
foreach (var feedbackUnit in feedbacks.Values)
{
float timeScaleMultiplier = owner.player.selfTimeSm.TimeScale;
feedbackUnit.feedback.ExternalTimeScale = timeScaleMultiplier;
feedbackUnit.Update();
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using DamageNumbersPro;
using Sirenix.OdinInspector;
using UnityEngine;
@@ -8,7 +9,7 @@ namespace Cielonos.MainGame
public class BasePrefabsCollection : SerializedScriptableObject
{
public GameObject audioPoint;
public Dictionary<string, GameObject> hudTextCollection;
public Dictionary<string, DamageNumber> hudTextCollection;
public Dictionary<BreakthroughType, Color> outlineColorCollection;
}

View File

@@ -1,3 +1,4 @@
using System;
using Cielonos.MainGame.Characters;
using SLSFramework.General;
using UnityEngine;
@@ -14,15 +15,17 @@ namespace Cielonos.MainGame
protected override void Awake()
{
base.Awake();
Application.targetFrameRate = 120;
}
private void Start()
{
Application.targetFrameRate = 60;
}
}
public partial class MainGameManager
{
public static Player Player => Instance.player;
public static float PlayerTimeScale => Instance.player.selfTimeSm.TimeScale;
public static float PlayerDeltaTime => Instance.player.selfTimeSm.DeltaTime;
public static BasePrefabsCollection BasePrefabs => Instance.basePrefabs;
}
}

View File

@@ -0,0 +1,15 @@
using SLSFramework.General;
using UniRx;
using UnityEngine;
namespace Cielonos.MainGame
{
public class TimeManager : Singleton<TimeManager>
{
public FloatReactiveProperty globalTimeScale = new FloatReactiveProperty(1f);
public FloatReactiveProperty playerTimeScale = new FloatReactiveProperty(1f);
public FloatReactiveProperty alliedMinionTimeScale = new FloatReactiveProperty(1f);
public FloatReactiveProperty nonPlayerTimeScale = new FloatReactiveProperty(1f);
public FloatReactiveProperty enemyTimeScale = new FloatReactiveProperty(1f);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 588340523f272b040ac2333d06c0443b