Jump to content
Unity Insider Forum

Error bei transform.position


DaBa123
 Share

Recommended Posts

Hallo Community,

ich bin noch relativ neu bei Unity (ich arbeite ca seit Mitte Juli damit) und habe einen Fehler in meinem Code gehabt: 'Transform' does not contain a definition for 'positon' and no accessible extension method 'positon' accepting a first argument of type 'Transform' could be found (are you missing a using directive or an assembly reference?)

Ich arbeite mit der Unity Version 2020.2.

Hier das Skript:

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

public class playercontroller : MonoBehaviour
{
    public Text text;
    public Text textsniper;
    public Text textMp7;
    public int keycollect = 0;
    public bool weapon1_bool = false;
    public bool weapon2_bool = false;
    public bool weapon3_bool = false;
    public string weapon1 = "AKM";
    public string weapon2 = "Sniper";
    public string weapon3 = "MP7";
    private void OnTriggerEnter(Collider other)
    {
       if(other.gameObject.tag == "Key")
        {
            Destroy(other.gameObject);
            keycollect = keycollect + 1;
            //die untere Zeile
            transform.position = new Vector3(175, 0, -1300);
        }  
        if(other.gameObject.tag == "Waypoint")
        {
            Destroy(other.gameObject);
        }
    }
    private void OnTriggerStay(Collider other)
    {
        if(weapon1_bool == false)
        {
            if(other.gameObject.tag == "Trigger" && Input.GetKey(KeyCode.F))
            {
                weapon1_bool = true;
                Debug.Log("OK");
                text.text = weapon1;
                Destroy(other.gameObject);

            }
        }
        if(weapon2_bool == false)
        {
            if(other.gameObject.tag == "Trigger1" && Input.GetKey(KeyCode.F))
            {
                weapon2_bool = true;
                Debug.Log("ok");
                textsniper.text = weapon2;
                Destroy(other.gameObject);

            }
            if(other.gameObject.tag == "Trigger2" && Input.GetKey(KeyCode.F))
            {
                weapon3_bool = true;
                Debug.Log("ok");
                textMp7.text = weapon3;
                Destroy(other.gameObject);

            }
        }
    }
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    }
    
}

Kann mir jemand helfen?

Danke,

Daniel

Link to comment
Share on other sites

Die Fehlermeldung sieht für mich nach einem Schreibfehler aus. "positon" -> "position".

Ich habe das Skript überflogen und sehe hier keine Fehler die das versursachen können.

Gibt es noch andere Skripte, die die Position von Gameobjekten setzen möchten?
Eventuell mal in der IDE im Projekt nach "positon" suchen um die fehlerhafte Zeile zu finden.

Link to comment
Share on other sites

Danke für die Antwort.
Der Fehler ist zwar weg, aber es macht nicht das, was es machen sollte(in meiner Vorstellung ^^). Ich wollte, dass der Player der den Key einsammelt zu der position verschoben wird, aber wie es aussieht, wird der Key, der bereits gelöscht ist, dahin verschoben. Wie kann ich das machen, dass der player dahin verschoben wird?

vor 16 Minuten schrieb SkipToPlay:

Gibt es noch andere Skripte, die die Position von Gameobjekten setzen möchten?
Eventuell mal in der IDE im Projekt nach "positon" suchen um die fehlerhafte Zeile zu finden.

Nein, das ist das einzige.

Link to comment
Share on other sites

Für mich sieht das Skript in Ordnung aus.
Prüfe ob alle Rahmenbedingungen eingehalten werden.
Das z.B. nur der Player in deiner Szene das Skript "playercontroller" zugewiesen hat, die Tags alle korrekt gesetzt sind, die Collider der anderen Objekten gesetzt und richtig konfiguriert sind.
Wenn das alles nicht hilft, versuch in deinem Code zusätzliche Debug-Befehle einzubauen, um nach und nach weitere Ursachen auszuschließen.
z.B: ein

Debug.Log(Time.frameCount + " " + name + " keycollect#: " +  keycollect );

in einer Zeile hinter "transform.position" um zu prüfen, ob dieser Code überhaupt ausgeführt wird.

Link to comment
Share on other sites

