last update
This commit is contained in:
@@ -1,32 +1,61 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using Zenject;
|
||||
using UltraFace;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class AnimationHandler : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Transform _sberText;
|
||||
[SerializeField] private Transform _mirror;
|
||||
[SerializeField] private Transform _sberPrimeLogo;
|
||||
[SerializeField] private ParticleSystem _sberEffect;
|
||||
private Vector3 _sberScale, _sberPosition;
|
||||
|
||||
[SerializeField] private List<Transform> _firstGroup = new List<Transform>();
|
||||
[SerializeField] private List<Transform> _secondGroup = new List<Transform>();
|
||||
[SerializeField] private List<Transform> _thirdGroup = new List<Transform>();
|
||||
|
||||
[SerializeField] private List<Transform> _objects = new List<Transform>();
|
||||
[SerializeField] private List<ParticleSystem> _effects = new List<ParticleSystem>();
|
||||
[Inject] private Visualizer _visualizer;
|
||||
|
||||
private Dictionary<string, Vector3> _scales;
|
||||
private Dictionary<string, Vector3> _positions;
|
||||
private Dictionary<string, ParticleSystem> _effectDict;
|
||||
private Dictionary<string, Quaternion> _rotations;
|
||||
private Vector3 _baseScale;
|
||||
|
||||
private List<Tween> _rotationAnimations = new List<Tween>();
|
||||
private List<Tween> _animations = new List<Tween>();
|
||||
|
||||
private static CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private CancellationToken _ct = _cts.Token;
|
||||
|
||||
public event Action OnAnimationEnded;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_sberText.DOLocalMoveY(_sberText.localPosition.y - .25f, 2.5f)
|
||||
_sberScale = _sberPrimeLogo.localScale;
|
||||
|
||||
_sberPrimeLogo.DOLocalMoveY(_sberPrimeLogo.localPosition.y - .25f, 2.5f)
|
||||
.SetEase(Ease.InOutSine)
|
||||
.SetLoops(-1, LoopType.Yoyo);
|
||||
|
||||
_sberPrimeLogo.localScale = Vector3.zero;
|
||||
|
||||
var sberEffectEmission = _sberEffect.emission;
|
||||
sberEffectEmission.enabled = false;
|
||||
|
||||
_scales = new Dictionary<string, Vector3>();
|
||||
_positions = new Dictionary<string, Vector3>();
|
||||
_effectDict = new Dictionary<string, ParticleSystem>();
|
||||
_visualizer.OnDetectionStatusChanged += OnFaceDetected;
|
||||
_rotations = new Dictionary<string, Quaternion>();
|
||||
|
||||
_visualizer.OnDetectionStatusChanged += isDetected => OnFaceDetected(isDetected).Forget();
|
||||
|
||||
foreach(var item in _objects)
|
||||
{
|
||||
@@ -35,9 +64,10 @@ public class AnimationHandler : MonoBehaviour
|
||||
_scales.Add(item.name, item.localScale);
|
||||
item.DOScale(Vector3.zero, 0);
|
||||
|
||||
item.DOLocalMoveY(item.localPosition.y + (index == _objects.Count - 1 ? .2f : .5f), Random.Range(2f, 5f))
|
||||
.SetEase(Ease.InOutSine)
|
||||
.SetLoops(-1, LoopType.Yoyo);
|
||||
_positions.Add(item.name, item.position);
|
||||
item.localPosition = Vector3.zero;
|
||||
|
||||
_rotations.Add(item.name, item.rotation);
|
||||
}
|
||||
|
||||
for(int i = 0; i < _objects.Count; i++)
|
||||
@@ -50,49 +80,154 @@ public class AnimationHandler : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFaceDetected(bool isDetected)
|
||||
private async UniTaskVoid OnFaceDetected(bool isDetected)
|
||||
{
|
||||
if(isDetected)
|
||||
{
|
||||
foreach(var tween in _rotationAnimations)
|
||||
tween.Kill();
|
||||
|
||||
_rotationAnimations = new List<Tween>();
|
||||
await UniTask.Delay(300, false, PlayerLoopTiming.Update, _ct);
|
||||
|
||||
foreach(var item in _objects)
|
||||
_sberPrimeLogo.DOScale(_sberScale, .2f);
|
||||
var sberEmission = _sberEffect.emission;
|
||||
sberEmission.enabled = true;
|
||||
|
||||
foreach(var effect in _effects)
|
||||
{
|
||||
int index = _objects.IndexOf(item);
|
||||
|
||||
if(index != _objects.Count - 1 || index % 2 == 0)
|
||||
item.DOLocalRotate(Vector3.up * 360 * 2, Random.Range(1f, 2f))
|
||||
.SetRelative()
|
||||
.SetEase(Ease.InOutSine)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
_rotationAnimations.Add(item.DOLocalRotate(new Vector3(0, index % 2 == 0 ? 360f : 0, 0), Random.Range(10f, 14f))
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetRelative()
|
||||
.SetEase(Ease.InOutSine));
|
||||
});
|
||||
|
||||
item.DOScale(_scales[item.name], 1f)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
var emission = _effectDict[item.name].emission;
|
||||
emission.enabled = true;
|
||||
});
|
||||
var emission = effect.emission;
|
||||
emission.enabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
await PlayGroupAnimation(_firstGroup);
|
||||
await UniTask.Delay(50, false, PlayerLoopTiming.Update, _ct);
|
||||
await PlayGroupAnimation(_secondGroup);
|
||||
await UniTask.Delay(50, false, PlayerLoopTiming.Update, _ct);
|
||||
await PlayGroupAnimation(_thirdGroup);
|
||||
|
||||
OnAnimationEnded?.Invoke();
|
||||
|
||||
foreach(var effect in _effects)
|
||||
{
|
||||
var emission = effect.emission;
|
||||
emission.enabled = false;
|
||||
}
|
||||
|
||||
foreach(var item in _objects)
|
||||
item.DOScale(Vector3.zero, .2f);
|
||||
sberEmission.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cts.Cancel();
|
||||
_cts = new CancellationTokenSource();
|
||||
_ct = _cts.Token;
|
||||
|
||||
foreach(var tween in _animations)
|
||||
tween.Kill();
|
||||
_animations = new List<Tween>();
|
||||
|
||||
foreach(var item in _objects)
|
||||
{
|
||||
item.DOScale(0, .2f)
|
||||
.OnComplete(()=> item.DOLocalMove(Vector3.zero, 0));
|
||||
}
|
||||
|
||||
_sberPrimeLogo.DOScale(Vector3.zero, .2f);
|
||||
var sberEmission = _sberEffect.emission;
|
||||
sberEmission.enabled = false;
|
||||
}
|
||||
|
||||
#region old animation
|
||||
// if(isDetected)
|
||||
// {
|
||||
// foreach(var tween in _rotationAnimations)
|
||||
// tween.Kill();
|
||||
|
||||
// _rotationAnimations = new List<Tween>();
|
||||
|
||||
// foreach(var item in _objects)
|
||||
// {
|
||||
// int index = _objects.IndexOf(item);
|
||||
|
||||
// item.DOLocalRotate(Vector3.up * 360 * 2, Random.Range(1f, 2f))
|
||||
// .SetRelative()
|
||||
// .SetEase(Ease.InOutSine)
|
||||
// .OnComplete(() =>
|
||||
// {
|
||||
// _rotationAnimations.Add(item.DOLocalRotate(new Vector3(0, index % 2 == 0 ? 360f : 0, 0), Random.Range(10f, 14f))
|
||||
// .SetLoops(-1, LoopType.Yoyo)
|
||||
// .SetRelative()
|
||||
// .SetEase(Ease.InOutSine));
|
||||
// });
|
||||
|
||||
// item.DOScale(_scales[item.name], 1f)
|
||||
// .OnComplete(async () =>
|
||||
// {
|
||||
// var emission = _effectDict[item.name].emission;
|
||||
// emission.enabled = true;
|
||||
|
||||
// await UniTask.Delay(1500);
|
||||
|
||||
// emission.enabled = false;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// foreach(var effect in _effects)
|
||||
// {
|
||||
// var emission = effect.emission;
|
||||
// emission.enabled = false;
|
||||
// }
|
||||
|
||||
// foreach(var item in _objects)
|
||||
// item.DOScale(Vector3.zero, .2f);
|
||||
// }
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
private async UniTask PlayGroupAnimation(List<Transform> group)
|
||||
{
|
||||
foreach(var item in group)
|
||||
{
|
||||
item.rotation = _rotations[item.name];
|
||||
|
||||
item.DOScale(_scales[item.name], .9f);
|
||||
item.DOMove(_positions[item.name], .7f)
|
||||
.SetEase(Ease.OutQuad)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
bool isRight = item.transform.position.x - _mirror.position.x > 0;
|
||||
bool isBehind = item.transform.position.z > _mirror.position.z;
|
||||
|
||||
int dir = isRight ? -1 : 1;
|
||||
|
||||
_animations.Add(item.DOLocalMoveY(item.localPosition.y + .5f, Random.Range(2f, 5f))
|
||||
.SetEase(Ease.InOutSine)
|
||||
.SetLoops(-1, LoopType.Yoyo));
|
||||
|
||||
_animations.Add(
|
||||
item.DOLocalRotate(new Vector3(0, 45, 0), Random.Range(10f, 14f))
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetRelative()
|
||||
.SetEase(Ease.InOutSine));
|
||||
|
||||
if(!isBehind)
|
||||
{
|
||||
_animations.Add(
|
||||
item.DOLocalMoveZ(-1f, Random.Range(3f, 5f))
|
||||
.SetRelative()
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetEase(Ease.InOutSine));
|
||||
}
|
||||
|
||||
_animations.Add(
|
||||
item.DOLocalMoveX(isBehind ? .6f * dir : .2f * dir, Random.Range(3f, 5f))
|
||||
.SetRelative()
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetEase(Ease.InOutSine));
|
||||
});
|
||||
|
||||
await UniTask.Delay(200, false, PlayerLoopTiming.Update, _ct);
|
||||
}
|
||||
|
||||
Debug.Log("конец группы");
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ public class FixedImageSource : MonoBehaviour
|
||||
#region Public property
|
||||
|
||||
public Texture Texture => OutputBuffer;
|
||||
public Vector2Int OutputResolution => _outputResolution;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -24,12 +23,11 @@ public class FixedImageSource : MonoBehaviour
|
||||
|
||||
// Webcam options
|
||||
[SerializeField] string _webcamName = "";
|
||||
[SerializeField] Vector2Int _webcamResolution = new Vector2Int(1920, 1080);
|
||||
[SerializeField] Vector2Int _webcamResolution;
|
||||
[SerializeField] int _webcamFrameRate = 30;
|
||||
|
||||
// Output options
|
||||
[SerializeField] RenderTexture _outputTexture = null;
|
||||
[SerializeField] Vector2Int _outputResolution = new Vector2Int(1920, 1080);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -49,28 +47,68 @@ public class FixedImageSource : MonoBehaviour
|
||||
RenderTexture OutputBuffer
|
||||
=> _outputTexture != null ? _outputTexture : _buffer;
|
||||
|
||||
private Texture FlipTextureAsync(WebCamTexture texture, bool clockwiseRotation = false)
|
||||
private Texture2D AdjustWebCamTextureWidth(WebCamTexture webcamTexture, int reductionPixels)
|
||||
{
|
||||
int width = webcamTexture.width;
|
||||
int height = webcamTexture.height;
|
||||
|
||||
int newWidth = width - (reductionPixels * 2);
|
||||
if (newWidth <= 0)
|
||||
{
|
||||
Debug.LogError("Reduction pixels exceed the width of the texture.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Color32[] pixels = webcamTexture.GetPixels32();
|
||||
Color32[] adjustedPixels = new Color32[newWidth * height];
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < newWidth; x++)
|
||||
{
|
||||
int originalX = x + reductionPixels;
|
||||
|
||||
// Проверяем, чтобы не выйти за границы исходной ширины
|
||||
if (originalX >= 0 && originalX < width)
|
||||
{
|
||||
adjustedPixels[y * newWidth + x] = pixels[y * width + originalX];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture2D adjustedTexture = new Texture2D(newWidth, height);
|
||||
adjustedTexture.SetPixels32(adjustedPixels);
|
||||
adjustedTexture.Apply();
|
||||
|
||||
Debug.LogWarning($"{width}x{height} / {adjustedTexture.width}x{adjustedTexture.height}");
|
||||
|
||||
return adjustedTexture;
|
||||
}
|
||||
|
||||
private Texture FlipTexture(WebCamTexture texture, bool clockwiseRotation = false)
|
||||
{
|
||||
int width = texture.width;
|
||||
int height = texture.height;
|
||||
|
||||
Color32[] pixels = texture.GetPixels32();
|
||||
Color32[] flippedPixels = new Color32[pixels.Length];
|
||||
Color32[] rotatedPixels = new Color32[pixels.Length];
|
||||
Texture2D rotatedTexture = new Texture2D(height, width);
|
||||
|
||||
Texture2D flippedTexture = new Texture2D(height, width);
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
for(int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
for(int x = 0; x < width; x++)
|
||||
{
|
||||
flippedPixels[x * height + (height - y - 1)] = pixels[y * width + x];
|
||||
rotatedPixels[width * height - (height * x + height) + y] =
|
||||
pixels[width * height - (width * y + width) + x];
|
||||
}
|
||||
}
|
||||
|
||||
flippedTexture.SetPixels32(flippedPixels);
|
||||
flippedTexture.Apply();
|
||||
rotatedTexture.SetPixels32(rotatedPixels);
|
||||
rotatedTexture.Apply();
|
||||
|
||||
return flippedTexture;
|
||||
Debug.LogWarning($"input: {width}x{height}, output: {rotatedTexture.width}x{rotatedTexture.height}");
|
||||
|
||||
return rotatedTexture;
|
||||
|
||||
#region unsafe handling
|
||||
// int width = texture.width;
|
||||
@@ -140,11 +178,6 @@ public class FixedImageSource : MonoBehaviour
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Allocate a render texture if no output texture has been given.
|
||||
if (_outputTexture == null)
|
||||
_buffer = new RenderTexture
|
||||
(_outputResolution.x, _outputResolution.y, 0);
|
||||
|
||||
// Create a material for the shader (only on Card and Gradient)
|
||||
if (_sourceType == SourceType.Card || _sourceType == SourceType.Gradient)
|
||||
_material = new Material(_shader);
|
||||
@@ -186,9 +219,9 @@ public class FixedImageSource : MonoBehaviour
|
||||
|
||||
if (_sourceType == SourceType.Webcam && _webcam.didUpdateThisFrame)
|
||||
{
|
||||
Texture texture = FlipTextureAsync(_webcam);
|
||||
Blit(texture, _webcam.videoVerticallyMirrored);
|
||||
//Blit(_webcam, _webcam.videoVerticallyMirrored);
|
||||
//Texture texture = AdjustWebCamTextureWidth(_webcam, 800);
|
||||
//Blit(texture, _webcam.videoVerticallyMirrored);
|
||||
Blit(_webcam, _webcam.videoVerticallyMirrored);
|
||||
}
|
||||
|
||||
// Asynchronous image downloading
|
||||
|
||||
@@ -17,11 +17,10 @@ public class MirrorAnimationHandler : MonoBehaviour
|
||||
|
||||
public void Init()
|
||||
{
|
||||
_material.DOColor(_baseColor, .2f);
|
||||
_visualizer.OnDetectionStatusChanged += isDetected =>
|
||||
{
|
||||
if(isDetected) _material.DOColor(Color.white, .5f);
|
||||
else _material.DOColor(_baseColor, .5f);
|
||||
if(isDetected) _material.DOFade(1, .5f);
|
||||
else _material.DOFade(0, .5f);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,23 @@ public class SettingsUI : MonoBehaviour
|
||||
[SerializeField] private TMP_Text _maxFaceHeight;
|
||||
[SerializeField] private Button _acceptButton;
|
||||
|
||||
[SerializeField] private Slider _maskSlider;
|
||||
[SerializeField] private RectTransform _mask;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_maskSlider.minValue = _mask.rect.width - (_mask.rect.width / 2);
|
||||
_maskSlider.maxValue = _mask.rect.width + (_mask.rect.width / 2);
|
||||
_maskSlider.value = _mask.rect.width;
|
||||
|
||||
_maskSlider.onValueChanged.AddListener(value =>
|
||||
{
|
||||
_mask.sizeDelta = new Vector2(value, _mask.rect.height);
|
||||
});
|
||||
|
||||
if(_initOnStart)
|
||||
{
|
||||
OnAcceptButtonClick(0.134f);
|
||||
OnAcceptButtonClick(0.11f);
|
||||
return;
|
||||
}
|
||||
_acceptButton.onClick.AddListener(() => OnAcceptButtonClick());
|
||||
|
||||
Reference in New Issue
Block a user