将Spline移出Plugin,以调整SplineRenderer的OnWillCameraRender
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class ColorModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ColorKey : Key
|
||||
{
|
||||
public enum BlendMode { Lerp, Multiply, Add, Subtract }
|
||||
public Color color = Color.white;
|
||||
public BlendMode blendMode = BlendMode.Lerp;
|
||||
|
||||
public ColorKey(double f, double t) : base(f, t)
|
||||
{
|
||||
}
|
||||
|
||||
public Color Blend(Color input, float percent)
|
||||
{
|
||||
switch (blendMode)
|
||||
{
|
||||
case BlendMode.Lerp: return Color.Lerp(input, color, blend * percent);
|
||||
case BlendMode.Add: return input + color * blend * percent;
|
||||
case BlendMode.Subtract: return input - color * blend * percent;
|
||||
case BlendMode.Multiply: return Color.Lerp(input, input * color, blend * percent);
|
||||
default: return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Length > 0;
|
||||
public ColorKey[] keys = new ColorKey[0];
|
||||
|
||||
public ColorModifier()
|
||||
{
|
||||
keys = new ColorKey[0];
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
return new List<Key>(keys);
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new ColorKey[input.Count];
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
keys[i] = (ColorKey)input[i];
|
||||
}
|
||||
base.SetKeys(input);
|
||||
}
|
||||
|
||||
public void AddKey(double f, double t)
|
||||
{
|
||||
ArrayUtility.Add(ref keys, new ColorKey(f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
if (keys.Length == 0) return;
|
||||
base.Apply(ref result);
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
result.color = keys[i].Blend(result.color, keys[i].Evaluate(result.percent) * blend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07c5bf379e882994f9828b66623ef12f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,75 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class FollowerSpeedModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class SpeedKey : Key
|
||||
{
|
||||
public enum Mode { Add, Multiply }
|
||||
public float speed = 0f;
|
||||
public Mode mode = Mode.Add;
|
||||
|
||||
public SpeedKey(double f, double t) : base(f, t)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Count > 0;
|
||||
public List<SpeedKey> keys = new List<SpeedKey>();
|
||||
|
||||
public FollowerSpeedModifier()
|
||||
{
|
||||
keys = new List<SpeedKey>();
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
List<Key> output = new List<Key>();
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
output.Add(keys[i]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new List<SpeedKey>();
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
//input[i]._modifier = this;
|
||||
keys.Add((SpeedKey)input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddKey(double f, double t)
|
||||
{
|
||||
keys.Add(new SpeedKey(f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
}
|
||||
|
||||
public float GetSpeed(float input, double percent)
|
||||
{
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
float lerp = keys[i].Evaluate(percent);
|
||||
if(keys[i].mode == SpeedKey.Mode.Add)
|
||||
{
|
||||
input += keys[i].speed * lerp;
|
||||
} else
|
||||
{
|
||||
input *= Mathf.Lerp(1f, keys[i].speed, lerp);
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ef79d2db1fdbb54588b21a1643fabd2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class MeshScaleModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ScaleKey : Key
|
||||
{
|
||||
public Vector3 scale = Vector3.one;
|
||||
|
||||
public ScaleKey(double f, double t) : base(f, t)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Count > 0;
|
||||
public List<ScaleKey> keys = new List<ScaleKey>();
|
||||
|
||||
public MeshScaleModifier()
|
||||
{
|
||||
keys = new List<ScaleKey>();
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
List<Key> output = new List<Key>();
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
output.Add(keys[i]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new List<ScaleKey>();
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
keys.Add((ScaleKey)input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddKey(double f, double t)
|
||||
{
|
||||
keys.Add(new ScaleKey(f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
if (keys.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
result.size += keys[i].Evaluate(result.percent) * keys[i].scale.magnitude * blend;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetScale(SplineSample sample)
|
||||
{
|
||||
Vector3 scale = Vector3.one;
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
float lerp = keys[i].Evaluate(sample.percent);
|
||||
Vector3 scaleMultiplier = Vector3.Lerp(Vector3.one, keys[i].scale, lerp);
|
||||
scale.x *= scaleMultiplier.x;
|
||||
scale.y *= scaleMultiplier.y;
|
||||
scale.z *= scaleMultiplier.z;
|
||||
}
|
||||
return Vector3.Lerp(Vector3.one, scale, blend);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7be735bc80e43dc43984bdce01839e2e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class OffsetModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class OffsetKey : Key
|
||||
{
|
||||
public Vector2 offset = Vector2.zero;
|
||||
public OffsetKey(Vector2 o, double f, double t) : base(f, t)
|
||||
{
|
||||
offset = o;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Length > 0;
|
||||
public OffsetKey[] keys = new OffsetKey[0];
|
||||
|
||||
public OffsetModifier()
|
||||
{
|
||||
keys = new OffsetKey[0];
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
return new List<Key>(keys);
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new OffsetKey[input.Count];
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
keys[i] = (OffsetKey)input[i];
|
||||
}
|
||||
base.SetKeys(input);
|
||||
}
|
||||
|
||||
public void AddKey(Vector2 offset, double f, double t)
|
||||
{
|
||||
ArrayUtility.Add(ref keys, new OffsetKey(offset, f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
if (keys.Length == 0) return;
|
||||
base.Apply(ref result);
|
||||
Vector2 offset = Evaluate(result.percent);
|
||||
result.position += result.right * offset.x + result.up * offset.y;
|
||||
}
|
||||
|
||||
public Vector2 Evaluate(double time)
|
||||
{
|
||||
if (keys.Length == 0) return Vector2.zero;
|
||||
Vector2 offset = Vector2.zero;
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
offset += keys[i].offset * keys[i].Evaluate(time);
|
||||
}
|
||||
return offset * blend;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d0cc7c794f1e3148acddeb3d008c597
|
||||
timeCreated: 1482692196
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[System.Serializable]
|
||||
public class RotationModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class RotationKey : Key
|
||||
{
|
||||
public bool useLookTarget = false;
|
||||
public Transform target = null;
|
||||
public Vector3 rotation = Vector3.zero;
|
||||
|
||||
public RotationKey(Vector3 rotation, double f, double t) : base(f, t)
|
||||
{
|
||||
this.rotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Length > 0;
|
||||
public RotationKey[] keys = new RotationKey[0];
|
||||
|
||||
public RotationModifier()
|
||||
{
|
||||
keys = new RotationKey[0];
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
return new List<Key>(keys);
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new RotationKey[input.Count];
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
keys[i] = (RotationKey)input[i];
|
||||
}
|
||||
base.SetKeys(input);
|
||||
}
|
||||
|
||||
public void AddKey(Vector3 rotation, double f, double t)
|
||||
{
|
||||
ArrayUtility.Add(ref keys, new RotationKey(rotation, f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
if (keys.Length == 0) return;
|
||||
base.Apply(ref result);
|
||||
|
||||
Quaternion offset = Quaternion.identity, look = result.rotation;
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
if (keys[i].useLookTarget && keys[i].target != null)
|
||||
{
|
||||
Quaternion lookDir = Quaternion.LookRotation(keys[i].target.position - result.position);
|
||||
look = Quaternion.Slerp(look, lookDir, keys[i].Evaluate(result.percent) * blend);
|
||||
}
|
||||
else
|
||||
{
|
||||
Quaternion euler = Quaternion.Euler(keys[i].rotation.x, keys[i].rotation.y, keys[i].rotation.z);
|
||||
offset = Quaternion.Slerp(offset, offset * euler, keys[i].Evaluate(result.percent) * blend);
|
||||
}
|
||||
}
|
||||
Quaternion rotation = look * offset;
|
||||
Vector3 invertedNormal = Quaternion.Inverse(result.rotation) * result.up;
|
||||
result.forward = rotation * Vector3.forward;
|
||||
result.up = rotation * invertedNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0049066920c0f4549af72ec0044c71c6
|
||||
timeCreated: 1482692196
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class SizeModifier : SplineSampleModifier
|
||||
{
|
||||
[System.Serializable]
|
||||
public class SizeKey : Key
|
||||
{
|
||||
public float size = 0f;
|
||||
|
||||
public SizeKey(double f, double t) : base(f, t)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public override bool hasKeys => keys.Length > 0;
|
||||
public SizeKey[] keys = new SizeKey[0];
|
||||
|
||||
public SizeModifier()
|
||||
{
|
||||
keys = new SizeKey[0];
|
||||
}
|
||||
|
||||
public override List<Key> GetKeys()
|
||||
{
|
||||
return new List<Key>(keys);
|
||||
}
|
||||
|
||||
public override void SetKeys(List<Key> input)
|
||||
{
|
||||
keys = new SizeKey[input.Count];
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
keys[i] = (SizeKey)input[i];
|
||||
}
|
||||
base.SetKeys(input);
|
||||
}
|
||||
|
||||
public void AddKey(double f, double t)
|
||||
{
|
||||
ArrayUtility.Add(ref keys, new SizeKey(f, t));
|
||||
}
|
||||
|
||||
public override void Apply(ref SplineSample result)
|
||||
{
|
||||
if (keys.Length == 0) return;
|
||||
base.Apply(ref result);
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
result.size += keys[i].Evaluate(result.percent) * keys[i].size * blend;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 896008ffd57dfab499f9f0745f7dbb4f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,193 @@
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class SplineSampleModifier
|
||||
{
|
||||
[Range(0f, 1f)]
|
||||
public float blend = 1f;
|
||||
public bool useClippedPercent = false;
|
||||
|
||||
public virtual bool hasKeys => false;
|
||||
|
||||
public virtual List<Key> GetKeys()
|
||||
{
|
||||
return new List<Key>();
|
||||
}
|
||||
|
||||
public virtual void SetKeys(List<Key> input)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Apply(ref SplineSample result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Apply(ref SplineSample source, ref SplineSample destination)
|
||||
{
|
||||
destination = source;
|
||||
Apply(ref destination);
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Key
|
||||
{
|
||||
public double start
|
||||
{
|
||||
get { return _featherStart; }
|
||||
set {
|
||||
if (value != _featherStart)
|
||||
{
|
||||
_featherStart = DMath.Clamp01(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double end
|
||||
{
|
||||
get { return _featherEnd; }
|
||||
set {
|
||||
if (value != _featherEnd)
|
||||
{
|
||||
_featherEnd = DMath.Clamp01(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public double centerStart
|
||||
{
|
||||
get { return _centerStart; }
|
||||
set {
|
||||
if (value != _centerStart)
|
||||
{
|
||||
_centerStart = DMath.Clamp01(value);
|
||||
if (_centerStart > _centerEnd) _centerStart = _centerEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double centerEnd
|
||||
{
|
||||
get { return _centerEnd; }
|
||||
set {
|
||||
if (value != _centerEnd)
|
||||
{
|
||||
_centerEnd = DMath.Clamp01(value);
|
||||
if (_centerEnd < _centerStart) _centerEnd = _centerStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public double globalCenterStart
|
||||
{
|
||||
get {
|
||||
return LocalToGlobalPercent(centerStart);
|
||||
}
|
||||
set
|
||||
{
|
||||
centerStart = DMath.Clamp01(GlobalToLocalPercent(value));
|
||||
}
|
||||
}
|
||||
|
||||
public double globalCenterEnd
|
||||
{
|
||||
get
|
||||
{
|
||||
return LocalToGlobalPercent(centerEnd);
|
||||
}
|
||||
set
|
||||
{
|
||||
centerEnd = DMath.Clamp01(GlobalToLocalPercent(value));
|
||||
}
|
||||
}
|
||||
|
||||
public double position
|
||||
{
|
||||
get
|
||||
{
|
||||
double center = DMath.Lerp(_centerStart, _centerEnd, 0.5);
|
||||
if (start > end)
|
||||
{
|
||||
double fromToEndDistance = 1.0 - _featherStart;
|
||||
double centerDistance = center * (fromToEndDistance + _featherEnd);
|
||||
double pos = _featherStart + centerDistance;
|
||||
if (pos > 1.0) pos -= 1.0;
|
||||
return pos;
|
||||
}
|
||||
else return DMath.Lerp(_featherStart, _featherEnd, center);
|
||||
|
||||
}
|
||||
set
|
||||
{
|
||||
double delta = value - position;
|
||||
start += delta;
|
||||
end += delta;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private double _featherStart = 0.0, _featherEnd = 0.0, _centerStart = 0.25, _centerEnd = 0.75;
|
||||
public AnimationCurve interpolation;
|
||||
public float blend = 1f;
|
||||
|
||||
internal Key(double f, double t)
|
||||
{
|
||||
start = f;
|
||||
end = t;
|
||||
interpolation = AnimationCurve.Linear(0f, 0f, 1f, 1f);
|
||||
}
|
||||
|
||||
private double GlobalToLocalPercent(double t)
|
||||
{
|
||||
if (_featherStart > _featherEnd)
|
||||
{
|
||||
if (t > _featherStart) return DMath.InverseLerp(_featherStart, _featherStart + (1.0 - _featherStart) + _featherEnd, t);
|
||||
else if (t < _featherEnd) return DMath.InverseLerp(-(1.0 - _featherStart), _featherEnd, t);
|
||||
else return 0f;
|
||||
}
|
||||
return DMath.InverseLerp(_featherStart, _featherEnd, t);
|
||||
}
|
||||
|
||||
private double LocalToGlobalPercent(double t)
|
||||
{
|
||||
if (_featherStart > _featherEnd)
|
||||
{
|
||||
t = DMath.Lerp(_featherStart, _featherStart + (1.0 - _featherStart) + _featherEnd, t);
|
||||
if (t > 1.0) t -= 1.0;
|
||||
return t;
|
||||
}
|
||||
return DMath.Lerp(_featherStart, _featherEnd, t);
|
||||
}
|
||||
|
||||
public float Evaluate(double t)
|
||||
{
|
||||
t = (float)GlobalToLocalPercent(t);
|
||||
if (t < _centerStart)
|
||||
{
|
||||
return interpolation.Evaluate((float)(t / _centerStart)) * blend;
|
||||
}
|
||||
|
||||
if (t > _centerEnd)
|
||||
{
|
||||
return interpolation.Evaluate(1f - (float)DMath.InverseLerp(_centerEnd, 1.0, t)) * blend;
|
||||
}
|
||||
return interpolation.Evaluate(1f) * blend;
|
||||
}
|
||||
|
||||
public virtual Key Duplicate()
|
||||
{
|
||||
Key newKey = new Key(start, end);
|
||||
newKey._centerStart = _centerStart;
|
||||
newKey._centerEnd = _centerEnd;
|
||||
newKey.blend = blend;
|
||||
newKey.interpolation = DuplicateUtility.DuplicateCurve(interpolation);
|
||||
return newKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26a8731450d83c541afa4dd71666f85d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user