Jump to content
Unity Insider Forum
Splashy

Wer findet den Bug? 2D Top-Down: Anfängerfehler?

Recommended Posts

Hallo zusammen

Ich bin ein C# und Unity Anfänger, der sich in einem 2D Top down Game versucht. Das Spiel funktioniert schon recht gut jedoch finde ich den einen Bug nicht!!!

Das Problem ist, dass der Spieler sich nicht bewegt oder die Eisblöcke nur noch langsam geschoben werden, wenn es immer weniger Eisblöcke auf dem Spielfeld gibt. Meisten passiert das, wenn es nur noch 5,4 oder 3 Blöcke hat. Siehe Video. Manchmal bugt jedoch auch der Spieler bei einem Eisblock.

Der Unit - Setup ist auf Bild B zu sehen. Die beiden Scripts sind ebenfalls weiter unten dokumentiert.

Würde mich sehr freuen, wenn mir hierbei jemand helfen könnte. Vielen Dank im Voraus!

using System.Collections;
using UnityEngine;

class PlayerMovement : MonoBehaviour
{
    private Vector2 targetPosition;
    private float speed = 5f;
    private bool MoveAllowed;
    private Vector2 change;
    private Animator animator;
    private Vector2 IceCubePosition;
    private GameObject PushWallObject;
    private Vector2 NewDirection;

    // PUBLIC VARIABLES
    public bool MoveCube;
    public GameObject IceCubeObject; 
    public Vector2 PushWallObjectPosition;

    private void Awake()
    {
        // Set this so we don't wander off at the start
        targetPosition = new Vector2Int(Mathf.RoundToInt(transform.position.x), Mathf.RoundToInt(transform.position.y));
        transform.position = (Vector2)targetPosition;
        MoveAllowed = true;

        //MoveCube = false;
    }

    private void Start()
    {
        animator = GetComponent<Animator>();
        //Debug.Log("Dir: " + NewDirection);
    }

    public void Update()
    {
        // Animation START
        change = Vector2.zero;
        change.x = Input.GetAxisRaw("Horizontal");
        change.y = Input.GetAxisRaw("Vertical");

        if (change != Vector2.zero)
        {
            animator.SetFloat("moveX", change.x);
            animator.SetFloat("moveY", change.y);
        }
        // Animation END

        if ((Vector2)transform.position != targetPosition)
        {
            MoveTowardsTargetPosition();
            // Animation START
            animator.SetFloat("AnimSpeed", change.sqrMagnitude);
            // Animation END
        }

        else
        {
            SetNewTargetPositionFromInput();
        }
    }

    private void MoveTowardsTargetPosition()
    {
        transform.position = Vector2.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
    }

    // INPUTSYSTEM
    private void SetNewTargetPositionFromInput()
    {
        if (Input.GetKey(KeyCode.W))
        {
            NewDirection = new Vector2(0, 1);
            PushAndDestroy(NewDirection);
        }

        else
        if (Input.GetKey(KeyCode.S))
        {
            NewDirection = new Vector2(0, -1);
            PushAndDestroy(NewDirection);
        }

        else
        if (Input.GetKey(KeyCode.A))
        {
            NewDirection = new Vector2(-1, 0);
            PushAndDestroy(NewDirection);
        }

        else
        if (Input.GetKey(KeyCode.D))
        {
            NewDirection = new Vector2(1, 0);
            PushAndDestroy(NewDirection);
        }
        MoveAllowed = true;

    }

    private void PushAndDestroy(Vector2 NewDirection)
    {
        //MoveCube = false; // not worksing
        RaycastHit2D[] hitsOne = Physics2D.RaycastAll(transform.position, NewDirection, 1f); //1 Block analysieren
        if (hitsOne.Length == 1)
        {
            MoveCube = false; //good working
            RaycastHit2D[] hitsPush = Physics2D.RaycastAll(transform.position, NewDirection, 20f); //20 Blöcke analysieren                                                                                   //Debug.Log(hitsTwo.Length);
            Debug.Log("Wieviele Objekte sind denn da: " + hitsPush.Length);

            IceCubeObject = hitsPush[0].collider.gameObject;
            IceCubePosition = hitsPush[0].point;

            PushWallObject = hitsPush[1].collider.gameObject;
            PushWallObjectPosition = hitsPush[1].point - (NewDirection/2);

            RaycastHit2D[] FrontRay = Physics2D.RaycastAll(transform.position, NewDirection, 2f); //2 Block analysieren

            if (FrontRay.Length == 1 && hitsPush[0].collider.CompareTag("IceCube") && Input.GetKey(KeyCode.Space))
                {
                //Push Funktion aufrufen im Objekt IceCube
                MoveCube = true;
            }

            // Wenn 2 Blöcke erkannt werden und der erste Block ein IceCube ist, dann zerstöre den IceCube
            RaycastHit2D[] DestroyRay =  Physics2D.RaycastAll(transform.position, NewDirection, 2f); //2 Block analysieren
            if (DestroyRay.Length == 2 && hitsPush[0].collider.CompareTag("IceCube") && Input.GetKey(KeyCode.Space))
            {
                Destroy(hitsPush[0].transform.gameObject);
            }
        }

        else

        if (MoveAllowed == true)
        {
            targetPosition += NewDirection;
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PushIceCube : MonoBehaviour
{
    PlayerMovement PlayerMovementScript;
    private readonly float PushSpeed = 1.5f;
    private Vector2 PushWallObjectPosition;
    private bool MoveCube;
    private GameObject IceCubeObject;

    // Start is called before the first frame update
    void Start()
    {
        PlayerMovementScript = GameObject.Find("Player").GetComponent<PlayerMovement>(); 
    }

    // Update is called once per frame
    void Update()
    {
        MoveCube = PlayerMovementScript.MoveCube;
        IceCubeObject = PlayerMovementScript.IceCubeObject;
        PushWallObjectPosition = PlayerMovementScript.PushWallObjectPosition;
        if (MoveCube == true)
        {
            IceCubeObject.transform.position = Vector2.MoveTowards(IceCubeObject.transform.position, PushWallObjectPosition, PushSpeed * Time.deltaTime);
        }
    }
}

 

Bild B - Unity Setup.jpg

Share this post


Link to post
Share on other sites

Moin @Splashy! Erstmal wilkommen im Forum! :)

Schätze ich habe deinen Bug gefunden (gibts finderlohn ? 😜). So wie ich das sehe

  • führst du PushAndDestroy aus wenn der spieler sich bewegt
  • Checkst ob innerhalb 1 Unit in moveDirection ein cube is
  • Wenn Ja setzt du MoveCube auf False
  • Dann schaust du ob du den getroffenen Cube Pushen kannst (), falls ja (und die SPACE taste gedrückt ist) setzt du MoveCube wieder auf True

Was jetzt aber passiert ist das in PushIceCube deine Update methode jedes frame aufgerufen wird. Wenn du jetzt aber im letzten Frame einen IceCube gepusht hast, du dich weiterhin bewegst während er noch näher als 1 unit ist, wird der IceCube angehalten und nicht wieder auf MoveCube = True gesetzt (wenn die space bar nicht gedrückt ist)

Share this post


Link to post
Share on other sites

Hallo Cxyda

Vielen Dank für einen Input. ich werde mir das anschauen. Und ja, es gibt einen Finderlohn: Du kriegst das Spiel wenn es fertig ist! 😉 

Danke Dir!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...