English 中文(简体)
B. 统一实施无能动的移动制度的问题
原标题:Issues with implementing tile-snap movement system in Unity

我致力于把基于我的运动纳入其中,其宗旨是使行动方向的特性符合下一个徒劳无益。 目前,有一个问题,即无论投入方向如何,参与者总是被带往顶和右囚室。 因此,当我把性质转移出底时,它会 s到右上或上下层,而不是按预期的方向发展。 我利用新的参与者投入系统。

Current logic:

The target grid position is calculated based on the current player position (rb.position) divided by the gridSize. This gives the grid cell that the player is currently in. The center of the next tile in the movement direction is calculated by adding the movementInput vector to the target grid position. The rb.MovePosition method is then used to smoothly move the player towards the calculated center of the next tile. It uses Vector2.Lerp to interpolate between the current position and the target position. nextTileCenter * gridSize converts the grid position back to world space. new Vector2(gridSize / 2, gridSize / 2) is added to ensure that the player moves to the center of the next tile.

`script:

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 1f;
    public float snapSpeed = 10.0f;
    public LayerMask collisionLayer;

    Vector2 movementInput;
    SpriteRenderer spriteRenderer;
    Rigidbody2D rb;
    Animator animator;
    Transform gridTransform; // Reference to the grid game object

    bool canMove = true;
    float gridSize = 0.16f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        spriteRenderer = GetComponent<SpriteRenderer>();

        // Find the grid game object
        gridTransform = GameObject.Find("Grid").transform;
    }

    private void FixedUpdate()
    {
    if (canMove)
    {
        // Get raw input without normalization
        Vector2 rawInput = movementInput;

        // Normalize the input vector to limit diagonal movement
        movementInput = new Vector2(Mathf.Round(rawInput.x), Mathf.Round(rawInput.y)).normalized;

        if (movementInput != Vector2.zero)
        {
            // Calculate the target position on the grid
            Vector2 targetPosition = CalculateTargetPosition(rb.position, movementInput);

            // Check for potential collisions
            RaycastHit2D hit = Physics2D.Raycast(targetPosition, Vector2.zero, gridSize, collisionLayer);
            if (hit.collider == null)
            {
                // Move towards the target position using Rigidbody2D.MovePosition()
                rb.MovePosition(rb.position + movementInput * moveSpeed * Time.deltaTime);
            }
            else
            {
                // Player hit something, try to snap to the grid smoothly
                SmoothSnapToGrid();
            }

            animator.SetBool("isMoving", true);
        }
        else
        {
            // Player is not moving, try to snap to the grid smoothly
            SmoothSnapToGrid();

            animator.SetBool("isMoving", false);
        }

        // Set direction of sprite to movement direction
        if (movementInput.x < 0)
        {
            spriteRenderer.flipX = true;
        }
        else if (movementInput.x > 0)
        {
            spriteRenderer.flipX = false;
        }
    }
}

    private void SmoothSnapToGrid()
    {
        // Calculate the target grid position
        Vector2 targetGridPosition = new Vector2(
            Mathf.Round(rb.position.x / gridSize),
            Mathf.Round(rb.position.y / gridSize)
        );

        // Calculate the center of the next tile in the movement direction
        Vector2 nextTileCenter = targetGridPosition + movementInput;

        // Smoothly move towards the center of the next tile in the movement direction
        rb.MovePosition(Vector2.Lerp(rb.position, nextTileCenter * gridSize + new Vector2(gridSize / 2, gridSize / 2), snapSpeed * Time.deltaTime));
    }

    private Vector2 CalculateTargetPosition(Vector2 currentPosition, Vector2 direction)
    {
        // Calculate the target position based on the movement direction
        Vector2 targetPosition = currentPosition + direction * moveSpeed * Time.deltaTime;

        return targetPosition;
    }

    void OnMove(InputValue movementValue)
{
    Vector2 rawInput = movementValue.Get<Vector2>();
    float horizontal = Mathf.Round(rawInput.x);
    float vertical = Mathf.Round(rawInput.y);

    // Ensure only one direction is considered
    if (Mathf.Abs(horizontal) > Mathf.Abs(vertical))
    {
        movementInput = new Vector2(horizontal, 0f).normalized;
    }
    else
    {
        movementInput = new Vector2(0f, vertical).normalized;
    }
}


    public void LockMovement()
    {
        canMove = false;
    }

    public void UnlockMovement()
    {
        canMove = true;
    }
}`

Anyone could help with that please? Thank you

问题回答

The Mathf.Round function rounds to the nearest integer, which means if the player s position is exactly in the middle of two cells, it might not round to the expected direction. This could be causing the consistent snapping to the top and right cells.

为此,您可修改<>。 SmoothSnapToGrid方法是在计算目标网位时说明流动方向。 不使用 Mathf.Round,根据行动方向,可使用Mathf.Floor<>Mathf.Ceil:

private void SmoothSnapToGrid()
{
    // Use Floor or Ceil depending on the direction to ensure snapping to the correct cell
    Vector2 targetGridPosition = new Vector2(
        (movementInput.x > 0) ? Mathf.Floor(rb.position.x / gridSize) : Mathf.Ceil(rb.position.x / gridSize),
        (movementInput.y > 0) ? Mathf.Floor(rb.position.y / gridSize) : Mathf.Ceil(rb.position.y / gridSize)
    );

    // Calculate the center of the next tile in the movement direction
    Vector2 nextTileCenter = targetGridPosition + movementInput;

    // Smoothly move towards the center of the next tile in the movement direction
    rb.MovePosition(Vector2.Lerp(rb.position, nextTileCenter * gridSize + new Vector2(gridSize / 2, gridSize / 2), snapSpeed * Time.deltaTime));
}

这一变化确保,在移出或缩小时(流动投入x <0或移动投入.y <0),Mathf。 锡尔被用于获得上层,实际上向左上或底层的囚室进行pping。 反之,在移动权或提升时(流动投入x >0或移动投入.y >0),Mathf。 底层用于向右上或上层进行na。

此外,必须确保你的网上方法准确地确定流动数据。 如果你重新研究分校运动的问题,或想在某个时候只确保运动的一个轴心,那么你目前的执行似乎是正确的。

最后,始终确保你的电网面积(电网)与你在游戏世界中的实际功能相匹配。 如果存在不匹配的情况,可能会导致错误的pping弄。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签