Sooo... 1. Nur der Player hat das entsprechende Skript, 2. Alle Tags sind korrekt, 3.Collider stimmen alle.
Der Code wird ausgeführt, sonst würde der Wert ja in der UI nicht geändert werden. Ich habe probiert den Befehl Destroy.GameObject mal weg gemacht um zu gucken, ob überhaupt iwas verschoben wird an die Position. Nein. 
Ich habe überlegt, um den Player zu verschieben müsste man ja nicht das other.gameObject (Den key) verschieben, sondern den Player z.B. mit dem Tag Player.

 

gameObject.tag == "Player" = transform.position = new Vector3(175, 0, -1300);

Hab diesen Code ausprobiert, nein, hat nicht geklappt. Es ist ein Error rausgekommen. 

Link to comment
Share on other sites

Gib doch mal die Zeile transform.position = new Verctor3(175f, 0f, -1300f);

in die Startmethode ein, ob der Player dann gleich verschoben wird.

Falls nicht, würde ich mal schauen, ob das Script auf der richtigen Ebene des Player-Gameobjects ist.

 

Link to comment
Share on other sites

Hallo,

vor 20 Stunden schrieb DaBa123:
gameObject.tag == "Player" = transform.position = new Vector3(175, 0, -1300);

Hab diesen Code ausprobiert, nein, hat nicht geklappt. Es ist ein Error rausgekommen. 

gameObject.tag == "Player" ,  ist ein String vergleich und gibt True oder False zurück .Dementsprechend kann man auch keinen Transform zuweisen. 

2 Sachen die man mal gerne vergisst.

1. Hat dein Player auch einen Rigidbody ?, ohne Rigidbody keine Collisions Erkennung.

2. Du benutzt die OnTriggerEnter( ) Methode. Haben alle bei der Collision beteiligten Collider auch den IsTrigger Parameter Aktiviert?.

Gruß Jog

Link to comment
Share on other sites

vor 8 Stunden schrieb Lewo:

Gib doch mal die Zeile transform.position = new Verctor3(175f, 0f, -1300f);

in die Startmethode ein, ob der Player dann gleich verschoben wird.

Falls nicht, würde ich mal schauen, ob das Script auf der richtigen Ebene des Player-Gameobjects ist.

 

Danke ich probier es. Es kann sein, dass es daran liegt, dass ich vergessen habe, das Float einzubauen.

Link to comment
Share on other sites

@Jog 1. Ja, sonst würde ja die Funktion gar nicht funktionieren. Die Keys werden ja eingesammelt, die Waffen genauso.

2. Der Is Trigger Parameter muss doch nicht aktiviert sein, da es gameObjects mit MeshCollidern sind. Nur die Trigger für die Waffen haben den Parameter aktiviert.

 

Viele Grüße

Daniel

Link to comment
Share on other sites

Hallo,

vor einer Stunde schrieb DaBa123:

da es gameObjects mit MeshCollidern sind. Nur die Trigger für die Waffen haben den Parameter aktiviert.

Hast du daran gedacht dass, entweder beim Rigidbody der Is Kinematic Parameter, oder beim MeshCollider der Is Convex Parameter aktiviert sein muss um mit der OnTriggerEnter( ) Methode zu interagieren. Vorausgesetzt Rigidbody und MeshCollider liegen als Component auf dem selben GameObject.

Gruß Jog

Link to comment
Share on other sites

Also ich glaube das Ganze ist ein wenig komplexer.
So wie ich das hier verfolgt habe, ist da kein Problem beim Triggern an sich. @DaBa123 hat ja ziemlich am Anfang schon geschrieben, dass die UI, sich aktualisiert. Ich gehe davon aus, dass er damit die Variable keycollect meint, die um 1 erhöht wird.

Meiner Meinung nach, ist der Collider, der das Triggerevent auslöst und auch das Scipt hat, nicht das Vaterobjekt des Players. Also irgend ein Unterobjekt, welches dann bestimmt auch verschoben wird, aber eben nicht der komplette Player.

@DaBa123

Ich will dir mal ein paar Dinge erklären, die dir vielleicht weiter helfen könnten.

Die Abfrage eines Tags soll man schon seit Jahren anders machen als du es tust. Du bekommst auch immer eine Info dazu, falls du VisualStudio zum programmieren nutzt.

