Jump to content
Unity Insider Forum

MaZy

Members
  • Posts

    659
  • Joined

  • Last visited

  • Days Won

    27

MaZy last won the day on April 16

MaZy had the most liked content!

About MaZy

  • Birthday 02/20/1988

Profile Information

  • Gender
    Male
  • Location
    Hannover

Recent Profile Visitors

22,193 profile views

MaZy's Achievements

Advanced Member

Advanced Member (3/3)

183

Reputation

  1. 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
  2. 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.
  3. 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.
  4. 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?
  5. Mal ehrlich, würde dir helfen, aber ich hab keine Lust Dateien runterladen zu müssen um zu helfen.
  6. 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.
  7. Benutze einfach dafür DateTime. Das tut schon alles was du brauchst.
  8. 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
  9. 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.
  10. Mein Fehler, hab an Spielerspawns wie beim Multiplayer gedacht
  11. 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.
  12. 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(); }
  13. 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.
  14. 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.
  15. @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) ; }
×
×
  • Create New...