// -------------------------------------------------------------------------------------------- private void UpdateReticleAlpha() { float alpha = _defaultColor.a; if (_actor.Input.space) { alpha = 1f; } if (!alpha.IsApproximately(_targetAlpha)) { _targetAlpha = alpha; float startAlpha = _spriteRenderer.color.a; _reticleAlphaAnimation?.Stop(); _reticleAlphaAnimation = new TofuAnimation() .Value01(_alphaAnimTime, EEaseType.Linear, (float newValue) => { _currentColor.a = Mathf.LerpUnclamped(startAlpha, _targetAlpha, newValue); }) .Then() .Execute(() => { _reticleAlphaAnimation = null; }) .Play(); } }
// -------------------------------------------------------------------------------------------- public void UnHighlight() { _pointerEnterAnim?.Stop(); _pointerExitAnim?.Stop(); // reset pointer down anim _pointerDownAnim?.Stop(); _captionLabel.Transform.localScale = Vector3.one; Vector2 startSize = new Vector2(_background.RectTransform.sizeDelta.x, 0f); Vector2 endSize = Size; float startLerp = Mathf.InverseLerp(startSize.y, endSize.y, _background.RectTransform.sizeDelta.y); _pointerExitAnim = new TofuAnimation() .ValueFromTo(startLerp, 0f, 1f - Mathf.Lerp(0f, HoverAnimTime, startLerp), EEaseType.EaseOutExpo, (float newValue) => { _background.RectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, Mathf.LerpUnclamped(startSize.y, endSize.y, newValue)); _background.Color = Color.Lerp(DefaultBackgroundColor, HighlightedBackgroundColor, newValue); _captionLabel.Color = Color.Lerp(DefaultColor, HighlightedColor, newValue); }) .Then() .Execute(() => { _pointerExitAnim = null; }) .Play(); }
// -------------------------------------------------------------------------------------------- private void SetVisible(bool visible) { _visible = visible; _fadeAnimation?.Stop(); float startAlpha = _canvasGroup.alpha; float endAlpha = visible ? 1f : 0f; float time = visible ? _fadeAnimTime * (1f - startAlpha) : _fadeAnimTime * startAlpha; _fadeAnimation = new TofuAnimation() .Value01(time, EEaseType.Linear, (float newValue) => { if (this) { // check that we haven't been destroyed _canvasGroup.alpha = Mathf.Lerp(startAlpha, endAlpha, newValue); } }) .Then() .Wait(_visible ? _lingerTime : 0f) .Then() .Execute(() => { _fadeAnimation = null; }) .Play(); }
public static void GenerateOnThread(IntVector2 coord, Action <RegionState> onComplete) { object lockObj = new object(); RegionState regionState = null; Thread genThread = new Thread(new ThreadStart(() => { RegionState rs = Generate(coord); lock (lockObj) { regionState = rs; } })); TofuAnimation waitForGeneration = new TofuAnimation() .Execute(() => { genThread.Start(); }) .WaitUntil(() => { lock (lockObj) { return(regionState != null); } }) .Then() .Execute(() => { onComplete(regionState); }) .Play(); }
private void Unit_OnTookDamage(object sender, Unit.DamageEventArgs e) { if (e.wasKilled) { _unit.OnTookDamage -= Unit_OnTookDamage; } if (!IsShowing) { Show(); } _healthbarAnim?.Stop(); float startFill = e.previousHealth / (float)e.targetUnit.MaxHealth; float endFill = e.newHealth / (float)e.targetUnit.MaxHealth; _healthbarAnim = new TofuAnimation() .Value01(HealthBarAnimTime, EEaseType.Linear, (float newValue) => { _healthBar.Percent = Mathf.LerpUnclamped(startFill, endFill, newValue); }) .Then() .Wait(2f) .Then() .Execute(() => { Hide(); }) .Play(); }
private void Animate() { _anim?.Stop(); Vector2 startLabelPos = new Vector2(_bannerBackground.Width, 0f); Vector2 holdLabelPos = new Vector2(0f, 0f); Vector2 endLabelPos = new Vector2(-_bannerBackground.Width, 0f); _anim = new TofuAnimation() .Value01(AnimateInTime, EEaseType.Linear, (float newValue) => { _bannerBackground.Color = Color.Lerp(BackgroundStartColor, BackgroundEndColor, newValue); }) .Value01(AnimateInTime, EEaseType.EaseInOutCirc, (float newValue) => { _bannerLabel.LocalPosition = Vector3.LerpUnclamped(startLabelPos, holdLabelPos, newValue); }) .Then() .Wait(AnimateHoldTime) .Then() .Value01(AnimateInTime, EEaseType.Linear, (float newValue) => { _bannerBackground.Color = Color.Lerp(BackgroundEndColor, BackgroundStartColor, newValue); }) .Value01(AnimateOutTime, EEaseType.EaseInOutCirc, (float newValue) => { _bannerLabel.LocalPosition = Vector3.LerpUnclamped(holdLabelPos, endLabelPos, newValue); }) .Then() .Execute(() => { Hide(); }) .Play(); }
// -------------------------------------------------------------------------------------------- public void AnimateSelected(Action onComplete) { UnHighlight(); UnsubscribeToEvent(EEventType.PointerEnter, OnPointerEnter); UnsubscribeToEvent(EEventType.PointerExit, OnPointerExit); UnsubscribeToEvent(EEventType.PointerDown, OnPointerDown); UnsubscribeToEvent(EEventType.PointerUp, OnPointerUp); UnsubscribeToEvent(EEventType.PointerClick, OnClicked); Vector2 startPosition = RectTransform.anchoredPosition; Vector2 endPosition = startPosition + Vector2.up * AnimateSelectedTime; Color startColor = _captionLabel.Color; Color endColor = Color.white; Vector3 startScale = Vector3.one; Vector3 endScale = Vector3.one * AnimateSelectedScale; _animateSelectedAnim = new TofuAnimation() .Value01(AnimateAwayTime, EEaseType.EaseOutExpo, (float newValue) => { RectTransform.anchoredPosition = Vector2.LerpUnclamped(startPosition, endPosition, newValue); _captionLabel.Color = Color.Lerp(startColor, endColor, newValue); RectTransform.localScale = Vector3.Lerp(startScale, endScale, newValue); }) .Then() .Execute(() => { onComplete?.Invoke(); }) .Play(); }
public void SetTile(Tile tile, bool teleport) { _moveAnim?.Stop(); Vector3 targetPos = tile.LocalPosition; if (teleport) { _moveAnim = null; LocalPosition = targetPos; } else { Vector3 startPos = LocalPosition; float animTime = Mathf.Abs(_state.moveSpeed) > 0f ? _state.moveSpeed : float.MaxValue; _moveAnim = new TofuAnimation() .Value01(animTime, EEaseType.Linear, (float newValue) => { LocalPosition = Vector3.LerpUnclamped(startPos, targetPos, newValue); }) .Then() .Execute(() => { _moveAnim = null; }) .Play(); } }
// -------------------------------------------------------------------------------------------- private void UpdateReticleMove() { if (_previousInteractOffset.IsApproximately(_actor.InteractOffset, 0.01f)) { return; } _previousInteractOffset = _actor.InteractOffset; float fromAngle = Mathf.Atan2(_spriteRenderer.transform.localPosition.x, -_spriteRenderer.transform.localPosition.y) - Mathf.PI / 2f; float toAngle = Mathf.Atan2(_actor.InteractOffset.x, -_actor.InteractOffset.y) - Mathf.PI / 2f; if (toAngle - fromAngle > Mathf.PI) { toAngle -= Mathf.PI * 2f; } if (fromAngle - toAngle > Mathf.PI) { fromAngle -= Mathf.PI * 2f; } _reticleMoveAnimation?.Stop(); _reticleMoveAnimation = new TofuAnimation() .Value01(_moveAnimTime, EEaseType.Linear, (float newValue) => { float angle = Mathf.LerpUnclamped(fromAngle, toAngle, newValue); _spriteRenderer.transform.localPosition = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0f); }) .Then() .Execute(() => { _reticleMoveAnimation = null; }) .Play(); }
public void SetCenterRegion(IntVector2 coord, Action onComplete) { TofuAnimation currentLoadAnim = null; int numRegionsLoaded = 0; for (int x = -SimulateRegionDistance; x <= SimulateRegionDistance; x++) { for (int y = -SimulateRegionDistance; y <= SimulateRegionDistance; y++) { IntVector2 regionCoord = coord + new IntVector2(x, y); new TofuAnimation() .WaitUntil(() => { // by waiting for the current loadAnim to be null, we ensure that we only generate/load one region at a time (since it will be threaded) return(currentLoadAnim == null); }) .Then() .Execute(() => { RegionState regionState = null; currentLoadAnim = new TofuAnimation() .Execute(() => { LoadRegionState(regionCoord, (RegionState payload) => { regionState = payload; }); }) .WaitUntil(() => { return(regionState != null); }) .Then() .Execute(() => { _state.AddRegionState(regionCoord, regionState); numRegionsLoaded++; currentLoadAnim = null; }) .Play(); }) .Play(); } } new TofuAnimation() .WaitUntil(() => { return(numRegionsLoaded == ((SimulateRegionDistance * 2) + 1) * ((SimulateRegionDistance * 2 + 1))); }) .Then() .Execute(() => { onComplete(); }) .Play(); }
// -------------------------------------------------------------------------------------------- public void StopOnTile() { if (_moveAnim != null) { _moveAnim.Stop(); _onMoveComplete?.Invoke(); _moveAnim = null; } OccupyBoardTile(BoardTile, true); LocalPosition = Vector3.zero; }
// -------------------------------------------------------------------------------------------- protected override void Update() { if (MoveMode == EMoveMode.Tactical) { if (!_playerHasTakenTacticalTurn) { TryChooseNextTargetPosition(); } TryMoveInteractOffset(); if (!_playerHasTakenTacticalTurn) { TryInteract(); } if (_playerHasTakenTacticalTurn && _tacticalTurnCooldownAnimation == null) { _tacticalTurnCooldownAnimation = new TofuAnimation() .Wait(TakeTurnCooldown) .WaitUntil(() => { // wait for the player's attack to complete before telling all the other actors to take their turn return(!(EquipedWeapon && EquipedWeapon.IsAttacking)); }) .Then() .Execute(() => { _takeTacticalTurn?.Invoke(); _playerHasTakenTacticalTurn = false; _tacticalTurnCooldownAnimation = null; }) .Play(); } } base.Update(); if (UnityEngine.Input.GetKeyDown(KeyCode.Tab)) { if (MoveMode == EMoveMode.FreeMove) { SetMoveMode(EMoveMode.Tactical); } else if (MoveMode == EMoveMode.Tactical) { SetMoveMode(EMoveMode.FreeMove); } } }
// -------------------------------------------------------------------------------------------- private void UICard_OnDrag(UICard uiCard, PointerEventData pointerEventData) { if (uiCard != _draggingCard) { return; } if (_cardCorrectRotAnim == null) { Quaternion startRot = uiCard.LocalRotation; _cardCorrectRotAnim = new TofuAnimation() .Value01(CardCorrectRotAnimTime, EEaseType.Linear, (float newValue) => { uiCard.LocalRotation = Quaternion.SlerpUnclamped(startRot, Quaternion.Euler(0f, 0f, 0f), newValue); }) .Play(); } //if(_game.board.RaycastToPlane(_game.gameCamera.ScreenPointToRay(pointerEventData.position), out Vector3 worldPos)) //{ // BoardTile draggingOverTile = _game.board.GetBoardTileAtPosition(worldPos); // if(draggingOverTile != null) // { // List<BoardTile> playableTiles = Card.GetPlayableTiles(_game, _player, _draggingCard.CardData); // bool isTilePlayable = false; // foreach(BoardTile boardTile in playableTiles) // { // isTilePlayable |= boardTile == draggingOverTile; // } // if(isTilePlayable) // { // AnimateCardToSide(); // } // else // { // CenterCardOnPointer(); // } // } // else // { // CenterCardOnPointer(); // } //} //else //{ // CenterCardOnPointer(); //} _draggingCard.RectTransform.anchoredPosition = _dragStartAnchorPos + UIMainCanvas.Instance.PointerPositionToAnchoredPosition(pointerEventData.position - _dragStartPointerPos) + _draggingCardAnchorPosOffset; }
// -------------------------------------------------------------------------------------------- private void OnOwnerInteracted(Interactable.InteractedEventInfo info) { if (_attackSequence != null) { return; } if (!owner.EquipedWeapon == this) { return; } Destructible destructible = info.interactedWith.GetComponent <Destructible>(); if (!destructible) { return; } CurrentlyAttacking = destructible; _attackSequence = new TofuAnimation() .Execute(() => { PreAttackAnimation().Play(); }) .Wait(_preAttackDelay) .Then() .Execute(() => { DoAttack(); }) .Then() .Execute(() => { PostAttackAnimation().Play(); }) .Wait(_postAttackCooldown) .Then() .Execute(() => { _attackSequence = null; CurrentlyAttacking = null; }) .Play(); }
// -------------------------------------------------------------------------------------------- public void Press() { _pointerDownAnim?.Stop(); Vector3 startScale = Vector3.one; Vector3 endScale = Vector3.one * PressedScale; _pointerDownAnim = new TofuAnimation() .Value01(PressAnimTime, EEaseType.EaseOutExpo, (float newValue) => { _captionLabel.Transform.localScale = Vector3.LerpUnclamped(startScale, endScale, newValue); }) .Then() .Execute(() => { _pointerDownAnim = null; }) .Play(); }
// -------------------------------------------------------------------------------------------- public void SetHealth(int currentHealth, int maxHealth) { _healthBarAnim?.Stop(); float startPercent = _heroHealthBar.Percent; float endPercent = (float)currentHealth / (float)maxHealth; _healthBarAnim = new TofuAnimation() .Value01(HealthBarAnimTime, EEaseType.Linear, (float newValue) => { _heroHealthBar.Percent = Mathf.Lerp(startPercent, endPercent, newValue); }) .Then() .Execute(() => { _healthBarAnim = null; }) .Play(); }
//private void AnimateCardToSide() //{ // _cardOffsetAnimation?.Stop(); // _cardOffsetAnimation = null; // // Vector2 startOffset = _draggingCardAnchorPosOffset; // Vector2 endOffset = CardOverPlayableTileOffset; // // _cardOffsetAnimation = new TofuAnimation() // .Value01(CardOverPlayableTileAnimTime, EEaseType.EaseOutExpo, (float newValue) => // { // _draggingCardAnchorPosOffset = Vector2.LerpUnclamped(startOffset, endOffset, newValue); // }) // .Then() // .Execute(() => // { // _cardOffsetAnimation = null; // }) // .Play(); //} // //// -------------------------------------------------------------------------------------------- //private void CenterCardOnPointer() //{ // _cardOffsetAnimation?.Stop(); // _cardOffsetAnimation = null; // // Vector2 startOffset = _draggingCardAnchorPosOffset; // // _cardOffsetAnimation = new TofuAnimation() // .Value01(CardOverPlayableTileAnimTime, EEaseType.EaseOutExpo, (float newValue) => // { // _draggingCardAnchorPosOffset = Vector2.LerpUnclamped(startOffset, Vector2.zero, newValue); // }) // .Then() // .Execute(() => // { // _cardOffsetAnimation = null; // }) // .Play(); //} // -------------------------------------------------------------------------------------------- private void UICard_OnPointerUp(UICard uiCard, PointerEventData pointerEventData) { if (uiCard != _draggingCard) { return; } _listener.OnPlayerReleasedCard(_uiCardToCard[uiCard], pointerEventData); _cardCorrectRotAnim?.Stop(); _cardCorrectRotAnim = null; _cardOffsetAnimation?.Stop(); _cardOffsetAnimation = null; _draggingCard = null; _draggingCardAnchorPosOffset = Vector2.zero; PositionCards(true); }
// -------------------------------------------------------------------------------------------- private void SetMoveMode(EMoveMode moveMode) { if (moveMode == MoveMode) { return; } EMoveMode previousMode = MoveMode; MoveMode = moveMode; _playerHasTakenTacticalTurn = false; _tacticalTurnCooldownAnimation?.Stop(); _tacticalTurnCooldownAnimation = null; _moveModeChanged?.Invoke(new MoveModeChangedInfo { previousMode = previousMode, currentMode = MoveMode, }); }
// -------------------------------------------------------------------------------------------- private void PositionCards(bool animate) { _cardFanAnim?.Stop(); float[] cardAngles = GetCardFanAngles(); Vector3[] cardOffsets = GetCardFanOffsets(); _cardLayout.UpdateChildren(); int index = 0; foreach (Card card in _cardToUICard.Keys) { UICard uiCard = _cardToUICard[card]; Quaternion startRotation = uiCard.LocalRotation; Quaternion endRotation = Quaternion.Euler(uiCard.LocalRotation.x, uiCard.LocalRotation.y, uiCard.LocalRotation.z - cardAngles[index]); Vector3 startPosition = uiCard.LocalPosition; Vector3 endPosition = cardOffsets[index]; index++; if (animate) { _cardFanAnim = new TofuAnimation() .Value01(CardFanAnimTime, EEaseType.EaseOutExpo, (float newValue) => { uiCard.LocalRotation = Quaternion.Slerp(startRotation, endRotation, newValue); uiCard.LocalPosition = Vector3.LerpUnclamped(startPosition, endPosition, newValue); }) .Play(); } else { uiCard.LocalRotation = endRotation; uiCard.LocalPosition = endPosition; } } }
// -------------------------------------------------------------------------------------------- public void SetFacing(EFacing facing, bool animate) { _facing = facing; _facingAnim?.Stop(); Quaternion rot = FacingToRotation(facing); if (animate) { Quaternion startRot = LocalRotation; _facingAnim = new TofuAnimation() .Value01(0.5f, EEaseType.EaseOutExpo, (float newValue) => { LocalRotation = Quaternion.SlerpUnclamped(startRot, rot, newValue); }) .Play(); } else { LocalRotation = rot; } }
// -------------------------------------------------------------------------------------------- private void UpdateReticleColor() { Color changeTo = _defaultColor; Destructible facingDestructible = null; Collider2D[] facingColliders = Physics2D.OverlapCircleAll(_actor.transform.position + _actor.InteractOffset, 0.4f); foreach (Collider2D collider in facingColliders) { if (!facingDestructible && collider.gameObject != _actor.gameObject) { facingDestructible = collider.gameObject.GetComponent <Destructible>(); } } if (facingDestructible && _actor.EquipedWeapon && _actor.EquipedWeapon.CanAttackDestructible(facingDestructible)) { changeTo = _attackColor; } if (!((Vector4)changeTo).IsApproximately(_targetColor)) { Color startColor = _spriteRenderer.color; _targetColor = changeTo; _reticleColorAnimation?.Stop(); _reticleColorAnimation = new TofuAnimation() .Value01(_colorAnimTime, EEaseType.EaseOutExpo, (float newValue) => { _currentColor = Color.LerpUnclamped(startColor, _targetColor, newValue); }) .Then() .Execute(() => { _reticleColorAnimation = null; }) .Play(); } }
private void SetMoveModeText(PlayerActor.EMoveMode moveMode, bool flashCamera) { switch (moveMode) { case PlayerActor.EMoveMode.FreeMove: _moveModeLabel.text = "Free Move"; break; case PlayerActor.EMoveMode.Tactical: _moveModeLabel.text = "Tactical"; break; case PlayerActor.EMoveMode.Paused: _moveModeLabel.text = "Paused"; break; } if (flashCamera) { _cameraBGColorAnim?.Stop(); _cameraBGColorAnim = new TofuAnimation() .Value01(_cameraFlashTime / 2f, EEaseType.EaseOutExpo, (float newValue) => { Camera.main.backgroundColor = Color.LerpUnclamped(Color.black, _cameraFlashColor, newValue); }) .Then() .Value01(_cameraFlashTime / 2f, EEaseType.EaseOutExpo, (float newValue) => { Camera.main.backgroundColor = Color.LerpUnclamped(_cameraFlashColor, Color.black, newValue); }) .Then() .Execute(() => { _cameraBGColorAnim = null; }) .Play(); } }
// -------------------------------------------------------------------------------------------- private void OnDamaged(Destructible.DamageEventInfo info) { if (!_visible) { SetVisible(true); } float startAmount = _slider.value; float endAmount = info.currentHealth / Destructible.MaxHealth; _sliderAnimation?.Stop(); _sliderAnimation = new TofuAnimation() .Value01(_sliderAnimTime, EEaseType.Linear, (float newValue) => { _slider.value = Mathf.LerpUnclamped(startAmount, endAmount, newValue); }) .WaitUntil(() => { return(_fadeAnimation == null); }) .Then() .Execute(() => { if (PlayerActor.MoveMode == PlayerActor.EMoveMode.FreeMove) { if (this) // check if we've been destroyed first { SetVisible(false); } } }) .Then() .Execute(() => { _sliderAnimation = null; }) .Play(); }
// -------------------------------------------------------------------------------------------- public void AnimateAway(float delay) { UnsubscribeToEvent(EEventType.PointerEnter, OnPointerEnter); UnsubscribeToEvent(EEventType.PointerExit, OnPointerExit); UnsubscribeToEvent(EEventType.PointerDown, OnPointerDown); UnsubscribeToEvent(EEventType.PointerUp, OnPointerUp); UnsubscribeToEvent(EEventType.PointerClick, OnClicked); Vector2 startPosition = RectTransform.anchoredPosition; Vector2 endPosition = startPosition + Vector2.up * AnimateAwayDistance; Color startColor = _captionLabel.Color; Color endColor = new Color(startColor.r, startColor.g, startColor.b, 0f); _animateAwayAnim = new TofuAnimation() .Wait(delay) .Then() .Value01(AnimateAwayTime, EEaseType.EaseOutExpo, (float newValue) => { RectTransform.anchoredPosition = Vector2.LerpUnclamped(startPosition, endPosition, newValue); _captionLabel.Color = Color.Lerp(startColor, endColor, newValue); }) .Play(); }
// -------------------------------------------------------------------------------------------- public void Move(IntVector2[] path, bool animate, Action onComplete) { if (!CanMove) { Debug.LogError($"Unit {id} cannot move"); return; } _onMoveComplete = () => { onComplete?.Invoke(); _onMoveComplete = null; }; HasMoved = true; if (animate) { if (_moveAnim != null) { Debug.LogError("move anim in progress!"); return; } _moveAnim = new TofuAnimation(); Parent.RemoveChild(this, false); for (int i = 1; i < path.Length; i++) { Vector3 fromPos = _game.board.GetTile(path[i - 1]).Transform.position; Vector3 toPos = _game.board.GetTile(path[i]).Transform.position; float time = (toPos - fromPos).magnitude / _data.travelSpeed; if (i != 1) { // we don't need to call Then() on the first loop _moveAnim.Then(); } _moveAnim.Execute(() => { SetFacing(VectorToFacing(toPos - fromPos), false); }) .Value01(time, EEaseType.Linear, (float newValue) => { Transform.position = Vector3.LerpUnclamped(fromPos, toPos, newValue); Ray ray = new Ray(Transform.position + Vector3.up, Vector3.down); RaycastHit[] hits = Physics.RaycastAll(ray, 2f); for (int j = 0; j < hits.Length; j++) { BoardTileView boardTileView = hits[j].collider.GetComponentInParent <BoardTileView>(); if (boardTileView == null) { continue; } if (boardTileView.BoardTile != BoardTile) { OccupyBoardTile(boardTileView.BoardTile, false); } break; } }); } _moveAnim.Then() .Execute(() => { StopOnTile(); }) .Play(); } else { for (int i = 0; i < path.Length; i++) { BoardTile boardTile = _game.board.GetTile(path[i]); StopOnTile(); } _onMoveComplete?.Invoke(); } }