Jump to content
Unity Insider Forum

MaZy

Members
  • Posts

    667
  • Joined

  • Last visited

  • Days Won

    29

Everything posted by MaZy

  1. Hallo im Inspector lasse ich mir ein ObjectField anzeigen. So sieht das in OnInspectorGUI(). SerializedProperty textComponentProperty = serializedObject.FindProperty("m_textComponent"); EditorGUILayout.ObjectField(textComponentProperty); if (GUI.changed) { Debug.Log(textComponentProperty.objectReferenceValue); serializedObject.ApplyModifiedProperties(); EditorUtility.SetDirty(target); } Dort kann ich ein text component reinwerfen. Wenn ich nun ein Text component drag and drop mache, wird beim Debug.Log auch kein null angezeigt. Heißt, dass es funktioniert hat mit drag and drop, doch danach ist es sofort wieder null. Ich weiß gar nicht mehr was ich machen soll. Im selben component ist string dabei und das lässt sich speichern. Benutze 2020.2.3f1 Hab es doch heraus gefunden: Ich hab zwei Types die Text heißen und hat nach falschen Text gesucht. Unity hat mir aber keine Fehlermeldung gezeigt, dass die Types nicht passen, sondern machte daraus direkt null. Zweites Type ist ein Child von UI.Text.
  2. Verstehe. Theorietisch müsste man so machen, damit es geht: Vector3 pos = transform.position; pos.Set(100,0,0); transform.position = pos;
  3. @Sascha Oh, das mit Set kannte ich auch noch nicht. Oh man hätten sie auch noch gleich SetX, SetY, SetZ gemacht (hab ich aber als extension gemacht) z.B. transform.position = transform.position.SetX(0).SetY(0). Ich weiß man kann position[0] fürs x setzen machen, aber die Schreibweise ist irgendwie doof und das obige funktioniert auch nicht so.
  4. Ich sehe deutlich, dass bei dir Unity Extension für Visual Studio nicht installiert ist. Kann eventuell daran liegen, aber bin mir nicht sicher. Edit: Aso auch MonoBehaviour ist nicht erkannt worden. Liegt wohl dann doch nicht an der Extension, sondern vllt müssen die Projektdateien neu erstellt werden bzw. Visual Studio mal neustarten.
  5. Unity hat dazu allgemeine VR Packages, wo man nur beim Canvas ein Component reinpacken muss. Zusätzlich noch paar für die Controller für die Raycasts. Danach gehen diese Events auch normal für VR. https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@1.0/manual/index.html#ui-interaction-setup
  6. Ist schon lange her, dass ich GoogleAds eingebunden habe, da ich mittlerweile fast nur UnityAds benutze (selbst das ist paar Jährchen her :D), aber ich habe vorladen lassen und dann angezeigt. Also dein Request finde ich auch merkwürdig. Da du Destroy beim Requesten tust. Das macht nicht so viel sinn, da beim Destroy eher darum geht, dass du Speicher freigibst. Also am besten dahin packen, wo man nicht mehr die Werbung sieht. Quasi nach Werbung wegklicken. Außerdem denke ich, dass aber Destroy nur nötig ist, wenn du gar nicht mehr anzeigen willst. Und ich gehe davon aus, dass man immer irgendwann anzeigen will und daher Destroy nicht gebraucht wird. Also im Prinzip solltest du einfach nur erst mal Initialisierung durchführen und laden (z.B. InterstitialAd und LoadAd). Das hab ich vor oder im Hauptmenü meistens gemacht. Und dann irgendwann im Spiel ShowRewarded, wo du die Werbung anzeigen willst.
  7. Also @malzbie Vorschlag sollte die roten Fehler nicht ändern, denn das hat ja was eher mit dem Build zu tun. Ich kann ja theoretisch für Mac auch programmieren und würde keine Fehlermeldung sehen. Tippe daher auch auf @Sascha's Vorschlag, denn die Library oder Temp erstellen diese Sachen und binden es beim Projekt ein. Kann sein, dass in dem Fall nichts neues erstellt werden musste und daher Fehler auftauchen. Zur not kann man auch in der Unity Einstellungen die Visual Studio Projekte neu erzeugen lassen. Ich weiß gerade nicht aus dem Kopf wo genau das war.
  8. Ist bissel her, aber ich würde es übers Netzwerk machen. Also einfach eine Konsolenanwendung schreiben, welches auch als Server dient. Wenn man Unity startet sollte es damit verbinden und die Daten runterladen.
  9. So wie das @Sascha macht, versuche ich es auch mittlerweile. Der Unterschied ist nur, dass ich eher andere Namen verwende: Game Units UnitName Scripts (je nachdem, ob sie personalisierte haben) Models Prefab Texture
  10. Moin ein Tipp zu der if abfrage. Du kannst das optimieren in dem du das so machst: if (collision.gameObject.TryGetComponent<HuasScript>(out HuasScript huasScript)) { id = huasScript.GebäudeId; } else if (collision.gameObject.TryGetComponent<FarmScript>(out FarmScript farmScript) { id = farmScript.GebäudeId; } Viel bessere wäre übrigens, dass du ein extra Component hast die Basics hat. Beispiel wäre ein Component namens BuildingData oder BuildingInfo passend und mit den Daten wie die ID oder so. Nun musst du EINMAL if (collision.gameObject.TryGetComponent<BuildingData>(out BuildingData buildingData)) { id = buildingData.GebäudeId; } abfragen und schon ersparst du die ganzen if abfragen.
  11. Kannst time.deltaTime benutzen oder FixedUpdate() benutzen. Update wird nämlich mehrmals aufgerufen und wird je FPS mal weniger ode rmehr sein FixedUpdate ist immer gleich.
  12. Lasse doch im Hauptmenü mit einem Script überprüfen, ob Cursor versteckt ist, wenn ja dann sichtbar machen. Das wäre die einfachste Lösung. EDIT: Also im Hauptmenü ist die Maus wieder da, aber ist in der Mitte fest?
  13. Mal ehrlich, würde dir helfen, aber ich hab keine Lust Dateien runterladen zu müssen um zu helfen.
  14. Wenn irgendwo "Draw" steht, geht es meistens um eine Zeichnung in einem Frame. Leider kenn ich mich da nicht aus, aber bei 100.000 Meshs kann ich auch verstehen, dass man da hohe GPU Auslastung hat. Sieht man die 100.000 wirklich gleichzeitig. Du kannst nämmlich vllt sowas wie Culling machen und nicht zeichnen, wenn man sie nicht sieht. Ansonsten nimm doch einfach gameObjects mit Meshs. Da macht das Unity bissel automatisch.
  15. Benutze einfach dafür DateTime. Das tut schon alles was du brauchst.
  16. Also so solltest du das nicht machen, denn das ist der falsche Weg. Die GameObject.Find ist nicht für solche Sachen gedacht. So wäre es richtiger public class BauController : MonoBehaviour { [SerializeField] Image icon; private GameObject goBildHolen; public void bildHolen() { goBildHolen = icon.gameObject; } } Jetzt kannst du den ImageComponent in das Feld Icon ziehen und damit arbeiten. Man braucht hier nicht mal goBildHolen. Man kann allein mit icon.gameObject arbeiten. Möchte man nicht selber reinziehen und es soll beim Start selbst finden lassen, dann geht es auch so public class BauController : MonoBehaviour { Image icon; private GameObject goBildHolen; void Awake() { icon = GetComponentInChildren<Image>(); } public void bildHolen() { goBildHolen = icon.gameObject; } } Wenn du jetzt wirklich kein Image in Script haben willst (warum auch immer) kannst du transform.Find("deinButtonMitImage").gameObject machen. Das würde aber bei dir nicht funktionieren, da du (warum auch immer XD), jedes mal anderen Namen hast. Dein Button sollte ca. so aufgebaut sein: Also etwas Allgemeiner halten. Und nicht
  17. Wieso willst du eigentlich Panels per PhotonNetwork.Instantiate spawnen? Es hört sich nach UI Sachen an und finde komisch, dass man UI-Prefabs über das Netzwerk erstellen will und nicht beim Client selber.
  18. Mein Fehler, hab an Spielerspawns wie beim Multiplayer gedacht
  19. Also wie @Sascha das schon ungefähr erwähnt hat, wenn du "perfektes" Spawnsystem benutzen willst, wo man nicht auf der selben stelle spawnst kannst du folgendes tun: Eine Liste mit Spawnpunkte, Eine Liste, wo du die Liste reinkopierst z.b. AvailableSpawns. Sagen wir mal es gibt A, B, C, D Spawnpunkte. Jetzt kannst du random aus AvailableSpawns ausziehen und wenn es bei 0 ankommt (also keine Spawns mehr) füllst du die liste wieder mit den Spawnpunkten. Somit kann es NIEMALS zu Fehlern kommen. Manche machen das ja gerne mit while Schleifen, was ich nicht empfehle, weil da das Programm bei Fehler hängen bleibt (spreche aus Erfahrung xD). Falls du auch oder nur überprüfen willst, ob ein Spieler auf ein Spawn noch ist und gar nicht weg ist, kann man das mit Boxcollider + ein Script halt überprüfen.
  20. EDIT: Ich editiere diesen Post bald, damit keine Verwirrung entsteht, da ich nochmal gelesen habe. Also ich muss sagen, was @Sascha gesagt hat ist schon richtig. Ich wollte früher sogar zu so einem Thema ein Video machen, aber kam nicht dazu, weil beim Erklären es sich etwas kompliziert anhört (da ich das per C# Console mache + Interface dazu zeige). Ein Beispiel aus dem eigentlichen Tutorial Code-Bespiel. Ich habe List<Item> inventory. Dort werden Sachen wie Weapon bzw. Sword, Bow und andere Dinge gepackt. Manche davon sind mit IRepairable, IDurability bestückt. Das heißt manche Items können nicht repariert werden. Beispiel Potions. In meinem Fall Bow lässt sich nicht reparieren, da es aus Holz ist. Das mit IRepairable können auch sogut wie Components sein (dazu unten mehr). Nun ich gehe zu einem NPC und möchte ich reparieren lassen. Was ich tue ich nun? IEnumerable<IRepairable> repairableItems = from item in inventory where item is IRepairable select (IRepairable)item; // get auch where item is IRepairable select item as IRepairable; foreach (var item in repairableItems) { item.Repair(); } Schon lassen sich alle Waffen reparieren. Das lustige ist, in item (also beim Interface) steckt aber auch noch die jeweilige Instance mit drin. Heißt man könnte in der Schleife folgendes tun (sollte man aber nie, da sie wirklich unabhängig arbeiten sollten) if(item is Sword sword) { // mache etwas geiles } Aber ich möchte aber ein Item reparieren lassen. Sagen wir aus dem Inventory die Nummer 1 wurde gewählt: IRepairable r = inventory[1] as IRepairable if(r != null) { r.Repair(); } Nun, das Beispiel oben lässt sich auch mit Unity arbeiten, wenn man für ein Item eher Components benutzt. Also quasi GameObject -> Component Sword -> Component Durability - Hält also nicht für immer -> Component Repairable - Kann also repariert werden (wird wohl mit Durbility zusammen arbeiten :D) zumindest mach ich das so. Dann geht folgendes. Repairable bla = null; IEnumerable<Repairable> repairableItems = from item in inventory where (bla = item.GetComponent<Repairable>()) != null select bla; oder einzeln: Repairable r = inventory[1].GetComponent<Repairable>() if(r != null) { r.Repair(); }
  21. Wenn du mit NetworkBehaviour arbeitest, dann kannst du [Command] und [ClientRpc] benutzen. Allerdings sind die eigentlich nur für die Playerobjekte gedacht. Das heißt, wenn man z.B. [ClientRpc] void RpcHealEffect() { HealEffect(); } Wenn der Server RpcKill ausführt, wird die Funktion bei jedem Spieler ausgeführt. [Command] void CmdHealAll() { // server checkt, ob er überhaupt lebt und mana dafür hat if( IsAlive && IsMana ) { // loop und heile alle Spieler ... // Macht, dass alle Spieler diesen HealEffekt sehen RpcHealEffect(); } } Der Client wiederum sendet Command an den Server. Jetzt bei Button ist das natürlich etwas doof, wenn es eigenen NetworkBehaviour hat auf dem Server. buttonScript.ButtonClick() würde z.b. nur bedingt funktionieren, weil Mirror sagt beim Command, dass der Client aus seinem Spielerobjekt (Script) ein Command sendet. In anderen Worten: Ein Client kann nicht ein Script eines anderen Clients manipulieren. Da müsste man komplizierter denken. Man kann aber mittlerweile bei Command(requireAuthority = false) machen um doch andere Scripts anzusprechen. Das könntest du machen. Bevor ich das tue empfehle ich dir eher was anders (vllt auch etwas komplizierter). Ich würde da eher Network Messages verwenden. https://mirror-networking.gitbook.io/docs/guides/communications/network-messages Wenn es nur darum geht, dass jeder den Token um eins erhöhen kann, dann einfach in dein Control-Script IncreaseTokenMessage machen ungefähr wie in dem Beispiel im Link. Später im ButtonScript musst du nur NetworkClient.Send machen. Wichtig ist nur hier zu achten, dass im Text RegisterHandler steht. Das geht nur einmal im gesamten Spiel (also für den Server einmal, und für jedes Spieler auch einmal). In anderen Worten, zwei mal RegisterHandler geht nicht.
  22. Das ist auch etwas, was mich bis heute stört. Leider ist Unity Editor nicht so aufgebaut, dass man mehrere Sceneviews in verschiedenen Fenstern sehen kann (hatte ich mal in einem Thread gelesen). Beispiel Godot oder Unreal Engine können das. Man kann dort parallel damit arbeiten. Theoretisch hätte ich dann so gemacht. Sceneview Fenster 1 nur UI anzeigen. Sceneview Fenster 2, UI ausblenden und sonst alles anzeigen. In anderen Worten Layer Button oben rechts müsste pro Sceneview Fenster sein. Ich hab sogar ein Script geschrieben um die Layers zu togglen, wenn ich z.B. zwischen den Fenstern switche, aber es schlägt ab und zu fehl, weil die Kamera layers von der Scenenview die Werte vom Editor ablesen und überschreiben. Deswegen hab ich dann nicht mehr verwendet. Einzige was ich mache ist nun, dass ich zwei Fenster öffne um bei einem da UI Sachen zu machen und bei anderen blende ich es weg und arbeite an der Welt. Wenigstens muss ich da nicht mit der Kamera hin und her gehen. Alternative geht auch Canvas in World Space ganz weit weg und Layers einstellen.
  23. @gomboloDas ist zum Teil richtig. Man möchte ja zu einem Punkt fliegen lassen und nicht verfolgen. Und ja irgendwann zerstören. Timer braucht man nicht. Es gibt ja Invoke und wenn man gar keine Effekte haben will Destroy Naja ich hab dir auch nur eine Richtung gegeben und nicht die Komplettlösung. Ich mag es tatsächlich nicht komplette Lösung vorgeben, weil man dadurch nicht lernt. Das ist so wie als würde dir ein Lehrer Rechenweg zeigen, obwohl man das selber lösen soll. Du brauchst paar Dinge um das zu Lösen. private Vector3 moveDirection; wohin es fliegen soll private float killAfterSeconds = 5f; da es ja vllt nie etwas trifft, solle es auch irgendwann verschwinden Invoke() und dazu die Kill-Funktion um ja das Ding irgendwann zu zerstören. Man kann auch Destroy mit delay rein tun also Destroy(gameObject, 3f) für nach 3 Sekunden zerstören, aber da kann man keine Effekte einbauen wie die Explosion. Darum Invoke. void Awake () { Player = GameObject.FindGameObjectWithTag ("Player"); targetedPlayer = Player.transform; moveDirection = (targetedPlayer.position - transform.position).normalized; Invoke(nameof(Kill), killAfterSeconds); } void Update () { float step = MagicSpeed * Time.deltaTime; transform.position = transform.Translate(moveDirection * step); } void Kill() { Destroy(gameObject); } void OnCollisionEnter(Collision collision) { Instantiate (this.Explode, this.SpawnPoint.transform.position, this.SpawnPoint.transform.rotation ); Destroy(gameObject) ; }
  24. Verstehst du überhaupt dein Code? Wenn nicht lieber noch etwas mehr lernen, weil es einfach zu den simpelsten Sachen gehört. Wenn man auf https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html geht sieht man in der Beschreibung, dass es eine Akuelle- und Zielposition haben möchte. Ja das heißt, dass es in die Richtung zum Ziel bewegt. Hmm? Wie kann man das ändern? Genau die Zeile weg nehmen :D. Aber was würde dann passieren? Es würde nicht mehr weiter fliegen. Mal als Hilfestellung, hier würde https://docs.unity3d.com/ScriptReference/Transform.Translate.html gut passen. z.B. transform.Translate((targetedPlayer.position - transform.position).normalized * step);
  25. funktioniert leider nicht War Kurzform: Also genauer gesagt ist es: pos + direction * length. Also: currPosition + dir.normalized * 60. dir.normalized * 60 ist natürlich von 0 Punkt aus. Gibst du die Position dazu hast du relativ zu deinem Punkt die Verschiebung. Wenn die 60 aber keine Konstante ist sondern, du willst immer zu jeder Distanz -20. Dann statt 60 dir.magnitude - 20 oder Vector3.Distance(currPosition, goalPosition) - 20 rechnen. Also: var realPosition = currPosition + dir.normalized * (dir.magnitude - 20) // oder var realPosition = currPosition + dir.normalized * (Vector3.distance(currPosition, goalPosition) - 20)
×
×
  • Create New...