Files
JJBB/Assets/Project/Script/Player/Impact/ChangeMatPro.cs
2024-08-23 15:49:34 +08:00

298 lines
11 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 Games.LogicObj;
using GCGame.Table;
using Module.Log;
using System.Collections.Generic;
using UnityEngine;
using StringComparison = System.StringComparison;
//所有需要改变材质属性值得,都通过该类管理实现
/// EffectParams
/// 参数1 类型个数
/// 参数2 属性类型 int float color 等
/// 参数3 属性名称
/// 参数4 属性开始数值 当是 Color Vector等类型时 配置形式 1,1,1,1。配置Default表示材质默认值。
/// 参数5 属性结束数值 当是 Color Vector等类型时 配置形式 1,1,1,1。配置Default表示材质默认值。
/// 参数6 渐变参数,该属性从开始到结束过渡方式 -1整个过程渐变0保持开始数值>0渐变(渐变持续时间)
public class ChangeMatPro
{
private const string _defaultValueName = "Default";
private const string _intTypeName = "int";
private const string _floatTypeName = "float";
private const string _colorTypeName = "color";
private const string _vectorTypeName = "vector";
private const string _macroTypeName = "macro";
protected Obj obj;
protected int part;
protected Tab_EffectParam effectParam;
private readonly List<MatProFloatToken> _floatTokenList;
private readonly List<MatProVectorToken> _vectorTokenList;
private readonly List<int> _macroTokenList;
public ChangeMatPro(Obj obj, int part, Tab_EffectParam effectParam)
{
this.obj = obj;
this.part = part;
this.effectParam = effectParam;
_floatTokenList = new List<MatProFloatToken>();
_vectorTokenList = new List<MatProVectorToken>();
_macroTokenList = new List<int>();
}
public void Start(Tab_EffectParam param, float duration)
{
if (obj != null && param != null)
{
var countStr = param.GetParamValuebyIndex(0);
int count;
if (!string.IsNullOrEmpty(countStr) && int.TryParse(countStr, out count))
{
for (var i = 0; i < count; i++)
{
var index = i * 5 + 1;
var properType = param.GetParamValuebyIndex(index);
var properName = param.GetParamValuebyIndex(index + 1);
var startValue = param.GetParamValuebyIndex(index + 2);
var endValue = param.GetParamValuebyIndex(index + 3);
var fadeOutTime = param.GetParamValuebyIndex(index + 4);
AddProperty(properType, properName, startValue, endValue, fadeOutTime, duration);
}
}
}
}
public void SetRatio(float ratio)
{
for (var i = 0; i < _floatTokenList.Count; i++)
{
var token = _floatTokenList[i];
token.SetRatio(ratio);
obj.ModifyFloatPropertyMod(token.token, token.Current, part);
}
for (var i = 0; i < _vectorTokenList.Count; i++)
{
var token = _vectorTokenList[i];
token.SetRatio(ratio);
obj.ModifyVectorPropertyMod(token.token, token.Current, part);
}
}
private void AddProperty(string propertyType, string propertyName, string startValue, string endValue, string fadeOutTime, float duration)
{
// 临时使用这个变量提高代码重用率0 = 无效1 = float 2 = vector
var propertyTypeInt = 0;
if (string.Equals(propertyType, _intTypeName, StringComparison.CurrentCultureIgnoreCase) ||
string.Equals(propertyType, _floatTypeName, StringComparison.CurrentCultureIgnoreCase))
propertyTypeInt = 1;
else if (string.Equals(propertyType, _colorTypeName, StringComparison.CurrentCultureIgnoreCase) ||
string.Equals(propertyType, _vectorTypeName, StringComparison.CurrentCultureIgnoreCase))
propertyTypeInt = 2;
else if (string.Equals(propertyType, _macroTypeName, StringComparison.CurrentCultureIgnoreCase))
propertyTypeInt = 3;
if (propertyTypeInt > 0)
{
float fadeStart;
if (float.TryParse(fadeOutTime, out fadeStart))
{
if (fadeStart <= -1f)
fadeStart = Time.time;
else if (fadeStart <= 0f)
fadeStart = Time.time + duration;
else
fadeStart = Time.time + Mathf.Max(0f, duration - fadeStart);
}
else
{
LogModule.ErrorLog(string.Format("效果参数id={0}中,渐变时间{1}无法转换为浮点数!", effectParam.EffectParamID, fadeOutTime));
fadeStart = Time.time + duration;
}
switch (propertyTypeInt)
{
case 1:
{
// Float类型属性
var targetValue = StringToFloatValue(startValue, propertyName);
var defaultValue = StringToFloatValue(endValue, propertyName);
var nameId = Shader.PropertyToID(propertyName);
var token = obj.CreateFloatPropertyMod(nameId, targetValue, part);
var floatToken = new MatProFloatToken(token, targetValue, defaultValue, duration, fadeStart);
_floatTokenList.Add(floatToken);
}
break;
case 2:
{
// Vector类型属性
var targetValue = StringToVectorValue(startValue, propertyName);
var defaultValue = StringToVectorValue(endValue, propertyName);
var nameId = Shader.PropertyToID(propertyName);
var token = obj.CreateVectorPropertyMod(nameId, targetValue, part);
var vectorToken = new MatProVectorToken(token, targetValue, defaultValue, duration, fadeStart);
_vectorTokenList.Add(vectorToken);
}
break;
case 3:
{
// 材质宏属性
var token = obj.CreateMacroPropertyMod(propertyName, part);
_macroTokenList.Add(token);
}
break;
}
}
}
private float StringToFloatValue(string stringValue, string propertyName)
{
float result;
if (string.Equals(stringValue, _defaultValueName, StringComparison.CurrentCultureIgnoreCase))
result = obj.GetDefaultFloat(0, propertyName, part);
else
{
if (!float.TryParse(stringValue, out result))
{
LogPropertyValueParseError(effectParam.EffectParamID, stringValue, "Float");
result = default(float);
}
}
return result;
}
private Vector4 StringToVectorValue(string stringValue, string propertyName)
{
const string vectorTypeName = "Vector";
Vector4 result;
if (string.Equals(stringValue, _defaultValueName, StringComparison.CurrentCultureIgnoreCase))
result = obj.GetDefaultVector(0, propertyName, part);
else
{
result = default(Vector4);
var targetStrArray = stringValue.Trim('"').Split(',');
if (targetStrArray.Length == 4)
{
for (var i = 0; i < targetStrArray.Length; i++)
{
float floatValue;
if (float.TryParse(targetStrArray[i], out floatValue))
result[i] = floatValue;
else
{
LogPropertyValueParseError(effectParam.EffectParamID, stringValue, vectorTypeName);
break;
}
}
}
else
LogPropertyValueParseError(effectParam.EffectParamID, stringValue, vectorTypeName);
}
return result;
}
private static void LogPropertyValueParseError(int id, string properValue, string propertyType)
{
LogModule.ErrorLog(string.Format("效果参数id={0}中,{1}数值无法转换为{2}", id, properValue, propertyType));
}
public void StopEffect()
{
if (obj != null)
{
// 应该StopEffect后上层会抛弃数据因此不额外清空数列
for (var i = 0; i < _floatTokenList.Count; i++)
obj.RemoveFloatPropertyMod(_floatTokenList[i].token, part);
for (var i = 0; i < _vectorTokenList.Count; i++)
obj.RemoveVectorPropertyMod(_vectorTokenList[i].token, part);
for (var i = 0; i < _macroTokenList.Count; i++)
obj.RemoveMacroPropertyMode(_macroTokenList[i], part);
}
}
public void OnUpdate()
{
if (obj != null)
{
for (var i = 0; i < _floatTokenList.Count; i++)
{
var token = _floatTokenList[i];
token.Update();
if (token.ValueUpdate)
obj.ModifyFloatPropertyMod(token.token, token.Current, part);
}
for (var i = 0; i < _vectorTokenList.Count; i++)
{
var token = _vectorTokenList[i];
token.Update();
if (token.ValueUpdate)
obj.ModifyVectorPropertyMod(token.token, token.Current, part);
}
}
}
public abstract class MatProToken<T>
{
public int token;
public T targetValue;
public T defaultValue;
public float duration;
public float fadeStart;
public bool ValueUpdate { get; private set; }
public T Current { get; private set; }
protected MatProToken(int token, T targetValue, T defaultValue, float duration, float fadeStart)
{
this.token = token;
this.targetValue = targetValue;
this.defaultValue = defaultValue;
this.duration = duration;
this.fadeStart = fadeStart;
}
public void Update()
{
var value = GetValue();
ValueUpdate = !value.Equals(Current);
Current = value;
}
public void SetRatio(float ratio)
{
Current = LerpValue(targetValue, defaultValue, ratio);
}
private T GetValue()
{
if (Time.time > fadeStart)
return LerpValue(targetValue, defaultValue, (Time.time - fadeStart) / duration);
else
return targetValue;
}
protected abstract T LerpValue(T start, T end, float ratio);
}
public class MatProFloatToken : MatProToken<float>
{
public MatProFloatToken(int token, float targetValue, float defaultValue, float duration, float fadeStart) :
base(token, targetValue, defaultValue, duration, fadeStart)
{
}
protected override float LerpValue(float start, float end, float ratio)
{
return Mathf.Lerp(start, end, ratio);
}
}
public class MatProVectorToken : MatProToken<Vector4>
{
public MatProVectorToken(int token, Vector4 targetValue, Vector4 defaultValue, float duration, float fadeStart) :
base(token, targetValue, defaultValue, duration, fadeStart)
{
}
protected override Vector4 LerpValue(Vector4 start, Vector4 end, float ratio)
{
return Vector4.Lerp(start, end, ratio);
}
}
}