123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- 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;
-
- }
- 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;
- }
- }
- }
- }
|