Jump to content
Unity Insider Forum

Suche Hilfe


Juggernaut92

Recommended Posts

Hallo , ich bin ein einsteiger in unity  

Kenn mich schon ein wenig mit Unity 2017 aus aber programmieren kann ich leider noch nicht 

Also ich würde gerne einen kreis programmieren für meine map der random spawnt und nach einer gewissen zeit kleiner wird  und die spieler die nicht im kreis sind einen leicht schaden bekommen  und je kleiner der kreis desto mehr damage      Wie im spiel battlegrounds playerunknown

also ich möchte das mir jemand vl helfen kann oder gar programmieren kann was mir eigentlich lieber ist , natürlich würde ich für dieses script bezahlen bzw denjenigen für seine zeit entschädigen 

Hab auch schon 4 bücher gekauft für unity aber da steht nichts davon drinnen     Würde mich sehr freuen wen das jemand für mich machen könnte   

MFG Unity Noob      

 

und keine blöden kommentare wie lern doch selbst usw .. Jeder fängt mal klein an 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich werde dir hier kein komplett fertiges Skript schreiben, aber ich kann dir einen einfachen Lösungsweg geben.
1) Du platzierst einen Zylinder in deiner Szene.
2) Du drückst diesen Zylinder "platt", indem du seinen "Scale" in "Y" zum Beispiel auf "0.01" setzt.
3) Du setzt den Collider des Zylinders auf "Is Trigger".
4) Cylindertrigger-Klasse dem Zylinder hinzufügen.
5) Du machst aus dem Zylinder ein Prefab, indem du ihn in dein Projektfenster ziehst.
6) Im Spiel lässt du nun diesen Zylinder spawnen und setzt ihn auf die gewünschte Position:
https://docs.unity3d.com/Manual/InstantiatingPrefabs.htm
7) Du setzt einen Startumfang, indem du den local Scale des gespawnten Zylinders setzt.
8) Du verkleinerst den Umfang des Zylinders schrittweise.
9) Du prüfst, ob sich Spieler innerhalb des Zylinders befinden mit OnTriggerStay(), wann ja, dann bekommen sie Schaden.
10) Die Spieler brauchen einen RB und einen Collider damit die Kollision erkannt wird.
11) Die Spieler brauchen eine "Health"-Componente (also Klasse).

Ich habe nun doch mal ein Skript gemacht, es setzt bereits die Schritte 1-9 um.
Den 9 Schritt habe ich im unteren Skript angedeutet, deine Player die im Kreis stehen brauchen zusätzlich eine Health-Klasse. Diese Klasse hat dann eine Methode um Schaden zuzufügen. So Zeit verbraucht 30 Minuten (inklusive Test und Syntaxfixing) :)

using UnityEngine;
using System.Collections;

//
// Copyright (c) 2017,  by zer0f0rce (skype) for the Unity Insider Forum.
//
public class VoidZone : MonoBehaviour
{
    public GameObject cylinderPrefab; // Flattened cylinder prefab + void zone trigger
    public Transform startPosition; // Void zone start position
    public float startCircleSize = 10f; // Void zone start size
    public float circleStep = 1.0f; // Circle step 
    public float reduceTimeStep = 2.0f; // Time to downsize
    private float currentCirceSize;
    private GameObject zylinderClone;

    void Start()
    {
        Vector3 startPos = startPosition.position;
        zylinderClone = (GameObject)Instantiate(cylinderPrefab, startPos, Quaternion.identity);
        zylinderClone.transform.localScale = new Vector3(startCircleSize, zylinderClone.transform.localScale.y, startCircleSize);
        currentCirceSize = startCircleSize;

        InvokeRepeating("ReduceCircleSize", reduceTimeStep, reduceTimeStep);
    }

    void ReduceCircleSize()
    {
        print("Executing ReduceCircleSize()");
        currentCirceSize -= circleStep;
        zylinderClone.transform.localScale = new Vector3(currentCirceSize, zylinderClone.transform.localScale.y, currentCirceSize);
        if (currentCirceSize < circleStep) CancelInvoke();
    }
}


Das Zylinderprefab braucht eine eigene Klasse für die Kollisionserkennung:

