public void SetView(PointerMovementState state) { switch (state.SmoothState) { case PointerState.InJumpMovement: spriteRenderer.color = Color.yellow; break; case PointerState.InNormalMovement: spriteRenderer.color = Color.white; break; case PointerState.NotPresent: spriteRenderer.color = Color.red; break; } gameObject.transform.position = state.Position; Trace.Info(TraceCategory.PointerLocation, $"New loc: {gameObject.transform.position}"); }
void FixedUpdate() { var position = mainCamera.ScreenToWorldPoint(Input.mousePosition); position.z = 0; var movementState = new PointerMovementState() { Position = position }; var prevMovementState = movements[movements.Count - 1]; var deltaPosition = movementState.Position - prevMovementState.Position; deltaPosition.y -= Time.fixedDeltaTime * 0.12f; if (prevMovementState.SmoothState == PointerState.NotPresent) { movementState.SmoothState = PointerState.InNormalMovement; movementState.ActualState = PointerState.InNormalMovement; } else { // Needs to drop below some threshold to be considered normal again if already in jump float jumpMovementThresh = prevMovementState.SmoothState == PointerState.InJumpMovement ? jumpMovementThresholdHisteresisDown : jumpMovementThreshold; bool isFastMovement = deltaPosition.magnitude > jumpMovementThresh; bool canJump = timeSinceLastJump > jumpCooldown || prevMovementState.SmoothState == PointerState.InJumpMovement; movementState.ActualState = (isFastMovement && canJump) ? PointerState.InJumpMovement : PointerState.InNormalMovement; if (movementState.ActualState == PointerState.InNormalMovement || prevMovementState.SmoothState == PointerState.InJumpMovement) { bool stopJump = true; for (int i = 0; i < FramesInNormalToStopJump; ++i) { var movement = movements[movements.Count - i - 1]; if (movement.ActualState == PointerState.InJumpMovement) { stopJump = false; break; } } if (stopJump) { movementState.SmoothState = PointerState.InNormalMovement; } else { movementState.SmoothState = PointerState.InJumpMovement; } } else { movementState.SmoothState = movementState.ActualState; } } var viewportPosition = mainCamera.ScreenToViewportPoint(Input.mousePosition); bool isOutOfBounds = viewportPosition.x < 0 || viewportPosition.x > 1 || viewportPosition.y < 0 || viewportPosition.y > 1; if (isOutOfBounds) { viewportPosition.x = Mathf.Clamp01(viewportPosition.x); viewportPosition.y = Mathf.Clamp01(viewportPosition.y); movementState.Position = mainCamera.ViewportToWorldPoint(viewportPosition); movementState.SmoothState = PointerState.NotPresent; movementState.ActualState = PointerState.NotPresent; } // This can be implemented more efficiently by circular buffer // but there is no implementation directly in C# movements.Add(movementState); movements.RemoveAt(0); if (movementState.SmoothState == PointerState.InJumpMovement) { timeSinceLastJump = 0; } else { timeSinceLastJump += Time.deltaTime; } Trace.Info(TraceCategory.PointerMovement, $"Movement added: {movementState}"); pointerView.SetView(movementState); }