123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using DG.Tweening;
- using JTFold;
- using UnityEngine;
- using JTSystems;
- public class Paper : MonoBehaviour
- {
- [HideInInspector] public PossibleCombinationBuilder Builder;
- [HideInInspector] public RegexCombinationAnalyzer RegexAnalyzer;
- public delegate void OnPaperStateChanged();
- public OnPaperStateChanged onPaperStateChanged;
- public delegate void OnPaperEvolving();
- public OnPaperEvolving onPaperEvolving;
- public delegate void OnPaperShowEffect();
- public OnPaperShowEffect onPaperShowEffect;
- public delegate void PaperStartFold();
- public PaperStartFold paperStartFold;
- public delegate void PaperStartUnfold();
- public PaperStartUnfold paperStartUnfold;
- [Header(" Settings ")]
- [SerializeField] private bool _test;
- [SerializeField] private bool _decalPaper;
- public Transform foldingsParent;
- private readonly List<Folding> _foldedFolding = new List<Folding>();
- private Folding[] _folding;
- private bool _canFold = true;
- [SerializeField] private Texture2D paperTexture;
- [SerializeField] private PaperEffect effect;
- [Header(" Rendering ")]
- [SerializeField] private MeshRenderer paperBackRenderer;
- [SerializeField] private MeshRenderer paperFrontRenderer;
- Folding currentFolding;
- [Header(" Mesh Manipulation ")] MeshFilter backFilter;
- private MeshFilter _frontFilter;
- [SerializeField] private float verticesElevationStep;
- [SerializeField] private float foldingDuration;
- [Header(" Solution ")]
- public PossibleCombination[] possibleCombinations;
- public IEnumerable<Folding> Folding => foldingsParent.Cast<Transform>().Select(x => x.GetComponent<Folding>());
- private Action levelCompleteCallBack;
- public Action wrongPaperFolded;
- private void Awake()
- {
- backFilter = paperBackRenderer.GetComponent<MeshFilter>();
- _frontFilter = paperFrontRenderer.GetComponent<MeshFilter>();
- // Анимация появления
- float toPositionZ = transform.position.z;
- Vector3 startPosition = transform.position;
- startPosition.z = 10;
- transform.position = startPosition;
- transform.DOMoveZ(toPositionZ, 1f);
- }
- public void setPaperCallBack(Action levelCompleteCallBackTemp, Action wrongPaperFoldedTemp)
- {
- levelCompleteCallBack = levelCompleteCallBackTemp;
- wrongPaperFolded = wrongPaperFoldedTemp;
- }
- // Start is called before the first frame update
- void Start()
- {
- #if UNITY_EDITOR
- if(!FindObjectOfType<DecalMaster>())
- #endif
- paperFrontRenderer.material.mainTexture = paperTexture;
- _folding = GetFoldings();
- }
- public void TryFold(Folding tappedFolding)
- {
- if (!_canFold) return;
- _canFold = false;
- currentFolding = tappedFolding;
- if (!tappedFolding.IsFolded())
- {
- _foldedFolding.Add(currentFolding);
- Fold();
- }
- else
- {
- // It is folded, unfold it
- StartCoroutine(UnfoldingProcedureCoroutine());
- }
- }
- private void Fold()
- {
- // We need to get the vertices that need to be folded first
- // These are the ones inside the folding's tapping zone
- StartCoroutine(FoldCoroutine(true));
- //StartCoroutine("FoldingCoroutine");
- currentFolding.SetFoldedState(true);
- Taptic.Light();
- onPaperEvolving?.Invoke();
- }
- private int[] GetVerticesToMove(MeshFilter filter, Folding folding)
- {
- List<int> verticesInsideTappingZone = new List<int>();
- Vector3[] vertices = filter.mesh.vertices;
- Plane foldingPlane = folding.GetFoldingPlane();
- for (int i = 0; i < vertices.Length; i++)
- {
- Vector3 vertexWorldPos = filter.transform.TransformPoint(vertices[i]);
- if (foldingPlane.GetSide(vertexWorldPos))
- verticesInsideTappingZone.Add(i);
- }
- return verticesInsideTappingZone.ToArray();
- }
- private bool IsInsideTappingZone(Vector3 vertexLocalPos, BoxCollider tappingZone)
- {
- Vector3 vertexWorldPos = paperBackRenderer.transform.position + vertexLocalPos;
- return tappingZone.bounds.Contains(vertexWorldPos);
- }
- private Vector3 GetRotatedPoint(Vector3 point, float angle, RotationAxis rotationAxis)
- {
- Vector3 pivot = rotationAxis.position;
- Quaternion q = Quaternion.AngleAxis(angle, rotationAxis.AsVector());
- return q * (point - pivot) + pivot;
- }
- private void Unfold()
- {
- StartCoroutine(FoldCoroutine(false));
- currentFolding.SetFoldedState(false);
- currentFolding.ClearFoldedVertices();
- }
- public void StartUnfolding()
- {
- if (!_canFold) return;
- _canFold = false;
- StartCoroutine(UnfoldingProcedureCoroutine());
- }
- IEnumerator UnfoldingProcedureCoroutine()
- {
- // 1. Check if there is any folding before this one
- for (int i = _foldedFolding.Count - 1; i >= 0; i--)
- {
- Folding folding = _foldedFolding[i];
- if (folding == currentFolding)
- {
- //Unfold();
- Taptic.Light();
- onPaperEvolving?.Invoke();
- yield return StartCoroutine(FoldCoroutine(false));
- currentFolding.SetFoldedState(false);
- currentFolding.ClearFoldedVertices();
- _foldedFolding.Remove(currentFolding);
- break;
- }
- else
- {
- currentFolding = folding;
- Taptic.Light();
- onPaperEvolving?.Invoke();
- yield return StartCoroutine(FoldCoroutine(false));
- currentFolding.SetFoldedState(false);
- currentFolding.ClearFoldedVertices();
- _foldedFolding.Remove(currentFolding);
- }
- }
- _canFold = true;
- onPaperStateChanged?.Invoke();
- yield return null;
- }
- IEnumerator FoldCoroutine(bool folding)
- {
- if (folding)
- paperStartFold?.Invoke();
- else
- paperStartUnfold?.Invoke();
- int[] backVerticesToMove = folding
- ? GetVerticesToMove(backFilter, currentFolding)
- : currentFolding.GetBackFoldedVerticesIndices();
- int[] frontVerticesToMove = folding
- ? GetVerticesToMove(_frontFilter, currentFolding)
- : currentFolding.GetFrontFoldedVerticesIndices();
- if (folding)
- {
- currentFolding.SetBackFoldedVerticesIndices(backVerticesToMove);
- currentFolding.SetFrontFoldedVerticesIndices(frontVerticesToMove);
- }
- Vector3[] initialBackVertices = backFilter.mesh.vertices;
- Vector3[] backVertices = backFilter.mesh.vertices;
- Vector3[] initialFrontVertices = _frontFilter.mesh.vertices;
- Vector3[] frontVertices = _frontFilter.mesh.vertices;
- if (folding)
- {
- for (int i = 0; i < frontVerticesToMove.Length; i++)
- initialFrontVertices[frontVerticesToMove[i]].y -= verticesElevationStep * (1 + _foldedFolding.Count);
- }
- float angleMultiplier = folding ? 1 : -1;
- float targetAngle = currentFolding.GetRotationAngle() * angleMultiplier;
- float timer = 0;
- while (timer <= foldingDuration + Time.deltaTime)
- {
- float angle = Mathf.Clamp01((timer / foldingDuration)) * targetAngle;
- for (int i = 0; i < backVerticesToMove.Length; i++)
- backVertices[backVerticesToMove[i]] =
- GetRotatedLocalVertex(initialBackVertices[backVerticesToMove[i]], angle);
- for (int i = 0; i < frontVerticesToMove.Length; i++)
- frontVertices[frontVerticesToMove[i]] =
- GetRotatedLocalVertex(initialFrontVertices[frontVerticesToMove[i]], angle);
- if (!folding)
- {
- for (int i = 0; i < frontVerticesToMove.Length; i++)
- frontVertices[frontVerticesToMove[i]].y += verticesElevationStep * (1 + _foldedFolding.Count);
- }
- backFilter.mesh.vertices = backVertices;
- _frontFilter.mesh.vertices = frontVertices;
- timer += Time.deltaTime;
- yield return null;
- }
- for (int i = 0; i < backVerticesToMove.Length; i++)
- backVertices[backVerticesToMove[i]] =
- GetRotatedLocalVertex(initialBackVertices[backVerticesToMove[i]], targetAngle);
- for (int i = 0; i < frontVerticesToMove.Length; i++)
- frontVertices[frontVerticesToMove[i]] =
- GetRotatedLocalVertex(initialFrontVertices[frontVerticesToMove[i]], targetAngle);
- if (!folding)
- {
- for (int i = 0; i < frontVerticesToMove.Length; i++)
- frontVertices[frontVerticesToMove[i]].y += verticesElevationStep * (1 + _foldedFolding.Count);
- }
- backFilter.mesh.vertices = backVertices;
- _frontFilter.mesh.vertices = frontVertices;
- _frontFilter.GetComponent<MeshCollider>().sharedMesh = _frontFilter.mesh;
- if (folding)
- _canFold = true;
- if (AvailableFoldingsEnded() && folding)
- {
- yield return new WaitForSeconds(0.1f);
- CheckForLevelComplete();
- }
- onPaperStateChanged?.Invoke();
-
- }
- private void CheckForLevelComplete()
- {
- if (Builder != null && Builder.Used && Builder.IsCorrect(_foldedFolding))
- {
- StartCoroutine(SetLevelComplete());
- return;
- }
- if (RegexAnalyzer != null && RegexAnalyzer.IsCorrect(_foldedFolding))
- {
- StartCoroutine(SetLevelComplete());
- return;
- }
- for (int i = 0; i < possibleCombinations.Length; i++)
- {
- if (MatchPossibleCombination(possibleCombinations[i]))
- {
- StartCoroutine(SetLevelComplete());
- return;
- }
- }
- StartCoroutine(SetWrongFoldPaper());
- }
-
- private bool MatchPossibleCombination(PossibleCombination foldingsCombination)
- {
- if (_foldedFolding.Count != foldingsCombination.GetFoldings().Length)
- return false;
- for (int i = 0; i < _foldedFolding.Count; i++)
- if (_foldedFolding[i] != foldingsCombination.GetFoldings()[i])
- return false;
- return true;
- }
- private IEnumerator SetLevelComplete()
- {
- Debug.Log("Level Complete");
- if (_decalPaper || _test)
- yield break;
- _canFold = false;
-
- LeanTween.moveZ(gameObject, -20f, 0.7f).setEaseInBack().setOnComplete(() => { });
- if (effect.StickerEffect != null)
- {
- StickerEffect stickerEffect = Instantiate(effect.StickerEffect);
- stickerEffect.CachedTransform.position = transform.position;
- stickerEffect.CachedSpriteRenderer.flipX = effect.FlipX;
- stickerEffect.CachedSpriteRenderer.flipY = effect.FlipY;
- onPaperShowEffect?.Invoke();
- yield return stickerEffect.ShowEffect(effect.SpriteImage, effect.SpriteSize, effect.SpriteRotate);
- yield return new WaitForSeconds(0.5f);
- Destroy(stickerEffect.gameObject);
- }
- UIManager.setLevelCompleteDelegate?.Invoke();
- levelCompleteCallBack?.Invoke();
- yield break;
- }
- private IEnumerator SetWrongFoldPaper()
- {
- bool animationComplete = false;
- Debug.Log("Wrong!");
- LeanTween.moveLocalX(gameObject, transform.position.x + 0.1f, 0.1f).setEaseShake().setOnComplete(() =>
- {
- LeanTween.moveLocalX(gameObject, transform.position.x - 0.1f, 0.1f).setEaseShake()
- .setOnComplete(() => { animationComplete = true; });
- });
- yield return new WaitUntil(() => animationComplete);
- animationComplete = false;
- if (_decalPaper || _test)
- yield break;
- UnfoldAllFoldings();
- UIManager.wrongPaperFolded?.Invoke();
- wrongPaperFolded?.Invoke();
- yield break;
- }
- private Vector3 GetRotatedLocalVertex(Vector3 localVertexToMove, float angle)
- {
- Vector3 vertexWorldPos = paperBackRenderer.transform.TransformPoint(localVertexToMove);
- Vector3 rotatedWorldVertex = GetRotatedPoint(vertexWorldPos, angle, currentFolding.GetRotationAxis());
- Vector3 rotatedLocalVertex = paperBackRenderer.transform.InverseTransformPoint(rotatedWorldVertex);
- return rotatedLocalVertex;
- }
- public Folding[] GetFoldings(bool includeInactive = true)
- {
- return foldingsParent.GetComponentsInChildren<Folding>(includeInactive);
- }
- public MeshRenderer GetFrontRenderer()
- {
- return paperFrontRenderer;
- }
- public bool AvailableFoldingsEnded()
- {
- return _foldedFolding.Count >= _folding.Length;
- }
- public void UnfoldAllFoldings()
- {
- if (_foldedFolding.Count <= 0 || !_canFold)
- return;
- currentFolding = _foldedFolding[0];
- _canFold = false;
- StartCoroutine(UnfoldingProcedureCoroutine());
- }
- private void OnDisable()
- {
- levelCompleteCallBack = null;
- }
- }
- [System.Serializable]
- public struct PossibleCombination
- {
- [SerializeField] private Folding[] foldings;
- public Folding[] GetFoldings()
- {
- return foldings;
- }
- }
- [System.Serializable]
- public struct PaperEffect
- {
- [SerializeField] private StickerEffect _stickerEffect;
- [SerializeField] private Sprite _spriteImage;
- [SerializeField] private Vector3 _spriteSize;
- [SerializeField] private Quaternion _spriteRotate;
- [SerializeField] private bool _flipX;
- [SerializeField] private bool _flipY;
- public StickerEffect StickerEffect => _stickerEffect;
- public Sprite SpriteImage => _spriteImage;
- public Vector3 SpriteSize => _spriteSize;
- public Quaternion SpriteRotate => _spriteRotate;
- public bool FlipX => _flipX;
- public bool FlipY => _flipY;
- }
|