Jump to content
Unity Insider Forum

Recommended Posts

Ich habe folgendes Problem. Ich habe in meinem 2D Spiel was in einer 3D Umgebung ist allen Objekten die Rotation und auch die Position auf der Y Ebene festgelegt. Es kommt aber immer mal wieder vor, dass mein Spieler oder auch Gegner durch Kollisionen nach oben rutschen. Teilweise sogar nicht gerade knapp. Ein Gegner der von der Position y5 auf den Spieler schießt der auf y3 ist ist natürlich schwer zu besiegen...

Ich könnte zwar ein script schreiben, dass wenn ein Objekt auf Y höher oder tiefer als 3 wieder zurück gesetzt wird aber das kann ja nicht der Sinn seid.

Share this post


Link to post
Share on other sites

So völlig ohne Hinweise oder Code darüber, wie das überhaupt passieren könnte, kann man dir nur schwerlich helfen.

Share this post


Link to post
Share on other sites

Mmmh... okay dann schau ich mal, was ich da zusammen bekomme.

Wie gesagt, Rotation und Position sind auf der Y-Achse von Seite von Unity im Inspektor ausgeschaltet.

image.png.461ee737fe97657a2f7367b8649d00f9.png

Mein KI drückt sich aber, wenn sie zusammenstoßt aber trotzdem hoch oder runter. 

Zum Code: Hier weiß ich jetzt nicht genau, was du da brauchen könntest. Hier mal das Skript für meine KI, die die Bewegung steuert. (Ein Hinweis vorneweg: Das ist mein erster versuch eine KI zu entwickeln! Das sie nicht perfekt ist, ist mir bewusst. Ich bin aber schon stolz auf mich, dass ich es alleine geschafft habe. Sie läuft nicht super aber sie schießt auf den Spieler und Bewegt sich so wie ich es wollte (meistens zumindest). Das hier einiges zu verbessern ist ist mir absolut klar)

 void Start()
    {
        v1 = transform.position;
        player = GameObject.Find("Player");
        pltr = player.GetComponent<Transform>();   
        rb = GetComponent<Rigidbody>();
        NewWanderpoint();

        InvokeRepeating("GeschwindigkeitMesser", 0.1f, 0.1f);
    }

    void Update()
    {
        MachKaputt(); //Nur zum Testen! Wiederlöschen sobald nicht mehr benötigt!!!

        if (player == null)
        {
            goto Finish;
        }
        // Spieler ist geflohen und außer Reichweite --> zur letzen bekannten stelle fliegen
        float dist = Vector3.Distance(pltr.position, transform.position);
        if (playerInSight == true)
        {
            if (dist > reichweite)
            {
                wanderpoint = pltr.position;
            }
        }

        //zunächst Prüfen ob Spieler in Sicht ist.
        if(dist<= reichweite)
        {
            playerInSight = true;
        }
        else 
        {
            playerInSight = false;
        }

        if (playerInSight == false)
        {
            //Patroulie fliegen
            float distwanderpoint = Vector3.Distance(wanderpoint, transform.position);
            if (distwanderpoint <= 10) //Wanderpoint erreicht
            {
                NewWanderpoint();
            }
            else //Wanderpoint noch nicht erreicht
            {
                //Weiter auf Wanderpoint zufliegen bzw. drehen
                Vector3 v3 = wanderpoint - transform.position; //prüfen in welcher Richtung das Ziel ist
                Vector3 newDirection = Vector3.RotateTowards(transform.forward, v3, turnspeed * Time.deltaTime, 0f);
                transform.rotation = Quaternion.LookRotation(newDirection);

                rb.velocity = transform.forward * speed;
            }
        }
        else //(playerInSight == true)
        {
            if (dist <= kampfreichweite) //Spieler ist nah genug!
            {
                Angriff();
                if (dist <= kampfreichweiteclose)
                {
                    rb.velocity = transform.forward * 0;
                }
                else
                {
                    rb.velocity = transform.forward * kampfspeednear;
                }
                Vector3 v3 = pltr.position - transform.position; //prüfen in welcher Richtung das Ziel ist
                Vector3 newDirection = Vector3.RotateTowards(transform.forward, v3, turnspeed * Time.deltaTime, 0f);
                transform.rotation = Quaternion.LookRotation(newDirection);
            }
            else
            {

                Vector3 v3 = pltr.position - transform.position; //prüfen in welcher Richtung das Ziel ist
                Vector3 newDirection = Vector3.RotateTowards(transform.forward, v3, turnspeed * Time.deltaTime, 0f);
                transform.rotation = Quaternion.LookRotation(newDirection);
                //Auf Spieler zufliegen
                rb.velocity = transform.forward * kampfspeedfar;
            }
        }
        if(fighttimer >= feuergeschwindigkeit)
        {
            fighttimer = feuergeschwindigkeit;
        }
        else
        {
            fighttimer += Time.deltaTime;
        }
    Finish:;

    } //Update Ende

    void NewWanderpoint()
    {
        float rndXmin = pltr.position.x - wanderrange;
        float rndXmax = pltr.position.x + wanderrange;
        float rndZmin = pltr.position.z - wanderrange;
        float rndZmax = pltr.position.z + wanderrange;

        wanderpoint.x = (Random.Range(rndXmin, rndXmax));
        wanderpoint.y = 3;
        wanderpoint.z = (Random.Range(rndZmin, rndZmax));
    }

