123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- using System;
- using System.Collections;
- using UnityEngine;
- namespace Assets.Scripts.Utils
- {
- [RequireComponent(typeof(Projector))]
- internal sealed class ProjectorTextureAnimation : MonoBehaviour
- {
- public int TilesX = 4;
- public int TilesY = 4;
- public float Fps = 30;
- public AnimationCurve FrameOverTime = AnimationCurve.Linear(0, 1, 1, 1);
- private Projector _projector;
- private Material _projectorMaterial;
- private Material _originalMaterial;
- private float _animationLifeTime;
- private int _index;
- private int _countOfTextures, _currentNumOfTexture;
- private bool _isStarted;
- private bool _isCanceled;
- private float _animationStartTime;
- private void Start()
- {
- _projector = GetComponent<Projector>();
- if (_projector == null)
- throw new InvalidOperationException("Could not get projector");
- _animationLifeTime = TilesX * TilesY / Fps;
- _index = TilesX - 1;
- _countOfTextures = TilesY * TilesX;
- Play();
- }
- private void Play()
- {
- if (_isStarted)
- return;
- if (_projector == null || _projector.material == null)
- return;
- _originalMaterial = _projector.material;
- _projectorMaterial = Instantiate(_projector.material);
- _projector.material = _projectorMaterial;
- if (_originalMaterial == null)
- return;
- var offset = Vector3.zero;
- var size = new Vector2(1f / TilesX, 1f / TilesY);
- _projectorMaterial.SetTextureScale("_MainTex", size);
- _projectorMaterial.SetTextureOffset("_MainTex", offset);
- _isStarted = true;
- StartCoroutine(UpdateCorutine());
- }
- private IEnumerator UpdateCorutine()
- {
- _animationStartTime = Time.time;
- while (!_isCanceled)
- {
- UpdateFrame();
- var frameTime = (Time.time - _animationStartTime) / _animationLifeTime;
- var currentSpeedFps = FrameOverTime.Evaluate(Mathf.Clamp01(frameTime));
- yield return new WaitForSeconds(1f / (Fps * currentSpeedFps));
- }
- }
- private void UpdateFrame()
- {
- ++_currentNumOfTexture;
- ++_index;
- if (_index >= _countOfTextures)
- _index = 0;
- if (_currentNumOfTexture == _countOfTextures)
- {
- _animationStartTime = Time.time;
- _currentNumOfTexture = 0;
- }
- var offset = new Vector2((float)_index / TilesX - (int)(_index / TilesX), 1 - (int)(_index / TilesX) / (float)TilesY);
- if (_projector != null)
- _projectorMaterial.SetTextureOffset("_MainTex", offset);
- }
- private void Stop()
- {
- _isStarted = false;
- _isCanceled = true;
- StopAllCoroutines();
- _projector.material = _originalMaterial;
- //_projectorMaterial.SetTextureScale("_MainTex", new Vector2(1, 1));
- //_projectorMaterial.SetTextureOffset("_MainTex", new Vector2(0, 0));
- }
- private void OnEnable()
- {
- Play();
- }
- private void OnDisable()
- {
- Stop();
- }
- private void OnDestroy()
- {
- Stop();
- }
- }
- }
|