Jump to content
Unity Insider Forum

Antragon

Members
  • Content count

    13
  • Joined

  • Last visited

Community Reputation

1 Neutral

About Antragon

  • Rank
    Member

Recent Profile Visitors

488 profile views
  1. Antragon

    Sprite Shader- Color Tint

    Moin moin, Ich brauche einen Shader für Sprites, welcher Schatten erzeugen und "empfangen" kann. Nach ein wenig Internet-Recherche habe ich einen Shader gefunden, der genau das macht- Allerdings kann ich mit diesem Shader nicht mehr die Sprites einfärben (siehe Bild). Könnte mir jemand den folgenden Shader-Code so anpassen, dass das mit der Farbe funktioniert? Shader "Sprites/Beat/Diffuse-Shadow" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) _Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.5 } SubShader { Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } LOD 200 Cull Off Lighting On ZWrite Off CGPROGRAM #pragma surface surf Lambert addshadow alphatest:_Cutoff sampler2D _MainTex; fixed4 _Color; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } Fallback "Legacy Shaders/Transparent/Cutout/VertexLit" } PS: Ich habe mich versucht, in das Thema Shader reinzuarbeiten, konnte bisher aber noch bei keinem Tutorial den Code nachvollziehen.
  2. Antragon

    Mathematik / Formel / Funktionsfrage

    Sieht mir eher nach ner Hyperbel aus: http://www.nachhilfe-karrer.de/mathematische-begriffe-und-definitionen/hyperbel/ Die Gleichung davon rauszufinden, ist aber nicht ohne- und du bräuchtest noch einen vierten Punkt. Alternativ würde ich dir einen gesplittet linearen Ansatz vorschlagen: void Start() { print("x=25; y="+Function(25)); print("x=115; y="+Function(115)); print("x=255; y="+Function(255)); } float Function(float x) { float m; float n; if(x<=115) { m=-0.05f; n=6.75f; } else { m=-1f/280f; n=79f/56f; } return m*x+n; } Zumindest kommst du damit auf die exakten Werte. Allerdings würde sich deine Skalierung für x<=115 deutlich stärker ändern als für x>115. Wenn du da lieber einen sanfteren Übergang haben willst und dir die exakte Skalierung bei x=25 und x=255 nicht so wichtig ist, nimmt stattdessen einfach 115/x als Formel.
  3. Antragon

    Player sliden lassen

    Eine recht simple Möglichkeit wäre folgende: using UnityEngine; public class PlayerSlide : MonoBehaviour { float veloX=0; float timer=0; float direction=1; //Inspector values public float power=5; public float timeTillBreak=1; void Update() { Push(); } void FixedUpdate() { Slide(direction); } void Push() { if(Input.GetKeyDown(KeyCode.E)) { veloX=power; timer=timeTillBreak; direction=1; } else if(Input.GetKeyDown(KeyCode.Q)) { veloX=power; timer=timeTillBreak; direction=-1; } } void Slide(float direction) { if(timer>0) { Vector3 pos=transform.position; transform.position=new Vector3(Mathf.MoveTowards(pos.x, pos.x+direction, veloX*Time.deltaTime), pos.y, 0); timer-=Time.deltaTime; veloX=Mathf.Lerp(0, power, timer); } } } Das hängt natürlich davon ab, was dein Player noch alles können soll und in welchem Kontext der Slide auftritt. Wenn du beispielsweise kontrollieren möchtest, welche Strecke beim Slide zurückgelegt werden soll, würde ich das eher mit Mathf.Lerp als Mathf.MoveTowards umsetzen. Aber zumindest müsstest du die beiden Methoden erweitern können.
  4. Antragon

    Camera Store Old Position

    Wenn ich es richtig verstehe, willst du von einer starren Frontperspektive in eine bewegliche Vogelperspektive wechseln. Hilft dir da der folgende Code weiter? Das ganze basiert auf einer Kombination aus IEnumerator und Vector3.Lerp. Die Kamerabewegung habe ich noch nicht reinprogrammiert, aber das funktioniert ja auch schon bei dir. using System.Collections; using UnityEngine; public class CameraController : MonoBehaviour { Transform cam; Vector3 positionStart; Vector3 rotationEulerStart; //Wird im Inspektor festgelegt public Vector3 positionFreeCam; public Vector3 rotationEulerFreeCam; Vector3 positionBeforeSwitch; Vector3 rotationEulerBeforeSwitch; float timer; public float switchDuration=1; bool freeCamEnabled=false; bool blockswitch=false; void Start() { cam=Camera.main.transform; positionStart=cam.position; rotationEulerStart=cam.rotation.eulerAngles; } void Update() { if(Input.GetKeyDown(KeyCode.M) && !blockswitch) { if(freeCamEnabled) { //Wechsel auf Ausgangsposition freeCamEnabled=false; positionFreeCam=cam.position; rotationEulerFreeCam=cam.eulerAngles; StartCoroutine(SwitchPosition(positionStart, rotationEulerStart)); } else { //Wechsel auf Vogelperspektive freeCamEnabled=true; StartCoroutine(SwitchPosition(positionFreeCam, rotationEulerFreeCam)); } } if(freeCamEnabled) { //Camera Bewegung und scrolling kommt hier rein } } IEnumerator SwitchPosition(Vector3 position, Vector3 rotationEuler) { timer=0; blockswitch=true; positionBeforeSwitch=cam.position; rotationEulerBeforeSwitch=cam.eulerAngles; //IEnumerator bewegt die Camera so lange, bis das Ziel erreicht ist while(timer<switchDuration) { timer+=Time.deltaTime; timer=Mathf.Min(timer, 1); cam.position=Vector3.Lerp(positionBeforeSwitch, position, timer/switchDuration); cam.eulerAngles=Vector3.Lerp(rotationEulerBeforeSwitch, rotationEuler, timer/switchDuration); yield return null; } blockswitch=false; } } So sieht es dann aus: bandicam 2017-12-14 06-19-11-227.mp4 Zwei kleine Tipps noch: 1. Wenn du willst, das bestimmte Sachen nur einmalig bei Spielbeginn ausgeführt werden sollen (z.B. Player = GameObject.FindWithTag("Player"), dann ruf das besser in der Start()- oder Awake()-Methode auf. 2. Bei Rotation ist es meist sinnvoller und einfacher mit transform.eulerAngles zu arbeiten als mit transform.rotation. Da werden dir nämlich direkt die Werte aus dem Inspektor zurückgegeben.
  5. Antragon

    Leveleditor mit Sprites und deren Priorität

    Wir sind ja bereits an dem Punkt mit den Spezialkonstellationen. Nur würde ich diese gerne vermeiden, denn je mehr Diversität es an Sprites im Editor gibt, desto komplizierter wird es. Ich hatte daher gehofft, eine allgemeine Lösung für alle möglichen Konstellationen zu finden (soll heißen, eine Formel, womit ich die sortingOrder immer passend festlegen kann). Am liebsten wäre mir eine Möglichkeit, die Render-Reihenfolge zwischen zwei genau Sprites festlegen zu können. Ähnlich wie Physics.IgnoreCollision(col1, col2) wäre eine Unity-interne Funktion "SpriteRenderer.PrioritizeSprite(sprite1, sprite2)" toll, womit festgelegt würde, dass sprite1 vor sprite2 liegt. Aber das ist wohl nur Wunschdenken. Dass man die Transparency Axis festlegen kann, wusste ich noch nicht. Das wird vermutlich noch nicht das Hauptproblem lösen, aber sicherlich einiges vereinfachen- danke also dafür!
  6. Antragon

    Leveleditor mit Sprites und deren Priorität

    @Zer0Cool: Genau das ist im Endeffekt mein Vorhaben. Aktuell lass ich die platzierten Sprites erkennen, welche Sachen drumherum liegen. Auf dieser Basis könnte dann der Wert sortingOrder im SpriteRenderer festgelegt werden. Nur hapert es genau an dieser Stelle. Hier mal der (sehr abgespeckte) Code: Vector2 gridSize=new Vector2(80, 80); Dictionary<Vector2,GameObject> gridTiles=new Dictionary<Vector2, GameObject>(); void Awake() { for(int y=0; y<=gridSize-1; y++) { for(int x=0; x<=gridSize-1; x++) { gridTiles.Add(new Vector2(x, y), null); } } } public void CreateTile(Vector2 gridPosition, Texture2D tex) { //Eine Einheit im Raster sind 80 pixel; Jeder Sprite hat weitere 80 Pixel als Überhang //Beispiel: eine 2x2-Kiste hat einen 160 Pixel breiten und 160 Pixel hohen Collider und 80 Pixel zusätzlich auf jeder Seite; die Textur ist also 320x320 Pixel groß Vector2 spriteSize=new Vector2(tex.width, tex.height); Vector2 spriteDimension=spriteSize/80-2; //Erstelle GO und schiebe an korrekte Position GameObject tile=new GameObject(tex.name); tile.transform.localPosition=gridPosition; //Die Funktion "GetAdjacentTiles" schaut im Dictionary gridTiles nach allen angrenzenden Objekten und gibt zurück: //- welches Objekt grenzt an (Key-Wert) //- von welcher Seite grenzt es an (Value-Wert, kann "L"[eft], "R"[ight], "U"[p], "D"[own] sein Dictionary<GameObject,string> adjacentTiles=GetAdjacentTiles(tile); int minPriority=-999; int maxPriority=999; foreach(KeyValuePair<GameObject,string> adjacentTile in adjacentTiles) { //Information über Render-Priorität/Sorting Order des benachbarten Sprites erhalten (ist immer im ersten Child); int priority=adjacentTile.Key.transform.GetChild(0).GetComponent<SpriteRenderer>().sortingOrder; if(adjacentTile.Value=="L" || adjacentTile=="D") minPriority=Mathf.Max(priority, minPriority); else if(adjacentTile.Value=="R" || adjacentTile.Value=="U") maxPriority=Mathf.Min(priority, maxPriority); } SpriteRenderer spriteR; //Erstelle für jedes Raster-Element, welches das Sprite belegt, ein eigenes GO und fülle gridTiles mit dieser Info for(int x=0; x<=spriteDimension.x-1; x++) { for(int y=0; y<=spriteDimension.y-1; y++) { GameObject box=new GameObject("Box", typeof(SpriteRenderer)); box.transform.parent=tile.transform; box.transform.localPosition=new Vector2(x, y); gridTiles[new Vector2(gridPosition.x+x, gridPosition.y+y)]=box; if(x==0 && y==0) { //Erstelle den Sprite für das Child-Objekt links unten spriteR=box.GetComponent<SpriteRenderer>(); spriteR.sprite=Sprite.Create(tex, new Rect(0, 0, spriteSize.x, spriteSize.y), new Vector2(80/spriteSize.x, 80/spriteSize.y), //Pivot 80); /* Hier ist das Problem: Es gilt einen Wert für Sorting Order zu finden, welcher: - größer als minPriority und - kleiner als maxPriority ist. spriteR.sortingOrder=????? */ } } } } Die Sorting Order muss halt so festgelegt werden, dass Sprites auch in komplexeren Strukturen wie zum Beispiel im folgenden Bild korrekt dargestellt werden - egal in welcher Reihenfolge Sprites platziert, gelöscht und/oder neu gesetzt werden. @Sascha: So einen ähnlichen Versuch gab es ja bereits; da habe ich beispielsweise 2x2-Kisten in vier einzelne Sprites aufgeteilt. Bei so einem Sprite ist die linke obere Ecke immer hinten und die rechte untere Ecke immer vorn. Allerdings wird beispielsweise die Ecke rechts oben von Objekten darüber verdeckt, während sie aber Objekte rechts daneben selbst verdeckt. Mal ne andere Frage in die Runde: Gibt es denn eine Möglichkeit, Unity direkt zu sagen, dass ein Sprite immer hinter oder vor einem anderen Sprite gerendert werden soll, ohne auf die sortingOrder/sortingLayer/z-Achse zurückzugreifen?
  7. Antragon

    Leveleditor mit Sprites und deren Priorität

    Bei mir wird das Bild unten am Post ganz groß dargestellt? Der verlinkte Thread ist an sich irrelevant, entschuldige bitte die Verwirrung. Hinsichtlich deines Vorschlags habe ich das Problem, dass es immer nur eine "wahre" Darstellung der Sprites gibt. Unten habe ich nochmal ein Bild mit den tatsächlich für das Spiel benutzten Sprites hinzugefügt: Jede Kiste ist ein eigener Sprite und die linke Kiste muss immer eine höhere Priorität haben als die rechte, unabhängig von der Platzierungsreihenfolge. Wenn man als Levelbauer dann aber noch anfangen muss >100 Sprites pro Level händisch zu sortieren, geht der Spaß schnell flöten.
  8. Hallöchen Leute, Ich arbeite zur Zeit an dem rasterbasiertem LevelEditor für Lucy Lamplight: Ein Aufhänger ist leider immer wieder die Priorität der Sprites beim Überlappen. Ich versuche mal die Bauteile anhand des angehängten Bilds zu erklären: - jeder Sprite besteht aus einem Box-Collider und einem Überhang - der Collider richtet sich nach dem Raster (es gibt zum Beispiel (BxH): 1x1, 2x1, 1x2 und 2x2 große Collider, aber nicht 1.3x0.5 o.ä.) - der Überhang ragt in die benachbarten Raster-Teile herein und kann eine Breite von 0-1 haben (aber nie größer als 1) Betrachtet man im angehängten Bild den roten Sprite, hat dieser einen 2x2-Collider und ein wenig Überhang auf jeder Seite. Wie ihr auch seht, wird der rote Sprite von grünen, zweifeldergroßen Sprites überlappt. Die Regeln für die Überlappung sollen sein: 1.) Ist die untere Kante von Sprite A auf der gleichen Horizontalen Ebene wie die obere Kante von Sprite B, so soll Sprite A eine höhere Priorität haben 2.) (Falls 1. nicht gilt) Ist die rechte Kante von Sprite A auf der gleichen Vertikalen Ebene wie die linke Kante von Sprite B, so soll Sprite A eine höhere Priorität haben Es gibt auch Ausnahmefälle, bei denen die zweite Regel für Sprite A umgekehrt wird. Im unteren Bild wäre der blaue Sprite eine solche Ausnahme. Fehlgeschlagene Versuche Die Grundidee ist recht einfach: Priorität=position.y - position.x (Bei der Position gehe ich immer von der linken unteren Ecke des Sprites aus.) Dass das ganze nicht klappt sieht man schon am Beispiel-Bild: Ausgehend davon, dass der rote Sprites beispielsweise eine Priorität von 0 hat, würde der grüne Sprite links unten eine Priorität von 1 haben (also darüber liegen), was nach obiger Regel falsch wäre. Dass das ganze für den blauen Sprite nicht funktioniert, liegt hoffentlich auf der Hand. Eine bessere Idee wäre folgende: Normale Sprites (rot, grün): Priorität=position.y*rastergröße.x - position.x + 1 Blaue Sprites: Priorität=position.y*rastergröße.x Dadurch hätten automatisch alle Sprites mit höher y-Position eine höhere Priorität als alle anderen. Dumm ist nur: Der rote Sprite hat eine niedrigere Position als der grüne Sprite rechts oben; da hier aber Regel 1 nicht greift, muss Regel 2 angewendet werden und er soll den grünen Sprite stattdesse überdecken. Es gab auch viele Versuche Sprites zu splitten, wobei jeder Teil-Sprite eine eigene Priorität bekommen hat. Ein 2x2-Sprite wurde beispielsweise in 4 Einzelsprites zerlegt. Ohne zu weit ausschweifen zu wollen: Nichts hat so richtig funktioniert. Der Lösungsansatz Daher möchte ich eine andere Herangehensweise versuchen: In der Theorie könnte man erst alle Sprites platzieren und ihnen dann händisch Prioritäten zuweisen, bis alles so passt, wie man es haben will. Ein ähnliches Verfahren möchte ich auch programmieren: Sobald ein Sprite platziert wird, werden die Sprites in der Umgebung gecheckt und dann allen beteiligten Sprites Prioritäten vergeben, bis alles passt. Die benachbarten Sprites zu erkennen, ist kein großes Problem. Problematisch wird es, zu identifizieren, welche Prioritäten ich ihnen zuweisen muss. Ich denke, es wäre am sinnvollsten, wenn man den Sprites beim Platzieren schonmal Grund-Prioritäten wie oben zuweist: Priorität=position.y - position.x Anschließend werden in Abhängigkeit von der Umgebung die Prioritäten erhöht oder gesenkt. Hierfür muss ein logischer Algorithmus her. Bevor ich mich jetzt aber dumm und dusselig probiere, wollte ich hier im Forum fragen, ob irgendjemand eine Idee oder einen Ansatz für sowas hat? Oder denke ich viel zu kompliziert und es gibt eine viel viel trivialere Lösung für das Ganze? Ich hoffe, ich konnte das Problem einigermaßen vermitteln und würde mich echt freuen, falls irgendwer hier eine rettende Idee parat hat!
  9. Antragon

    Charakterwechsel durch (De)Aktivierung von Scripts

    Aaah, endlich hat's Klick bei mir gemacht. Das eröffnet mir ja vollkommen neue Möglichkeiten! :-D Besten Dank euch beiden!
  10. Antragon

    Charakterwechsel durch (De)Aktivierung von Scripts

    Hi, ich weiß in etwa wie Vererbung funktioniert, allerdings glaube ich, ich kann dir nicht ganz folgen. Wenn ich einem Charakter sowohl PlayerControlBase als auch das spezifische Script (PlayerControlWarrior/PlayerControlMage) zuweise, aber nur PlayerControlBase aktiviere und deaktiviere, dann ändert das doch nichts an der Funktionalität der anderen Scripts?
  11. Hallöchen, Ich grüble derzeit an einem Problem hinsichtlich der Aktivierung und Deaktivierung von Script-Komponenten. Im Endeffekt versuche ich zwischen verschiedenen Charakteren auf Knopfdruck Hin- und Herzuwechseln; dabei soll immer nur einer vom Spieler gesteuert werden, während die anderen ihrer KI folgen. Pro Charakter gibt es jeweils ein Script für die Spielersteuerung und eines für die KI. Meine Idee: Übernimmt man die Kontrolle über einen Charakter, wird sein Steuerungsscript aktiviert und sein KI-Script deaktiviert. Problem an der ganzen Sache: Die Charaktere sind verschiedenen und brauchen dementsprechend verschiedene Scripts. Beispielsweise heißt das Steuerungsscript des Kriegers "PlayerControlWarrior" und das des Magiers "PlayerControlMage". Ich kann also nicht einfach sagen GetComponent<PlayerControl>().enabled=false. Mir fielen zwar ein paar Lösungen ein, das ganze über Umwege zu erreichen (Child-Object, welches die entsprechenden Scripte beinhält, das man dann aktvieren und deaktvieren kann; oder Referenzen auf die Scripte), allerdings finde diese Herangehensweisen eher unschön und habe das Gefühl, dass das doch einfacher gehen muss. Jetzt ist meine generelle Frage: Ist meine Herangehensweise falsch? Gibt es elegantere Lösungen für mein Problem?
  12. Antragon

    Suchfunktion defekt

    Ach, na dann frag ich ja genau zur richtigen Zeit. :-D Dann mal viel Erfolg dass morgen alles klappt!
  13. Antragon

    Suchfunktion defekt

    Halloechen, wenn ich die Suchfunktion hier nutze, krieg ich nur die Anzahl der Treffer angezeigt, aber nicht die Treffer an sich, siehe hier: Ist das ein Bug oder ein unheimlich unnuetzes Feature? Und wenn ersteres, kann mir jemand sagen, woran das liegen kann? Weiss nicht, ob das weiterhilft, aber wenn ich ein Thema starte, steht bei mir ganz oben im Header auch eine recht merkwuerdige Meldung, wie hier zu sehen: PS: Ich nutze Firefox, aber mit dem Internet Explorer krieg ich die gleichen Fehler.
×