Also nicht mehr if( other.tag == "dingens")  sondern if( other.CompareTag("dingens")) . Die machen für dich zwar beide das Gleiche, aber wenn Unity darauf hinweist, dass man es anders machen soll, dann solltest du das auch tun, denn irgendwann, in einer neueren Version, ist die alte Möglichkeit nicht mehr da und hast du ne Menge Arbeit vor dir.

Da du ja noch ganz frisch dabei bist, will ich dir mal eine andere Möglichkeit zeigen, um abzufragen, was man getriggert hat. Die Eingewöhnung fällt einem leichter wenn man ganz frisch bei einer Sache ist. Alte Gewohnheiten werden nur ungern geändert. ;)

Also: Einen Tag abzufragen ist etwas fehleranfällig, weil es ja ein String ist, bei dem man sich schnell mal verschreiben kann. Du suchst z.B. nach "dingens" mit kleinem D, hast aber den Tag "Dingens" mit großem D genutzt. Da das nicht das Gleiche ist, bekommst du auch kein true zurück. Die Fehlersuche kann dann recht lange dauern.
Um dieses Problem zu umgehen, kann man sich ein leeres Script erzeugen, welches einen Namen hat, nach dem man stattdessen sucht.
Man würde jetzt also so abfragen:

OnTriggerEnter(other Collider){
  // wir suchen nach einer Komponente vom Typ TheKey
  TheKey einKey =other.gameObject.GetComponent<TheKey>();
  if(einKey != null){ // nur wenn die TheKey gefunden wurde, ist die Variable einKey nicht mehr null 
    //mache Dinge
  }
}

Der Vorteil ist dabei, dass man sich nicht verschreiben kann, denn du kannst nur einen Variablentyp ( z.B. TheKey) nutzen, wenn der Typ auch existiert.

In deiner Key Abfrage, machst du ja gewisse Dinge.
 

if(other.gameObject.tag == "Key")
{
  Destroy(other.gameObject);
  keycollect = keycollect + ;
  //die untere Zeile
  transform.position = new Vector3(175, 0, -1300);
}

Als erstes zerstörst du das GameObject vom other. Das ist ja ok. Du musst dir aber merken, dass das Zerstören nicht sofort passiert, sondern erst wenn alles im Zyklus abgearbeitet wurde. Das nur zur Info, ist nix schlimmes. ;)

Danach erhöhst du die Variable keycollect, was ja wohl funktioniert und dir sagt, dass richtig getriggert wurde.

Und dann verschiebst du das Object welches dieses Script hier hat an eine gewisse Position.
Denn:

das gameObject mit kleinem g und das transform mit kleinem t sind automatisch erzeugte Referenzen zu genau dem GameObject mit seiner Transform-Komponente, welches genau dieses Script hat.
Ist das GameObject aber ein Kindobjekt eines anderen GameObjects ( wie z.B. ein Rad, welches das Kind eines Autos ist), und du verschiebst oder drehst es über die transform.position oder transform.rotation, dann hat das keine Auswirkung auf das Vaterobjekt!
Wenn ein Vaterobjekt verschoben wird, dann nimmt es auch die Kindobjekte mit, anders herum passiert das nicht.
Wenn Rigidbodys im Spiel sind, sieht es noch einmal ganz anders aus. Aber die sollte man eh nicht über transform bewegen sondern über spezielle Rigidbody Befehle, wie MovePosition.

Eine ganz wichtige Sache noch:

Du solltest beim Triggern nicht irgendwelche Dinge tun, die außerhalb der Physik passieren. Du fragst ja im OnTriggerStay zusätzlich die Tastatur ab. Das funktioniert zwar wenn du das halten der Taste F abfragst, es würde aber nicht funktionieren, wenn du das Drücken (Down) oder Loslassen (Up) abfragen würdest.
Du musst immer daran denken, dass alle physikalischen Dinge (Kollisionen, Triggerevents, Rigidbodybewegungen usw.) in dem Zyklus des FixedUpdates abgearbeitet werden. Dieser Zyklus hat eine komplett anderen Zeitrahmen, als die Dinge die in der Update passieren. Es ist also nie gleichzeitig und nur dann, wenn sich beide Zyklen mal überscheiden würde es funktionieren!