Wie gesagt, dass ist jetzt nur das zur Bewegung.  Da kommen noch ein paar mehr Methoden die aber nicht auf die Bewegung Einfluss nehmen.

Brauchst du sonst noch etwas?

Share this post


Link to post
Share on other sites

image.png.e29c5de30ffac2664b214b8c868a5b5d.png

image.png.c9adbf5c61f5a31eae2726d95557fb79.png

Dieser Gegner wurde von den anderen soweit runter gedrückt, (normalerweise ist alles auf y = 3) dass er für den Spieler nicht mehr erreichbar ist. Da die Schüsse auch auf der Ebene bleiben kann der Gegner auch den Spieler nicht mehr abschießen aber der Sinn ist ein anderer.

Ich habe auch mal gerade versucht, dass ich die Bewegung und Rotation in Y Richtung wieder zulasse. Das gibt aber wahrscheinlich das Script nicht her deswegen macht das alles nur noch schlimmer xD.

Share this post


Link to post
Share on other sites

Rigidbodys sind nicht besonders freundlich, wenn es um Kontrolle geht. Die machen prinzipiell ihr Ding und müssen gebändigt werden, wenn sie weniger machen sollen. Ab einem bestimmten Punkt lohnt es sich daher, auf nicht-kinematische Rigidbodys zu verzichten und stattdessen selber etwas zu bauen, weil das Bändigen aufwendiger wird als das Implementieren einer eigenen Lösung.

Die Constraints funktionieren gut, um die Geschwindigkeit eines Rigidbodys zu beschränken, sodass keine Bewegung in Richtung X mehr passiert. Allerdings merkt sich der Rigidbody nicht beim aktiviert werden, welche Position er auf der jeweiligen Achse hat und überschreibt die Position ständig. Wenn sich die Position auf der Achse aus irgendwelchen anderen Gründen ändert als durch die regelmäßige Anwendung des Geschwindigkeitsvektors, dann kann sich die Position auch mal ändern. Rigidbodys finden es sehr wichtig, nicht in anderen Collidern drinzustecken. Und wenn sie keinen anderen Weg aus Collidern heraus finden als über eine eingeschränkte Achse, dann gehen die halt da lang.

Letztenendes darf man nicht vergessen: Die Dinger sind dafür da, runterfallende Kisten und so etwas zu simulieren. Dass inzwischen irgendwie Spielfiguren und Gegner nicht-kinematische (!) Rigidbodys unter der Haube haben, um sich damit durch die Welt zu bewegen, ist ein Riesenfehler.

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...