using UnityEngine;
using System.Collections;

public class VoidZoneTrigger : MonoBehaviour {

    void OnTriggerStay(Collider other)
    {
        if (other.gameObject.tag == "Player") {
            PlayerHealth health = other.GetComponentInParent<PlayerHealth>();
 
            if (health != null) {
                print("Damage to " + other.gameObject.name);
                health.removeHealth(1);
                Debug.Log("Player is drowning");
            }
        }
    }
}


Ich merke gerade, bei mir bekommen alle Spieler im Kreis Schaden. Aber du kannst die Mechanik leicht umdrehen. Alle Spieler die über den Trigger detektiert werden sind "save". Alle Spieler die nicht "save" sind bekommen Schaden.

Ich habe gerade noch eine einfach Healthklasse ausgegraben, also kann ich sie hier auch noch anführen.

public class PlayerHealth : MonoBehaviour {
    public float startingHealth = 100f;
    public float currentHealth;
 
    void Awake() {
        currentHealth = startingHealth;
    }
  
    public void removeHealth(float amount) {
        currentHealth -= amount;
        if (currentHealth <= 0f) {
            Destroy(gameObject);
        }                               
    }
}


PS:
Alternativ kann man dem Zylinderprefab auch den Capsulecollider wegnehmen und durch einen Meshcollider ersetzen, dann wird die Kollisionserkennung genauer. Aktuell wird alles detektiert, was sich in der Hemisphäre über und unter dem Kreis befindet.
Verkleinert wird der Kreis aktuell alle 2 Sekunden (2.0f). Du kannst diesen Float ebenfalls noch als "public" Variable des Skriptes herausziehen.

Das vorgestellte Skript eignet sich gut für eine Bossmechanik (sog. Void zones), wenn es jemand verwendet würde ich mich über "Credits" freuen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich persönlich verlasse mich nicht gerne auf Unitys Physikengine..

Zer0Cool`s Ansatz wird natürlich trotzdem 1A funktionieren ^^  ( kann es sein, dass der Player bei dir Schaden bekommt, wenn er innerhalb des Kreises ist? in Battle Royal ist das eigentlich genau andersrum :D )

 

Ich würde..

.. eine 'GameBorder' ( o.Ä. ) Klasse erstellen, die den Mittelpunkt und Radius des Kreises speichert und eine Liste mit allen Spielern hat

.. dieser Klasse eine 'Tick' Methode geben, die alle X-Sekunden aufgerufen wird und überprüft, welche Spieler innerhalb/außerhalb des Radius sind, und ggf. Schaden zufügt

.. dieser Klasse eine Methode geben, die periodisch den Radius verkleinert

( der Code ist sehr ähnlich zu Zer0Cool`s nur eben ohne Unitys Physikengine zu benutzen .. )

 

Ich weiß nicht, wie tief sich deine Bücher mit C# befasst haben, aber wenn du das große Problem in viele kleine Teilprobleme aufteilst, sollte es nicht all zu schwer sein.

Und wenn es irgendwo nicht weiter geht, kannst du hier fragen..

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, meine Klasse ist eine "herkömmliche" "Voidzone" (hatte erst nich gründlich die Anforderung gelesen^^), aber man kann wie gesagt die Mechanik einfach umdrehen und alle Spieler innerhalb der Voidzone als "save" markieren (innerhalb der OnTriggerStay-Methode) und alle anderen Spieler die nicht markiert sind bekommen dann Schaden verpasst.

Guter Einwand, es geht natürlich auch ohne Physikengine und damit ist es bestimmt auch performanter. Aber da man die Voidzone ja auch sehen können soll, hatte ich meinen Ansatz auf einem Mesh basiert. Aber wenn auch Spieler "save" sein sollen, die die Voidzone nur "ankratzen", dann kommt man fast wieder nicht um einen Collider herum, weil dann wird die Berechnung zwischen Playermesh (bzw. dem Playercapsulecollider) und einem Kreis schon wieder deutlich komplexer. Wobei man hier auch wieder mit der Boundingbox des Meshes oder des Playercolliders arbeiten könnte.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 4 weeks later...

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...