Wenn also etwas physikalisches passiert, wie z.B. ein Triggerevent, und es wirkt sich auf Dinge aus, die normalerweise in der Update abgearbeitet werden sollen, dann nutze Variablen, die zwar im Trigger Event gesetzt werden, aber nur in der Update eine Wirkung haben.
Als Beispiel ein Treffen eines Objektes mit einer Kugel, welches sich zerstören soll, wenn alle Hitpoints verbraucht sind.
Die Kugel trifft also das Objekt und guckt ob das Objekt ein Lebenspunktescript hat. Wenn ja, dann sendet es an eine öffentliche Methode in diesem Script, dass das Objekt jetzt 10 Schadenpunkte bekommt. Egal ob das getroffene Objekt dieses Lebenspunktescript hat, oder nicht. Die Kugel kann sich jetzt zerstören.
Das Objekt, welches getroffen wurde, hat in seiner Methode die 10 Schadenspunkte von seinen Lebenspunkten abgezogen, sonst ist da nichts passiert.
Aber im nächsten Update-Zyklus werden die Lebenspunkte verarbeitet und wenn sie auf 0 stehen, dann zerstört sich das Objekt und macht tolle visuelle Dinge.

Es kommt nicht darauf an, dass exakt in dem Moment, wo das Objekt getroffen wurde etwas passiert, denn sehen tust du das sowieso erst im nächsten Update.
Aber alles, was in der FixedUpdate mit abgearbeitet würde, kostet Zeit. Irgendwann kommt der Zyklus nicht mehr hinterher. Deswegen nur die nötigsten Dinge in physikalischen Events machen.

Also normalerweise sollte sich das Objekt, welches das Script hat, auch an die neue Position setzen, sobald du den Schlüssel berührst.
Ob das Objekt aber jenes ist, welches du auch bewegt haben willst, hängt halt davon ab, ob es auch der Vatter ist. Außerdem kann ein Rigidbody sich weigern dahin zu springen, weil es Parameter gibt, die ihn blockieren können.

Solltest du weiterhin nicht zum Ziel kommen, dann mach doch bitte mal einen Screenshot von dem Objekt, welches das Script hat. Das müssen wir sehen, denn sonst kommen wir nicht weiter.

 

 

 

 

Link to comment
Share on other sites

Hallo @malzbie

Danke für deine ausführliche Erklärung.

Da hast Du Recht, das Triggern ist nicht das Problem.

Zitat

Die Abfrage eines Tags soll man schon seit Jahren anders machen als du es tust. Du bekommst auch immer eine Info dazu, falls du VisualStudio zum programmieren nutzt.

Ich habe das Spiele programmieren mit einem Tutorial von einem YouTuber gelernt und da hat er das so gemacht. Ich nutze nicht VisualStudio, sondern VS Code, weil ich es vom programmieren zuhause(ich programmiere auch so gerne mal und das Spiele Entwickeln mache ich zur Abwechslung und weil ich Lust hatte).

 

vor 9 Stunden schrieb malzbie:

Also: Einen Tag abzufragen ist etwas fehleranfällig, weil es ja ein String ist, bei dem man sich schnell mal verschreiben kann. Du suchst z.B. nach "dingens" mit kleinem D, hast aber den Tag "Dingens" mit großem D genutzt. Da das nicht das Gleiche ist, bekommst du auch kein true zurück.

Ja, ich habe auf die Groß- und Kleinschreibung geachtet, aber ich verstehe den Gedanken.

 

vor 9 Stunden schrieb malzbie:

Ist das GameObject aber ein Kindobjekt eines anderen GameObjects ( wie z.B. ein Rad, welches das Kind eines Autos ist), und du verschiebst oder drehst es über die transform.position oder transform.rotation, dann hat das keine Auswirkung auf das Vaterobjekt!
Wenn ein Vaterobjekt verschoben wird, dann nimmt es auch die Kindobjekte mit, anders herum passiert das nicht.
Wenn Rigidbodys im Spiel sind, sieht es noch einmal ganz anders aus. Aber die sollte man eh nicht über transform bewegen sondern über spezielle Rigidbody Befehle, wie MovePosition.

Ja, ich weiß das mit der Parent-Child Sache. 

Ok, das werde ich mal anschauen, weil der Player Prefab hat einen Rigidbody.

vor 9 Stunden schrieb malzbie:

Du fragst ja im OnTriggerStay zusätzlich die Tastatur ab. Das funktioniert zwar wenn du das halten der Taste F abfragst, es würde aber nicht funktionieren, wenn du das Drücken (Down) oder Loslassen (Up) abfragen würdest.
Du musst immer daran denken, dass alle physikalischen Dinge (Kollisionen, Triggerevents, Rigidbodybewegungen usw.) in dem Zyklus des FixedUpdates abgearbeitet werden. Dieser Zyklus hat eine komplett anderen Zeitrahmen, als die Dinge die in der Update passieren. Es ist also nie gleichzeitig und nur dann, wenn sich beide Zyklen mal überscheiden würde es funktionieren!

Ja das tue ich. Zur Verständnis: Meinst Du mit halten der F Taste das gedrückt halten, oder drücken und loslassen? Weil ich drücke nur die F Taste und die Waffe wird eingesammelt. Okay, also ist die OnTriggerStay Funktion im Prinzip eine FixedUpdate Funktion? 

1.Screenshot: Der Player mit dem Script.

2.Screenshot: Eine Waffe vor der Taste F

3.Screenshot: Die Waffe nach der Taste F

4.Screenshot: Der Key

5.Screenshot: Nachdem ich den Key aufgenommen habe(auf der entsprechenden Position ist nichts)

Screenshot (20).png

Screenshot (21).png

Screenshot (22).png

Screenshot (23).png

Screenshot (24).png

Link to comment
Share on other sites

Die meisten Dinge, die ich dir geschrieben habe, drehen sich nicht unbedingt um dein Problem, sondern sollen dir nur aufzeigen warum man etwas nicht unbedingt so machen sollte, wie du es tust. Es heisst ja nicht, dass deine Herangehensweise nicht funktioniert, sie kann aber zu Problemen führen. Und wenn dann so ein Problem auftritt, dann suchst du dich tot.
Wie z.B. das mit der Taste F. GetKey ist ja der Zustand, dass eine Taste gedrückt wurde und sie auch weiterhin noch gedrückt ist. Dieser Zustand steht ja so lange an, wie du die Taste hältst, deswegen funktioniert das Triggern und gleichzeitige Auswerten der Taste auch.
Wenn du aber den Druck nach unten, oder das Loslassen der Taste auswerten würdest, dann wird das beim Triggern nicht unbedingt funktionieren, weil diese Info nur ein einziges Frame anhält.
Frame1 = nichts -> Frame2 =F wurde gedrückt -> Frame3 = F ist gedrückt-> ..... Frame 12 = F ist gedrückt -> Frame13 = F wurde losgelassen ->Frame14 =nichts.

Wenn jetzt deine Framerate 60 Bilder pro Sekunde ist, aber dein Physikzyklus nur 40 mal pro Sekunde ist, dann kann es sein, dass der Moment des Drückens gerade verpasst wurde und es somit nicht zur Bedingung kommt. Es kann aber auch genau passen.

Du machst das ja in der OnTriggerStay und zusätzlich fragst du das Halten der Taste ab, deswegen gibt es bei dir keine Probleme.

 Soviel dazu.

Jetzt zu deinem letzten Bild. So wie ich es sehe, hast du den Key aufgenommen und bist doch auch bei den Steinen. Also geht er doch an diese Position, oder etwa nicht?

Aber:

Ich sehe, dein player hat einen Character Controller. Du hast also einen CC und zusätzlich einen Rigidbody drauf. Das solltest du vermeiden. Entweder den CC nutzen oder alles mit dem RB machen. Der CC hat eine ganz andere Physikberechnung und funktioniert anders als ein RB.
Ich kann dir nicht sagen, ob die Kombination beider Dinge deine Probleme verursachen. Aber da solltest du mal ansetzen.

Link to comment
Share on other sites

Ups, die Nachricht gerade war ausversehen

 

Achso alles klar, danke für die Tipps.

Nein, ich bin zu dem Key hingegangen, und habe ihn berührt, so konnte ich ihn einsammeln.

Die eigentliche Position liegt außerhalb der Map.

Ja stimmt, daran könnte es liegen.

 

Viele Grüße 

Am 21.8.2022 um 11:54 schrieb Lewo:

 

Link to comment
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...
 Share

×
×
  • Create New...