Jump to content
Unity Insider Forum

Mr 3d

Members
  • Content Count

    680
  • Joined

  • Last visited

  • Days Won

    28

Mr 3d last won the day on June 2

Mr 3d had the most liked content!

Community Reputation

149 Excellent

About Mr 3d

  • Rank
    Christian
  • Birthday 12/09/1999

Profile Information

  • Gender
    Male
  • Location
    Bayern

Recent Profile Visitors

6,996 profile views
  1. Schau mal oben mittig im 'Game' Fenster, ob der 'Scale' Slider auf 1x steht..
  2. Hi, ich habe in den letzten zwei Jahren immer wieder an einem Flüssigkeit Simulations Shader gearbeitet und seit Mitte letzten Monats ist er jetzt im AssetStore erhältlich. Mit Fluid Flow kann man in Echtzeit simulieren wie beispielsweise Blut oder Farbe an einer Oberfläche herunter fließt. Es ist keine 100% physikalisch korrekte Simulation, sondern das Asset versucht mit möglichst geringen Performance Einbußen überzeugend Flüssigkeit zu simulieren. Dazu werden die Berechnungen mithilfe eines Compute Shaders auf die Grafikkarte ausgelagert. Compute Shader benötigen allerdings mindestens DirectX 11 oder OpenGL 4.3 support! Zudem sind Android und iOS momentan nicht unterstützt! Fluid Flow Echtzeit Flüssigkeit Simulation dynamisches Anpassen der Flussrichtung unterstützt animierte Objekte Tropfen* * werden asynchron von der GPU zur CPU gelesen. Dieses Feature gibt es erst seit Unity 2018.2, und mit OpenGL wird es nicht unterstützt! Demo (win): https://drive.google.com/drive/folders/1ewcJn2Cc56Pcg3IVXPgvDDYucfRrU2mg Asset Store: https://assetstore.unity.com/packages/vfx/shaders/fluid-flow-143786
  3. Im 'Game' Fenster ist oben ein 'Scale' Slider. Wenn du den auf 1 stellst müsste alles wieder normal sein..
  4. Hi, ich glaube er meinte das etwas anders. Wenn ich dich richtig verstanden habe, willst du, dass sich der Ball die ganze Zeit bewegt und jedes mal, wenn die Leertaste gedrückt wird, sich die Richtung ändert. Das kannst du so umsetzen, dass du immer die aktuelle Richtung speicherst und beim Tastendruck den Wert umkehrst. Also etwa so: int direction = 1; void Update(){ if(Input.GetKeyDown(KeyCode.Space)){ direction *= -1; } if(direction > 0){ //move right } else{ //move left } }
  5. Ich hab mich vor paar Jahren mal etwas mit dem Thema beschäftigt. Das kam dabei raus, falls es dich interessiert (Achtung Werbung ^^) https://assetstore.unity.com/packages/tools/physics/bullet-ballistics-72755 Jede Kugel hat alle wichtigen Daten: Position, Flugrichtung, Geschwindigkeit, Durchmesser, Luftwiderstand etc. Und dann jeden Update unter Einfluss von Gravitation, Luftwiderstand, usw. die neue Position berechnen und mit einem Raycast testen, ob es zu einer Kollision kommt. Je nachdem mit welchen Material kollidiert wird, wird die Kugel gestoppt, prallt ab, oder fliegt auf der anderen Seite gebremst weiter.
  6. Du speicherst die werte unter "theme_name"+i lädst dann aber nur "theme_name" /edit Und 'Themes Count' war oben im screenshot 0, wenn du das noch nicht geändert hast..
  7. Habs kurz gegoogelt und das hier gefunden, falls dich interessiert, warum es kein Cylinder Collider gibt.. https://forum.unity.com/threads/why-cylinder-collider-doesnt-exist.63967/#post-408699
  8. Über eine Millionen Tris sind für ein Smartphone Spiel viel zu viel, erst recht für eine VR Anwendung.. Besonders, weil deine Objekte im Screenshot nicht sehr highpoly aussehen. Ich schätze dein Roboterarm macht davon einen großen Teil aus. Ist nicht ganz mein Gebiet, aber ich glaube ~2,5k Batches sind auch sehr viel. Wenn du mal nach "unity batches reduzieren" googelst, solltest du einiges finden, wie du die reduzieren kannst.
  9. Hi, du kannst dir mit 'Quaternion.Euler(x, y, z)' deine eulerische Rotiation in einen Quaternion umrechnen lassen. Also: GameObject inst = Instantiate(shotGun, shotSpawnGun.position, Quaternion.Euler(0.0f,shotSpawnGun.rotation.y, shotSpawnGun.rotation.z)); Wenn du die drei Komponenten einfach nur in Klammern setzt, bekommst du ein Tripple was soweit ich weiß erst in einer neueren C# Version unterstützt wird (?) Syntaktisch richtig müsstest du schreiben 'new Quaternion(x, y, z, w)', aber da eh niemand Quaternions versteht, würde ich das lieber lassen.. ^^ Wenn du trotzdem wissen willst, was es mit Quaternions auf sich hat, kann ich dir dieses Video empfehlen:
  10. Ich würde fast sagen, dass ein Trigger pro Item unperformanter sein dürfte als ein Raycast pro Frame.. In einem meiner Projekte habe ich hunderte Raycasts pro Frame und selbst auf älterer Hardware habe ich keine Probleme, also sollte dein einzelner Ray nichts ausmachen.. Wenn du trotzdem Bedenken hast, würde ich wie malzbie schon meinte, einfach nur jedes x-te Frame einen Raycast schießen. Dann könntest du noch mit einer LayerMask arbeiten, damit du nur nach Items und Wänden checkst. Und du kannst jedes mal, wenn ein neues Objekt getroffen wird, dein 'IInteractable' cachen. Damit sparst du dir viele GetComponent calls, die wahrscheinlich schlimmer als der Raycast selbst sind.
  11. Für ein 8x8 'Pixel' Feld sollte die Abfragerate zu erhöhen ganz gut funktionieren. Falls du in Zukunft aber auch mit größeren Feldern arbeiten willst, wirst du damit evtl. Performance Probleme bekommen.. Alternativ kannst du dir immer die Fingerposition vom vorherigen Frame merken und dann alle Würfel anmalen, die zwischen der alten und neuen Position liegen. Unter 'line rasterization' solltest du da fündig werden..
  12. Die Syntax von deinem Code ist richtig, nur denkt der Compiler schon einen Schritt weiter.. z.B. '50 > 100' wird immer eine falsche Aussage sein, daher wird die Zeile 'Console.WriteLine("50 ist grösser 100");' unter keinen Umständen ausgeführt werden. Da denkt sich der Compiler, dass das nicht richtig sein kann und gibt dir die Warnung 'Unreachable code detected' . Funktionieren sollte der Code trotzdem..
  13. Deine Ansatz ist schon mal nicht ganz falsch, nur nicht sehr sauber/ optimiert.. Zum einen erzeugst du jeden Update eine neue Textur, was unnötigen Datenmüll erzeugt. Und du rufst mehrfach in einem Update 'Apply()' auf. Das sorgt dafür, dass die geänderte Textur zur GPU geschickt wird. Es reicht, wenn du am Ende von jedem Update 'Apply()' aufrufst, sonst schickst du unnötig viele Daten an die GPU, wodurch viel Zeit verloren geht.. Deine Grundstruktur sollte in etwa so aussehen: public int texSize = 512; private Texture2D tex; pivate Color[] pixelColors; private void Start(){ //init textur tex = new Texture2D(texSize, texSize); pixelColors = new Color[texSize * texSize]; GetComponent<Renderer>().material.mainTexture = tex; } private void Update(){ //pixelColors ändern ApplyTexture(); } private void ApplyTexture(){ tex.SetPixels(pixelColors); tex.Apply(); } Um die Pixelfarben zu ändern, musst du erstmal errechnen, wo sich die Maus gerade auf der Textur befindet. 'Input.mousePosition' gibt dir ja nur die Position im 'Game' -Fenster.. Je nachdem, wie du die Textur anzeigen lässt, kannst du das per 'mainCam.ScreenToWorldPoint()' + etwas Mathe machen, oder du schießt einen Ray auf deine Zeichenfläche und lässt dir von 'RaycastHit' die getroffenen UV Position auf der Textur geben. Wenn du dann die X- & Y- Koordinate ( zwischen 0 bis 'texSize' ) errechnet hast, kannst du den Index des getroffenen Pixels im 'pixelColors' Array errechnen: int pixelIndex = xCoord + yCoord * texSize; pixelColors[pixelIndex] = Color.red; Soviel zu den Basics.. wenn du aber vorhast ein 'richtiges' Malprogramm zu basteln, würde ich einen Shader verwenden, weil die um einiges performanter sind.. Ich hatte das selbst vor ein paar Monaten mal getestet.. Ich hab sogar noch den Code gefunden, falls dich die Methode mit dem Shader interessiert. Ich könnte das auch nochmal genauer erklären, aber das ist etwas aufwendiger.. // gab es nicht mal so ein 'Spoiler' Button, mit dem man den Code ein-/ausklappen kann? TexturePaint.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class TexturePaint : MonoBehaviour { public Texture2D source; public Transform target; public Shader myShader; private Mesh targetMesh; private Vector2 targetDimensions; public Color BrushColor; private RenderTexture tmpEditTexture; private Material CircleBrush; private int width; private int height; private Camera cam; private Vector2 lastUV; private bool startStroke; void Awake () { width = source.width; height = source.height; cam = Camera.main; CircleBrush = new Material(myShader); tmpEditTexture = new RenderTexture(width, height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.sRGB); Graphics.Blit(source, tmpEditTexture); target.GetComponent<Renderer>().material.mainTexture = tmpEditTexture; targetMesh = target.GetComponent<MeshFilter>().mesh; targetDimensions = new Vector2(targetMesh.bounds.size.x, targetMesh.bounds.size.z); } private void Update() { if (Input.GetMouseButtonDown(0)) { startStroke = true; } if (Input.GetMouseButton(0)) { Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition); mousePos.y = 0; mousePos = target.InverseTransformPoint(mousePos); Vector2 uv = new Vector2(1 - (mousePos.x / targetDimensions.x + .5f), 1 - (mousePos.z / targetDimensions.y + .5f)); if (startStroke) { startStroke = false; lastUV = uv; } BrushStroke(lastUV, uv); lastUV = uv; } } private void BrushStroke(Vector2 uvCoordFrom, Vector2 uvCoordTo) { CircleBrush.SetColor("_BrushColor", BrushColor); CircleBrush.SetFloat("_BrushSize", (brushSizeSlider.value / width)); CircleBrush.SetVector("_BrushLine", new Vector4(uvCoordFrom.x, uvCoordFrom.y, uvCoordTo.x, uvCoordTo.y)); RenderTexture tmp = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.sRGB); Graphics.Blit(tmpEditTexture, tmp, CircleBrush); Graphics.Blit(tmp, tmpEditTexture); RenderTexture.ReleaseTemporary(tmp); } } LineBrush.shader Shader "TexturePaint/CircleBrush" { Properties { _MainTex ( "Texture", 2D ) = "white" {} _BrushColor ( "Brush Color", COLOR ) = ( 1, 1, 1, 1 ) _BrushLine ( "Brush UV Line", VECTOR ) = ( 0, 0, 0, 0 ) _BrushSize ( "Brush Size", FLOAT ) = 0.01 } SubShader { Tags { "RenderType" = "Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _BrushColor; float4 _BrushLine; float _BrushSize; v2f vert ( appdata v ) { v2f o; o.vertex = UnityObjectToClipPos ( v.vertex ); o.uv = TRANSFORM_TEX ( v.uv, _MainTex ); return o; } float distFromLine ( float4 l, float2 p ) { return abs ( ( p.x - l.x )*( -l.w + l.y ) + ( p.y - l.y )*( l.z - l.x ) ) / sqrt ( pow ( -l.w + l.y,2 ) + pow ( l.z - l.x,2 ) ); } float4 frag ( v2f i ) : SV_Target { float4 col = tex2D ( _MainTex, i.uv ); float distLine = distFromLine ( _BrushLine, i.uv ); float distBrush = length ( _BrushLine.xy - _BrushLine.zw ); distBrush = sqrt ( distBrush*distBrush + _BrushSize*_BrushSize ); float distA = length ( i.uv - _BrushLine.xy ); float distB = length ( i.uv - _BrushLine.zw ); if ( ( distLine <= _BrushSize && distA <= distBrush && distB <= distBrush ) || distA < _BrushSize || distB < _BrushSize ) { col = _BrushColor; } return col; } ENDCG } } }
  14. Ich fände es auch schön, wenn hier mal wieder mehr gepostet werden würde. War immer sehr interessant zu sehen woran andere hier grade so arbeiten.. Hier mal wieder ein Update zu meinem Blutfluss Shader..
  15. Tatsache.. ich würde auch sagen, dass die dunkelblaue Fläche größer ist.. Ich schätze mal das liegt daran, dass zwischen der blauen und roten Fläche genau ein Streifen an Pixeln liegt, der theoretisch zu beiden Farben 50% gehört. Aber jeder Pixel muss sich für eine Farbe entscheiden und somit ist Blau um einen Pixel breiter.. Den Effekt kannst du minimieren, indem du eine höhere Auflösung verwendest. Dann hat der eine Pixel weniger Einfluss.. private Sprite generateCircleSprite(Color[] colors, int resolution) { Color[] pixels = new Color[resolution * resolution]; Vector2 center = new Vector2(resolution / 2f, resolution / 2f); float anglePerColor = 360f / colors.Length; for (int y = 0; y < resolution; y++) { for (int x = 0; x < resolution; x++) { Vector2 dir = new Vector2(x + .5f, y + .5f) - center; float angle = -Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg + 90; angle = (angle < 0 ? 360 + angle : angle); int colorIndex = Mathf.Min((int)(angle / anglePerColor), colors.Length - 1); pixels[x + y * resolution] = dir.magnitude < resolution * .5f ? colors[colorIndex] : Color.clear; } } Texture2D tex = new Texture2D(resolution, resolution); tex.SetPixels(pixels); tex.Apply(); return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(.5f, .5f), resolution); } Diese Methode gibt dir ein Sprite zurück, dass immer 1 Unit hoch/breit ist. Weil die Höhe/Breite in Pixeln der Textur gleich der PixelPerUnit des Sprites entspricht.. Dann kannst du die Größe deines Rades einfach mit der Transform Scale bestimmen.
×
×
  • Create New...