Files
JJBB/Assets/Project/Script/Player/Impact/ChangeMatPro.cs

298 lines
11 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
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);
}
}
}