119 lines
3.5 KiB
C#
119 lines
3.5 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|