public void ShowPath(IList <Vector2Int> pathPoints, float score) { if (!pathPoints.Any()) { return; } var line = new GameObject("PathFragment"); var lineRenderer = line.AddComponent <LineRenderer>(); SetupLineRenderer(pathPoints, lineRenderer); int middlePathPointIndex = pathPoints.Count / 2; Vector2Int labelPositionInGrid = pathPoints[middlePathPointIndex]; Vector3 labelPosition = _gridInfoProvider.GetCellCenterWorld(labelPositionInGrid); line.transform.position = labelPosition; var label = line.AddComponent <Label>(); label.Text = score.ToString(); foreach (var vector2Int in pathPoints) { var node = new GameObject("PathNode"); SpriteRenderer nodeSprite = node.AddComponent <SpriteRenderer>(); nodeSprite.sortingLayerName = "HUD"; nodeSprite.transform.position = _gridInfoProvider.GetCellCenterWorld(vector2Int); nodeSprite.sprite = Resources.Load <Sprite>(@"Sprites\Characters\Misc_tiles\19"); Object.Destroy(node.gameObject, 10.0f); } Object.Destroy(line.gameObject, 8.0f); }
public void SwingTo(Vector2Int targetPosition, bool isAggressiveAttack) { if (!gameObject.activeInHierarchy) { gameObject.SetActive(true); } _initialPosition = transform.position; _isAggressiveAttack = isAggressiveAttack; _mySwingTarget = _gridInfoProvider.GetCellCenterWorld(targetPosition); _animator.enabled = false; Vector3 directionToTarget = _mySwingTarget - _initialPosition; _deviationCurveForX = _rng.Choice(_weaponAnimationData.DeviationCurves); _deviationCurveForY = _rng.Choice(_weaponAnimationData.DeviationCurves); _deviationCurveForRotation = _rng.Choice(_weaponAnimationData.DeviationCurvesForRotation); _deviationImportanceForX = _rng.NextFloat(); _deviationImportanceForY = _rng.NextFloat(); var angle = ZRotationForLookAt2DConsidering45OffsetOfWeapon(Math.Abs(directionToTarget.x), directionToTarget.y); _mySwingTargetRotation = Quaternion.AngleAxis(angle, Vector3.forward); }
private Collider2D[] GetCollidersInRange(Vector2Int targetPosition, float cellsRangeInVision, IEnumerable <string> layerNames) { Vector3 targetWorldPosition2D = _gridInfoProvider.GetCellCenterWorld(targetPosition); int layerMask = 0; foreach (string layerName in layerNames) { layerMask |= 1 << LayerMask.NameToLayer(layerName); } float raycastLength = cellsRangeInVision * _gridInfoProvider.CellSize; Collider2D[] hitColliders = Physics2D.OverlapCircleAll(targetWorldPosition2D, raycastLength, layerMask); return(hitColliders); }
// Update is called once per frame void Update() { NavigationData navigationData = _actorBehaviour.ActorData.NavigationData; if (navigationData.Destination.HasValue) { _destinationRenderer.enabled = true; _destinationRenderer.transform.position = _gridInfoProvider.GetCellCenterWorld(navigationData.Destination.Value); } else { _nextNodeRenderer.enabled = false; } if (navigationData.PathToFollow != null) { _pathToTargetRenderer.positionCount = navigationData.PathToFollow.Count; _pathToTargetRenderer.SetPositions(navigationData.PathToFollow.Select(position => _gridInfoProvider.GetCellCenterWorld(position)).ToArray()); } if (navigationData.NextNode.HasValue) { _nextNodeRenderer.enabled = true; _nextNodeRenderer.transform.position = _gridInfoProvider.GetCellCenterWorld(navigationData.NextNode.Value); } else { _nextNodeRenderer.enabled = false; } if (navigationData.StepsToNextNode != null) { _stepsToNextNodeRenderer.positionCount = navigationData.StepsToNextNode.Count; _stepsToNextNodeRenderer.SetPositions(navigationData.StepsToNextNode.Select(position => _gridInfoProvider.GetCellCenterWorld(position)).ToArray()); } }
public void ShowTextEffect(Vector2Int position, string text, Color?color = null, bool forceShowing = false) { if (!color.HasValue) { color = Color.white; } if (!forceShowing && !_gameContext.VisiblePositions.Contains(position)) { return; } var textEffectObject = new GameObject("TextEffect"); textEffectObject.transform.position = _gridInfoProvider.GetCellCenterWorld(position); var textEffect = textEffectObject.AddComponent <TextEffect>(); float duration = Mathf.Max(2.5f, 1f + (float)text.Length / 5); textEffect.Initialize(text, color.Value, duration); Object.Destroy(textEffectObject, duration); }
public void RefreshWorldPosition() { transform.position = _gridInfoProvider.GetCellCenterWorld(EntityData.LogicalPosition); }
void Update() { if (_animationState == EntityAnimationState.Inactive) { return; } if (_animationState == EntityAnimationState.Moving) { _timeSinceStartedAnimation += Time.smoothDeltaTime; // deltaTime could be unnaturally big // because of calculations done when player performs an action Vector3 previousWorldPosition = _gridInfoProvider.GetCellCenterWorld(_previousLogicalPosition); Vector3 animationTargetPosition = _gridInfoProvider.GetCellCenterWorld(_animationTargetPosition); Vector3 interpolatedPosition = Vector3.Lerp(previousWorldPosition, animationTargetPosition, _timeSinceStartedAnimation / DefaultAnimationDuration); transform.position = interpolatedPosition; bool finished = _timeSinceStartedAnimation > DefaultAnimationDuration; if (finished) { _animationState = EntityAnimationState.Inactive; _timeSinceStartedAnimation = 0f; } } else if (_animationState == EntityAnimationState.FallingIn) { _timeSinceStartedAnimation += Time.smoothDeltaTime; // deltaTime could be unnaturally big // because of calculations done when player performs an action Vector3 previousWorldPosition = _gridInfoProvider.GetCellCenterWorld(_previousLogicalPosition); Vector3 animationTargetPosition = _gridInfoProvider.GetCellCenterWorld(_animationTargetPosition); float progress = _timeSinceStartedAnimation / FallInAnimationDuration; Vector3 interpolatedPosition = Vector3.Lerp(previousWorldPosition, animationTargetPosition, progress); Vector3 interpolatedScale = Vector3.Lerp(new Vector3(1, 1, 1), new Vector3(0.5f, 0.5f, 0.5f), progress); Quaternion interpolatedRotation = Quaternion.Lerp(_animationStartRotation, Quaternion.Euler(0, 0, 180), progress); transform.position = interpolatedPosition; transform.localScale = interpolatedScale; transform.rotation = interpolatedRotation; bool finished = progress >= 1; if (finished) { transform.parent = _entityToBecomeParent.transform; _animationState = EntityAnimationState.Inactive; _timeSinceStartedAnimation = 0f; _entityToBecomeParent = null; } } else if (_animationState == EntityAnimationState.FallingOut) { _timeSinceStartedAnimation += Time.smoothDeltaTime; // deltaTime could be unnaturally big // because of calculations done when player performs an action Vector3 previousWorldPosition = _gridInfoProvider.GetCellCenterWorld(_previousLogicalPosition); Vector3 animationTargetPosition = _gridInfoProvider.GetCellCenterWorld(_animationTargetPosition); float progress = _timeSinceStartedAnimation / FallInAnimationDuration; Vector3 interpolatedPosition = Vector3.Lerp(previousWorldPosition, animationTargetPosition, progress); Vector3 interpolatedScale = Vector3.Lerp(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(1, 1, 1), progress); Quaternion interpolatedRotation = Quaternion.Lerp(_animationStartRotation, Quaternion.identity, progress); transform.position = interpolatedPosition; transform.localScale = interpolatedScale; transform.rotation = interpolatedRotation; bool finished = progress >= 1; if (finished) { _animationState = EntityAnimationState.Inactive; GetComponent <SpriteRenderer>().sortingOrder -= 1; _timeSinceStartedAnimation = 0f; _entityToBecomeParent = null; } } else if (_animationState == EntityAnimationState.Bumping) { _timeSinceStartedAnimation += Time.smoothDeltaTime; Vector3 previousWorldPosition = _gridInfoProvider.GetCellCenterWorld(_previousLogicalPosition); Vector3 middleWayToTarget = (previousWorldPosition + _gridInfoProvider.GetCellCenterWorld(_animationAffectedPosition)) / 2; Vector3 interpolatedPosition = Vector3Utilities.LerpThereAndBack(previousWorldPosition, middleWayToTarget, _timeSinceStartedAnimation / DefaultAnimationDuration); transform.position = interpolatedPosition; bool finished = _timeSinceStartedAnimation > DefaultAnimationDuration; if (finished) { _animationState = EntityAnimationState.Inactive; _timeSinceStartedAnimation = 0f; } } else if (_animationState == EntityAnimationState.BeingKnockedOut) { _timeSinceStartedAnimation += Time.smoothDeltaTime; // deltaTime could be unnaturally big // because of calculations done when player performs an action float progress = _timeSinceStartedAnimation / DefaultAnimationDuration; Quaternion interpolatedRotation = Quaternion.Lerp(_animationStartRotation, Quaternion.Euler(0, 0, 180), progress); transform.rotation = interpolatedRotation; bool finished = progress >= 1; if (finished) { _animationState = EntityAnimationState.Inactive; _timeSinceStartedAnimation = 0f; } } else if (_animationState == EntityAnimationState.StandingUp) { _timeSinceStartedAnimation += Time.smoothDeltaTime; // deltaTime could be unnaturally big // because of calculations done when player performs an action float progress = _timeSinceStartedAnimation / DefaultAnimationDuration; Quaternion interpolatedRotation = Quaternion.Lerp(_animationStartRotation, Quaternion.identity, progress); transform.rotation = interpolatedRotation; bool finished = progress >= 1; if (finished) { _animationState = EntityAnimationState.Inactive; _timeSinceStartedAnimation = 0f; } } }
public virtual void Process() { bool visibleEnemiesClose = ActorData.ControlledByPlayer && _entityDetector.DetectActors(ActorData.LogicalPosition, 3) .Count(a => a.Team != Team.Beasts && a.Entity.IsVisible) > 0; if (visibleEnemiesClose) { DateTime potentialBlockedUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(150); ActorData.BlockedUntil = potentialBlockedUntil > ActorData.BlockedUntil ? potentialBlockedUntil : ActorData.BlockedUntil; } IGameEntity entity = ActorData.Entity; IEntityAnimator entityAnimator = entity.EntityAnimator; IEnumerable <ActorData> enemiesNearby = _entityDetector.DetectActors(ActorData.LogicalPosition, 3) .Where(e => ActorData.Team != e.Team) .Where(e => Vector2IntUtilities.IsOneTwoOrThreeSteps(e.LogicalPosition, ActorData.LogicalPosition)); // this code orientates the actor to face the closest danger, even if it means stepping backwards List <Vector2Int> directionsToOneStepEnemiesNearby = enemiesNearby.Select(e => e.LogicalPosition - ActorData.LogicalPosition) .Where(direction => Vector2IntUtilities.IsOneStep(direction)) .ToList(); List <Vector2Int> directionsToAllEnemiesNearby = enemiesNearby.Select(e => e.LogicalPosition - ActorData.LogicalPosition).ToList(); List <Vector2Int> directionsToRelevantEnemiesNearby = directionsToOneStepEnemiesNearby.Any() ? directionsToOneStepEnemiesNearby : directionsToAllEnemiesNearby; bool thereAreSomeEnemiesOnOneSide = directionsToRelevantEnemiesNearby.Any() && (directionsToRelevantEnemiesNearby.All(direction => direction.x < 0) || directionsToRelevantEnemiesNearby.All(direction => direction.x > 0)); if (thereAreSomeEnemiesOnOneSide) { _actorAligner.AlignActorToDirection(ActorData.Entity, directionsToRelevantEnemiesNearby.First().x); } else { _actorAligner.AlignActorToDirection(ActorData.Entity, ActorData.LogicalPosition.x - PreviousPosition.x); } if (entity.IsVisible) { entityAnimator.MoveTo(PreviousPosition, ActorData.LogicalPosition); } else { Vector3 animationTargetPosition = _gridInfoProvider.GetCellCenterWorld(ActorData.LogicalPosition); // The next line makes this class kind of untestable, because ActorData.Entity is a MonoBehaviour. I believe it must be so, // so that we can see and assign the reference to it in the inspector window. If this happens more often in other effects, // we could maybe extract some kind of proxy class to keep the Entity, so that we can test with fake proxy. entity.Position = animationTargetPosition; } if (!ActorData.ControlledByPlayer) { return; } ItemData itemOnTheGround = _entityDetector.DetectItems(ActorData.LogicalPosition).FirstOrDefault(); if (itemOnTheGround != null) { _uiConfig.TooltipPresenter.Present(itemOnTheGround.ItemDefinition, false); } }