177 lines
5.4 KiB
C#
177 lines
5.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace Assets.Scripts.Utils
|
|
{
|
|
internal class UvAnimation : MonoBehaviour
|
|
{
|
|
public int TilesX = 4;
|
|
public int TilesY = 4;
|
|
public float Fps = 30;
|
|
public int StartFrameOffset;
|
|
public bool IsLoop = true;
|
|
public float StartDelay = 0;
|
|
public bool IsReverse;
|
|
public bool IsBump;
|
|
|
|
public AnimationCurve FrameOverTime = AnimationCurve.Linear(0, 1, 1, 1);
|
|
|
|
private bool _isInizialised;
|
|
private int _index;
|
|
private int _count, _allCount;
|
|
private float _animationLifeTime;
|
|
private bool _isVisible;
|
|
private bool _isCorutineStarted;
|
|
private Renderer _currentRenderer;
|
|
private Material _instanceMaterial;
|
|
private float _animationStartTime;
|
|
private bool _animationStoped;
|
|
|
|
private void Start()
|
|
{
|
|
_currentRenderer = GetComponent<Renderer>();
|
|
InitDefaultVariables();
|
|
_isInizialised = true;
|
|
_isVisible = true;
|
|
Play();
|
|
}
|
|
|
|
private void InitDefaultVariables()
|
|
{
|
|
_currentRenderer = GetComponent<Renderer>();
|
|
if (_currentRenderer == null)
|
|
throw new Exception("UvTextureAnimator can't get renderer");
|
|
if (!_currentRenderer.enabled)
|
|
_currentRenderer.enabled = true;
|
|
_allCount = 0;
|
|
_animationStoped = false;
|
|
_animationLifeTime = TilesX * TilesY / Fps;
|
|
_count = TilesY * TilesX;
|
|
_index = TilesX - 1;
|
|
var offset = Vector3.zero;
|
|
StartFrameOffset = StartFrameOffset - (StartFrameOffset / _count) * _count;
|
|
var size = new Vector2(1f / TilesX, 1f / TilesY);
|
|
|
|
if (_currentRenderer != null)
|
|
{
|
|
_instanceMaterial = _currentRenderer.material;
|
|
_instanceMaterial.SetTextureScale("_MainTex", size);
|
|
_instanceMaterial.SetTextureOffset("_MainTex", offset);
|
|
if (IsBump)
|
|
{
|
|
_instanceMaterial.SetTextureScale("_BumpMap", size);
|
|
_instanceMaterial.SetTextureOffset("_BumpMap", offset);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Play()
|
|
{
|
|
if (_isCorutineStarted)
|
|
return;
|
|
if (StartDelay > 0.0001f)
|
|
Invoke("PlayDelay", StartDelay);
|
|
else
|
|
StartCoroutine(UpdateCorutine());
|
|
_isCorutineStarted = true;
|
|
}
|
|
|
|
private void PlayDelay()
|
|
{
|
|
StartCoroutine(UpdateCorutine());
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (!_isInizialised)
|
|
return;
|
|
InitDefaultVariables();
|
|
_isVisible = true;
|
|
Play();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_isCorutineStarted = false;
|
|
_isVisible = false;
|
|
StopAllCoroutines();
|
|
CancelInvoke("PlayDelay");
|
|
}
|
|
|
|
|
|
private IEnumerator UpdateCorutine()
|
|
{
|
|
_animationStartTime = Time.time;
|
|
while (_isVisible && (IsLoop || !_animationStoped))
|
|
{
|
|
if (!IsReverse)
|
|
UpdateFrame();
|
|
else
|
|
UpdateFrameReversed();
|
|
|
|
if (!IsLoop && _animationStoped)
|
|
break;
|
|
|
|
var frameTime = (Time.time - _animationStartTime) / _animationLifeTime;
|
|
var currentSpeedFps = FrameOverTime.Evaluate(Mathf.Clamp01(frameTime));
|
|
yield return new WaitForSeconds(1f / (Fps * currentSpeedFps));
|
|
}
|
|
_isCorutineStarted = false;
|
|
//currentRenderer.enabled = false;
|
|
}
|
|
|
|
private void UpdateFrame()
|
|
{
|
|
++_allCount;
|
|
++_index;
|
|
if (_index >= _count)
|
|
_index = 0;
|
|
if (_count == _allCount)
|
|
{
|
|
_animationStartTime = Time.time;
|
|
_allCount = 0;
|
|
_animationStoped = true;
|
|
}
|
|
var offset = new Vector2((float)_index / TilesX - (int)(_index / TilesX), 1 - (int)(_index / TilesX) / (float)TilesY);
|
|
if (_currentRenderer != null)
|
|
{
|
|
_instanceMaterial.SetTextureOffset("_MainTex", offset);
|
|
if (IsBump)
|
|
_instanceMaterial.SetTextureOffset("_BumpMap", offset);
|
|
|
|
}
|
|
}
|
|
|
|
private void UpdateFrameReversed()
|
|
{
|
|
--_allCount;
|
|
--_index;
|
|
if (_index <= 0)
|
|
_index = _count;
|
|
if (_count == _allCount)
|
|
{
|
|
_animationStartTime = Time.time;
|
|
_allCount = 0;
|
|
_animationStoped = true;
|
|
}
|
|
var offset = new Vector2((float)_index / TilesX - (int)(_index / TilesX), 1 - (int)(_index / TilesX) / (float)TilesY);
|
|
if (_currentRenderer != null)
|
|
{
|
|
_instanceMaterial.SetTextureOffset("_MainTex", offset);
|
|
if (IsBump)
|
|
_instanceMaterial.SetTextureOffset("_BumpMap", offset);
|
|
}
|
|
}
|
|
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_instanceMaterial != null)
|
|
{
|
|
Destroy(_instanceMaterial);
|
|
_instanceMaterial = null;
|
|
}
|
|
}
|
|
}
|
|
} |