298 lines
11 KiB
C#
298 lines
11 KiB
C#
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);
|
||
}
|
||
}
|
||
} |