<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bennett Upfield</title>
    <description>The latest articles on DEV Community by Bennett Upfield (@bjupfield).</description>
    <link>https://dev.to/bjupfield</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F762316%2Fdc5b20b1-7d0f-4e98-bec0-37090dbea030.gif</url>
      <title>DEV Community: Bennett Upfield</title>
      <link>https://dev.to/bjupfield</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bjupfield"/>
    <language>en</language>
    <item>
      <title>Official GameDev Post; PlayerDrawn Walls: 2</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Thu, 10 Mar 2022 02:12:19 +0000</pubDate>
      <link>https://dev.to/bjupfield/official-gamedev-post-playerdrawn-walls-2-5899</link>
      <guid>https://dev.to/bjupfield/official-gamedev-post-playerdrawn-walls-2-5899</guid>
      <description>&lt;h1&gt;
  
  
  Description
&lt;/h1&gt;

&lt;p&gt;This post will cover a function I've created in Unity VR with the SteamVR plugin to create a system where a player can create an adjustable wall. I decided to create this to use VR systems to what I think are they're full capabilities, creating engaging systems that are not really possible on a normal control scheme of mouse and keyboard. I have tried to keep the controls for the creator as simple as possible, with some added flair for fun, and I think I have succeeded in creating an easy to use system for creating a wall archetype object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Scheme
&lt;/h2&gt;

&lt;p&gt;As I said, my control scheme does have some flair to it and is not wholly practical but other than a single system that could be a series of buttons instead of giving player interaction through the capabilities of the Index controllers. In the &lt;a href="https://dev.to/bjupfield/official-gamedev-post-nameless-1-3mmn"&gt;Official Game Dev Post; Nameless: 1&lt;/a&gt; I go over a control scheme I use here to choose what action to take. There are Three different Main-Modes containing three Sub-Modes with this controller scheme. For this project I utilize one Main Mode, and below is the switch simplified for the action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(handposition("//mainmode 1//"){
   switch(handposition("//submode//")){
      case "InitialMode": //this is what the hand position is in upon entering the mainmode
         //draw mode refer to Initial Mesh Creation
         break;
      case "OpenPalm":
         //initiate case selection and mesh adjustability, refer to Wall Mesh Creation and Adjustability
         break;
      case "ClosedFist":
         //unused
         break;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, I do use two more specific controller actions that I will go over in their relevant sections, the first a Draw Function for Initial Mesh Creation, the second a General Purpose Hand Movement in the Direction the Palm is Pointing Action Controller that is used in the Wall Mesh Creation and Adjustability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Mesh Creation
&lt;/h2&gt;

&lt;p&gt;I divided the generation of the wall into three parts for two reasons. One is that it allows for the use of this draw function in unison with other Archetypes. Another is that drawing a wall is physically impossible on a flat canvas. The draw function only creates a "surface" mesh (a better name for a 2d mesh used in creating a wall") which I then use to crown the wall with. To get this surface all I had to do was make the player outline a shape with his controller. To do this I have a three step system. When first entering InitialMode the player creates a plane that they can "paint" their shape on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function drawStart(GameObject hand){
   Vector3 doubleReferenceMeansVariable = hand.transform.forward;
   Vector3 pointMeter = hand.transform.position + doubleReferenceMeansVariable;
   DrawPlane = createPlane(pointMeter, doubleReferenceMeansVariable);
}
plane createPlane(Vector3 point, Vector3 vector){
   float d = -(-(point.x * vector.x) - (point.y * vector.y) - (point.z * vector.z));
   return new plane{x = vector.x, y = vector.y, z = vector.z, d = d};
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Draw start takes the hand that is currently entering InitialMode and creates a plane based on the direction its pointing (hand.transform.forward) a meter away (unity.transform.direction gives a normalized vector meaning that adding one to a point makes the new point one unit away) and on the normal of that point and line. The next section of code takes the forward position of the hand controllers again, but instead creates a line from that forward and checks for points that intersect with the plane past the controller, and adds those points to an array. As its pretty simple to imagine I'll save you the code. The Third step of the system is the creation of surface mesh once the hand enters the Open Palm Mode, which takes the Vector3 array and uses the program triangulator to create a mesh from the array, and also using the scripts created by Jens-Kristian Nielsen to use this program and understand it &lt;a href="http://tothemathmos.com/2013/05/17/advanced-triangulation-in-unity.html"&gt;Link Here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    triangulateMesh createSurface(Vector3[] vects){
        List&amp;lt;Vector3&amp;gt; vectorList =  new List&amp;lt;Vector3&amp;gt;(vects);
        Vector3 firstPoint = vectorList[0];
        vectorList = vectorList.ConvertAll(new System.Converter&amp;lt;Vector3, Vector3&amp;gt;((point)=&amp;gt;{
            return point - firstPoint;
        }));
        Vector3 linea = vectorList[1] - vectorList[0];
        Vector3 lineb = vectorList[2] - vectorList[0];
        Vector3 cross = Vector3.Cross(linea, lineb);
        linea = linea.normalized;
        cross = cross.normalized;
        Vector3 cross2 = Vector3.Cross(linea, cross);
        Vector3 point1 = vectorList[0];
        Vector3 point2 = point1 + linea;
        Vector3 point3 = point1 + cross2;
        Vector3 point4 = point1 + cross;
        Matrix4x4 pointMatrix = new Matrix4x4(
            new Vector4(point1.x, point1.y, point1.z, 1),
            new Vector4(point2.x, point2.y, point2.z, 1),
            new Vector4(point3.x, point3.y, point3.z, 1),
            new Vector4(point4.x, point4.y, point4.z, 1));
        Matrix4x4 conversionMatrix =  new Matrix4x4(
            new Vector4(0, 0 ,0 ,1),
            new Vector4(1, 0, 0, 1),
            new Vector4(0, 1, 0, 1),
            new Vector4(0, 0, 1, 1));
        Matrix4x4 b = conversionMatrix * pointMatrix.inverse;
        List&amp;lt;Vector2&amp;gt; vectorLi = vectorList.ConvertAll&amp;lt;Vector2&amp;gt;(new System.Converter&amp;lt;Vector3, Vector2&amp;gt;((point)=&amp;gt;{
            Vector3 result; 
            result.x = b.m00 * point.x + b.m01 * point.y + b.m02 * point.z + b.m03; 
            result.y = b.m10 * point.x + b.m11 * point.y + b.m12 * point.z + b.m13; 
            float num = b.m30 * point.x + b.m31 * point.y + b.m32 * point.z + b.m33; 
            num = 1 / num;
            result.x *= num;
            result.y *= num;
            Vector2 xy = new Vector2(result.x, result.y);
            return xy;
        }));
        MeshFinder.PSLG myPoints = new MeshFinder.PSLG(vectorLi);
        MeshFinder.Polygon2D finished = binstance.Triangulate(myPoints);
        Mesh newMesh = new Mesh();
        List&amp;lt;Vector3&amp;gt; meshVertexs = new List&amp;lt;Vector2&amp;gt;(finished.vertices).ConvertAll&amp;lt;Vector3&amp;gt;(new System.Converter&amp;lt;Vector2, Vector3&amp;gt;((xy)=&amp;gt;(new Vector3(xy.x, xy.y, 0))));
        newMesh.vertices = meshVertexs.ToArray();
        newMesh.triangles = finished.triangles;
        return new triangulateMesh(){
            mesh = new Mesh(){
                vertices = meshVertexs.ToArray(),
                triangles = finished.triangles,
            },
            surfaceLength = newMesh.vertexCount,
            outlineLength = vects.Length,
        };
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here I simply use a transform matrix to change my 3d plane into a 2d plane, as that is also a second reason you cannot draw a 3d object (the Triangulator program only will fill in the blanks for 2d objects). I then throw these newly created 2d points into Jens and Triangulator written part of the program which gives me a lovely 2d mesh with no giant holes in it. I then save the two variables surfaceLength and outlineLength as knowing the size of the surface and of the original outline is useful further down the line. From this I create a surface mesh. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hyhoMo2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2b4gqdo60jmswz9jez3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hyhoMo2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2b4gqdo60jmswz9jez3.gif" alt="WellUploaded" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  (Just a demonstration of the creation of the plane)
&lt;/h6&gt;
&lt;h2&gt;
  
  
  Wall Mesh Creation
&lt;/h2&gt;

&lt;p&gt;After the creation of the initial surface mesh there is another selection tree to choose which type of object archetype you would like to take. This is chosen from the other new controller, the General Purpose Hand Movement in the Direction the Palm is Pointing Action Controller. This code checks if your palm is open and if your palm is open it checks if the hand moves in the direction your palm is moving.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(leftOpen){
   leftPalm = leftHand.transform.right.normalized;
   leftCurrMovement = (leftHand.transform.position - leftPrePos).normalized;
   if(Mathf.Abs((leftPalm + leftCurrMovement).magnitude) &amp;gt;= 1.85f){ //This checks if velocity is reasonably aligned with the direction the palm points
      goingForward(exportLeft, false);
      wroteLeft = false;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above checks first if the palm is open, then checks the palm direction and its movement adds the two normalized vectors together and checks if the magnitude is greater than 1.85. This reasonably checks if the two vectors align, while giving that much needed human wiggle room. Once the script checks for if the controller is going in the palm open direction it runs another check that first adds sets the current controller movement class and then checks if the class on the whole has gone a set distance while aligned.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(testRequiredLength &amp;lt;= Mathf.Abs((info.currPos - info.startPos).magnitude) &amp;amp;&amp;amp; (which ? rightTypeChoosen == false : leftTypeChoosen == false))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simply checks if the from the beginning of the movement you have gone further than a required length. The reset of this movement is initiated if&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(wroteLeft &amp;amp;&amp;amp; exportLeft.type == "None")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but if you reach the designated length a type is assigned to the class depending on how you moved the controller, mostly up, mostly down, or simply "forward". Once this selection is made the wall creation begins.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GameObject currCreation = new GameObject();
IceWall c = currCreation.AddComponent&amp;lt;IceWall&amp;gt;();
triangulateMesh toMake = c.wallFunction(initialMesh);
c.wallMesh = toMake;
currCreation.AddComponent&amp;lt;MeshFilter&amp;gt;().mesh = toMake.mesh;
currCreation.AddComponent&amp;lt;MeshRenderer&amp;gt;();


triangulateMesh wallFuncion(triangulateMesh surface){
   List&amp;lt;Vector3&amp;gt; vectorList = new List&amp;lt;Vector3&amp;gt;(surface.mesh.vertices).ConvertAll&amp;lt;Vector3&amp;gt;(new System.Converter&amp;lt;Vector3, Vector3&amp;gt;((vector)=&amp;gt;(new Vector3(vector.x, 0, vector.y)))); //converts to a z by x surface instead of x and y
   for(int b = 0; b &amp;lt; 10; ++b){
      float number = b;
      for(int i = 0; i &amp;lt; surface.outlineLength; ++i){
         Vector3 outlineVector = vectorList[i];
         vectorList.Add(new Vector3(outlineVector.x, -number / 10f, outlineVector.z));
      }
   } // adding new vertexes
   List&amp;lt;int&amp;gt; triangleList = new List&amp;lt;int&amp;gt;(surface.mesh.triangles);
   for(int curr = 0; curr &amp;lt; triangleList.Count; curr += 3){
      int reverse1 = triangleList[curr];
      int reverse2 = triangleList[curr + 2];
      triangleList[curr] = reverse2;
      triangleList[curr + 2] = reverse1;
    }
    for(int b = 0; b &amp;lt; 10; ++b){
       for(int i = 0; i &amp;lt; surface.outlineLength; ++i){
          int whichLayer = surface.outlineLength * b + surface.surfaceLength; // decides where the added vertexes from the loop above are
          int whereTop = (b &amp;gt; 0 ? surface.surfaceLength : 0) +  Mathf.Max(b - 1, 0) * surface.outlineLength; //decides where the vertexes above the added vertexes are
          if(i == surface.outlineLength - 1){
             triangleList.AddRange(new int[]{i + whichLayer, i + whereTop, whereTop,});
             triangleList.AddRange(new int[]{i + whichLayer, whereTop, whichLayer});
                }
          else{
             triangleList.AddRange(new int[]{i + whichLayer, i + whereTop, i + 1 + whereTop,});
             triangleList.AddRange(new int[]{i + whichLayer, i + 1 + whereTop, i + 1 + whichLayer});
          }
       }
    }
    Mesh meshToCreateWall = new Mesh();
    meshToCreateWall.vertices = vectorList.ToArray();
    meshToCreateWall.triangles = triangleList.ToArray();
    return new IceHandler.triangulateMesh(){
       mesh = meshToCreateWall,
       outlineLength = surface.outlineLength,
       surfaceLength = surface.surfaceLength,
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simply takes the triangulated mesh that was created in the Initial Mesh Creation which uses the two extra values OutlineLength and SurfaceLength to create the walls walls. It of course does this by using a for loop that adds new vertexes under each original outline Vertex (the vertexes that the player draws originally). The surfaces triangles also have to be reversed as the triangles set by the Triangulator will be upside down if not reversed. With this we finally have our Wall created, and now only need to adjust the wall dynamically.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WQbFgTBB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sunzt4kaqz72nbhuhlc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WQbFgTBB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sunzt4kaqz72nbhuhlc.gif" alt="Here I am" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  (Demonstration of Wall Creation)
&lt;/h6&gt;
&lt;h2&gt;
  
  
  Wall Mesh Adjustability
&lt;/h2&gt;

&lt;p&gt;As you might of noticed the wall creation above does not have any adjustability of the height of the wall. Because of this there must  be a further way to adjust the wall, which is once again done in the "openpalm" section of the switch, but only after the wall has been created. In each wall GameObject there is a script that takes the Palm Movement class and interprets what each class Movement is saying to result in different adjustments. The two useful Palm Movement types are the up and down types, which both initiate the wall adjustment "lift".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void simpleLift(actionPalmMovement lift, bool which){
    OpenPalmHandler.palmMovement mov = which ? lift.rightPalm : lift.leftPalm;
    Debug.Log("Before: " + wallMesh.mesh.vertices[0].y);
    Vector3[] newVertexes = wallMesh.mesh.vertices;
    if(mov.fin){
        for(int i = 0; i &amp;lt; wallMesh.surfaceLength; ++i){//for the top
            newVertexes[i].y += mov.velocity.y * Time.deltaTime;
        }
        for(int i = 0; i &amp;lt; 10; ++i){//this means all the sides
            float d = i;
            for(int j = wallMesh.surfaceLength + wallMesh.outlineLength * i; j &amp;lt; wallMesh.outlineLength * i + wallMesh.surfaceLength; ++j){
                newVertexes[i].y += mov.velocity.y * Time.deltaTime * ((1f + d) / 11f); 
            }
        }
    }
    else{
        for(int i = 0; i &amp;lt; wallMesh.surfaceLength; ++i){//for the top
            newVertexes[i].y += mov.currMov.y;
        }
        for(int i = 0; i &amp;lt; 10; ++i){//this means all the sides
            float d = i;
            for(int j = wallMesh.surfaceLength + wallMesh.outlineLength * i; j &amp;lt; wallMesh.outlineLength * i + wallMesh.surfaceLength; ++j){
                newVertexes[i].y += mov.currMov.y * ((1f + d) / 11f);
            }
        }
    }
    wallMesh.mesh.vertices = newVertexes;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This adds the movement of the Palm Movement to the wall, by method of OutlineLength and SurfaceLength used in a for loop again to adjust the right Vectors, each moving distance depending on which layer the vertex is on, to spread the object stretching along as many vertexes as possible. With this we have a fully adjustable wall when using a single controller.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwRT5hJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqzwce1eai1oqufg8lr0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwRT5hJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqzwce1eai1oqufg8lr0.gif" alt="AnotherOne" width="600" height="329"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  (Demonstration of Simple Lift)
&lt;/h6&gt;
&lt;h2&gt;
  
  
  Dynamic Actions
&lt;/h2&gt;

&lt;p&gt;All these actions I have presented have been single controller actions, but Humans have two hands. So, I have made more the system capable of handling both hands inputting at once, and here I'll present the most player visible one. For adjusting the wall with two hands there is a complexLift. This Action taking two inputs does two things differently from the first. First it test for which hand is further along the z axis of the wall,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transform wall = this.gameObject.transform;
Vector3 leftZCheck = action.lefthand.x * wall.right + action.lefthand.z * wall.forward;
Vector3 rightZCheck = action.righthand.x * wall.right + action.righthand.z * wall.forward;
Vector3 zFurther = leftZCheck.z &amp;gt;= rightZCheck.z ? action.leftPalm.fin ? action.leftPalm.velocity * Time.deltaTime : action.leftPalm.currMov : action.rightPalm.fin ? action.rightPalm.velocity * Time.deltaTime : action.rightPalm.currMov;
Vector3 zShorter = leftZCheck.z &amp;gt;= rightZCheck.z ? action.rightPalm.fin ? action.rightPalm.velocity * Time.deltaTime : action.rightPalm.currMov : action.leftPalm.fin ? action.leftPalm.velocity * Time.deltaTime : action.leftPalm.currMov;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then it creates a slope dependent on the hand movement and the length of the wall,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;float m = furthestZ - closestZ == 0 ? 0 : (zFurther.y - zShorter.y) / (furthestZ - closestZ);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating this slope it adds the slope * the vector z Position to each Vector, along wtih the layer position adjustment to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;newVertices[j].y += isnoteven ? m * newVertices[j].z * ((1f + d) / 11f) : action.leftPalm.currMov.y * ((1f + d) / 11f);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the player to create a sloped wall with the use of two hands.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LKbXZO2t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/os9bemo5jbhcl07d385l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LKbXZO2t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/os9bemo5jbhcl07d385l.gif" alt="Image description" width="600" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  (Demonstration of ComplexLift)
&lt;/h6&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project is Unfinished. As you can see from all the presentations from it, the wall is untextured, the height adjustments are hard to control, and the wall is a solid surface. The next blog post on this will probably be me adding all these features, finding a natural adjustment multiplier, adding a noise function for the added vectors, and texturing based on the noise function. However, this feature is just a demonstration of the capabilities of the VR medium. Unlike using a mouse and keyboard you can create 3d models from relatively simple feeling commands. For anything but VR controllers the creation of a wall like this would take the use of something like blender, or a serious of sliders similar to Character Creation screen, but with the use of VR controllers and the complex hand-like inputs you can receive from them the creation of more interesting functions like this is possible.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>unity3d</category>
      <category>vr</category>
    </item>
    <item>
      <title>Official GameDev Post; Nameless: 1</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Thu, 17 Feb 2022 22:14:46 +0000</pubDate>
      <link>https://dev.to/bjupfield/official-gamedev-post-nameless-1-3mmn</link>
      <guid>https://dev.to/bjupfield/official-gamedev-post-nameless-1-3mmn</guid>
      <description>&lt;h1&gt;
  
  
  SteamVr
&lt;/h1&gt;

&lt;p&gt;This dev post will be about the controller aspect of a Unity VR game I am programming. I am of course using the unity VR system but I am also using the Valve.Vr unity add on, which you can reference &lt;a href="https://valvesoftware.github.io/steamvr_unity_plugin/articles/intro.html"&gt;Here&lt;/a&gt; if need be. The steam plugin adds the interesting feature of finger placements to the VR controller, the depth of complexity that this post will focus on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Flashy Hands
&lt;/h1&gt;

&lt;p&gt;The current "thing" that I am programming is wizard hands for the game. This is basically a set of different finger placements and other things that say which magic spells you will be using. Here is the code for accessing the finger positioning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SteamVR_Action_Skeleton skeleton = whatever SteamVR_Action_Skeleton;
float[] curlindex = new float[5];
curlIndex = skeleton.fingerCurls;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The curlIndex is a float array that contains the curl amount of the fingers around the controller with a value of 0 being completely off the controller and 1 being fully wrapped around. CurlIndex[0] is the thumb and the rest follow in order. Steam Vr also has the function of finger splay which measures the width between each finger, but because of differing hand sizes and the problem that when you lift a finger of the controller it gets very confused it is not really usable. Now currently I have three modes for finger positioning with three submodes for each of those modes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;float thumbJoySide = 0.65f;
float thumbButtonSide = 0.76f;
float indexWrapped = 0.25f;
float m_rWrapped = .35f;
if(curlIndex[0] &amp;gt;= thumbJoySide &amp;amp;&amp;amp; curlIndex[0] &amp;lt;= thumbButtonSide &amp;amp;&amp;amp; curlIndex[1] &amp;gt;= indexWrapped &amp;amp;&amp;amp; curlIndex[2] &amp;gt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[3] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[4] &amp;lt;= m_rWrapped){
            mode1(); 
        }
else if(curlIndex[0] &amp;gt;= thumbButtonSide &amp;amp;&amp;amp; curlIndex[1] &amp;lt;= indexWrapped &amp;amp;&amp;amp; curlIndex[2] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[3] &amp;gt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[4] &amp;gt;= m_rWrapped){
            mode2();
        }
else if(curlIndex[0] &amp;lt;= thumbJoySide &amp;amp;&amp;amp; curlIndex[1] &amp;gt;= indexWrapped &amp;amp;&amp;amp; curlIndex[2] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[3] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[4] &amp;gt;= m_rWrapped){
            mode3();
        }
else if(curlIndex[0] &amp;gt; thumbJoySide &amp;amp;&amp;amp; curlIndex[1] &amp;gt;= indexWrapped &amp;amp;&amp;amp; curlIndex[2] &amp;gt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[3] &amp;gt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[4] &amp;gt;= m_rWrapped){
            closedFist();
        }
else if(curlIndex[0] &amp;lt; thumbJoySide &amp;amp;&amp;amp; curlIndex[1] &amp;lt;= indexWrapped &amp;amp;&amp;amp; curlIndex[2] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[3] &amp;lt;= m_rWrapped &amp;amp;&amp;amp; curlIndex[4] &amp;lt;= m_rWrapped){
            openPalm();
        }
else
        {
            notAny();
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see above there are a few defined curl input sizes like ThumbJoySide. These are the values that I tested that seem reasonably accurate in telling if a finger is wrapped around or not. Now to set the value type and subtype in each of the function call that is a mode I set a string array of length 2 to the name of the mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handPosition[0] = "Fire";
handPosition[1] = "Fire";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Of course there are better ways to store it but this is an easy way to remember which is which right now)&lt;br&gt;
The three submodes are set from the modes closedFist, openPalm and staying in the original mode position. As you've probably deduced by now the first part of the array is the main mode and the second value of the array is the submode. Now to reset which hand position you are in final else statement of notAny() initiates a timer that resets the "handPosition" array to the value "NoValue". Here is the simply switch statement for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;notAny(){
     switch(handPosition[0]){
            case "Fire":
                if(releaseTimer &amp;lt;= 3) {
                    releaseTimer += Time.deltaTime;
                }
                else{
                    handPosition[0] = "NoValue";
                    handPosition[1] = "NoValue";
                    releaseTimer = 0; 
                }
                break;
            case "Ice":
                if(releaseTimer &amp;lt;= 3) {
                    releaseTimer += Time.deltaTime;
                }
                else{
                    handPosition[0] = "NoValue";
                    handPosition[1] = "NoValue";
                    releaseTimer = 0;
                }
                break;
            case "Lightning":
                if(releaseTimer &amp;lt;= 3) {
                    releaseTimer += Time.deltaTime;
                }
                else{
                    handPosition[0] = "NoValue";
                    handPosition[1] = "NoValue";
                    releaseTimer = 0;
                }
                break;
            case "NoValue":
                handPosition[1] = "NoValue";
                releaseTimer = 0;
                break;
      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I do admit that for these positions mode3 might be a bit to close to other modes, as when playtesting switching between mode one to two sometimes switches to mode three, so for three modes more specific finger positions might be required. But anyway, taking these values you can then have the player choose an attack style, grant special powers, maybe have some sort of movement adjustment signifier tied to hand position, or really anything you are creative enough to think of. A small demonstration of this is in an unrelated post by me &lt;a href="https://dev.to/bjupfield/instantiation-difference-over-class-difference-529p"&gt;"here"&lt;/a&gt; where both of the gifs utilize this function to do different things. If you have any thoughts or comments plz leave them down below as anything is helpful for improving this code.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>vr</category>
      <category>c</category>
      <category>steamvr</category>
    </item>
    <item>
      <title>JPGs and URL.createObjectURL()</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Thu, 17 Feb 2022 20:49:20 +0000</pubDate>
      <link>https://dev.to/bjupfield/jpgs-and-urlcreateobjecturl-3ehi</link>
      <guid>https://dev.to/bjupfield/jpgs-and-urlcreateobjecturl-3ehi</guid>
      <description>&lt;h1&gt;
  
  
  CreatingImageUrls
&lt;/h1&gt;

&lt;p&gt;Lets say for some abstract reason completely unrelated to this other post of mine (&lt;a href="https://dev.to/bjupfield/javascript-sql-and-file-saving-53dn"&gt;Hmmm&lt;/a&gt;) you have a javascript File object that is of image and you want to display it on your site instead of simply pulling an url for and image. Now if you had this image you could use this cool Url method, URL.createObjectURL(). The code would be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const interpretedImage = URL.createObjectURL(imgFile);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to use this created url image on your html image element use the interpretedImage variable as the src. However do make sure the file is unnamed as the name of the file will appear in the image if you name it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Javascript, Sql, and File Saving</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Thu, 17 Feb 2022 19:56:01 +0000</pubDate>
      <link>https://dev.to/bjupfield/javascript-sql-and-file-saving-53dn</link>
      <guid>https://dev.to/bjupfield/javascript-sql-and-file-saving-53dn</guid>
      <description>&lt;h1&gt;
  
  
  Creating Files in Javascript
&lt;/h1&gt;

&lt;p&gt;This post will be over creating Files in Javascript and them uploading them to an SQL database. The first step to this process is creating the file. In Javascript there is a File Object that can be used to create Files. The constructor File() takes several components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const newFile = new File([fileData], `filename.extension`, {
            type: "filetype/filesubtype"
        })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a file use the constructor in a above mentioned way where fileData can be any sort of File data you need from strings to binary, the second parameter is the filename where it is helpful to put the extension on the end, and the third parameter is the filetype and subtype. Here is a better explanation, and a list of all the possible file-types, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/File/File"&gt;MDN&lt;/a&gt; and &lt;a href="https://www.iana.org/assignments/media-types/media-types.xhtml"&gt;FileTypes&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating The SQL Table
&lt;/h1&gt;

&lt;p&gt;To store files of any type in SQL the table you create needs to have three attributes, a binary and two strings. The binary will contain all the data that the file has, the two string will be for a name and the file mime/type (mime is name for file type). Here is the table in rails&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create_table :save_files do |t|
      t.binary :file_data
      t.string :file_name
      t.string :file_mime
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Uploading
&lt;/h1&gt;

&lt;p&gt;Now to upload the files to the SQL you will have to convert the data to binary. Luckily, Javascript has an excellent function for this arrayBuffer(). Using arrayBuffer() on your previously created file you can create a  promise that you can then call a second function Uint8Array on the return creating a binary data object. Then you can simply upload the file with whatever method you want to with the data from the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file.arrayBuffer()
   .then(r=&amp;gt;{
       const fileData = new Uint8Array(r)
       fetch(`whereverYouWant`,{
       method: "POST",
       headers: {
            "Content-Type" : "application/json"
       },
       body: JSON.stringify({
            file_data: fileData,
            file_name: file.name,
            file_mime: file.type,
       })
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Downloading
&lt;/h1&gt;

&lt;p&gt;To download the file you need to fetch the information. The only thing different from creating the file is that you will need to create an array buffer for the file data. For creating the array buffer make the length equal to the file_data length that you pulled from the SQL and then from that buffer create a new Uint8Array for the data. Then you use that Uint8Array for the date of the file you create.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const buffer = new ArrayBuffer(data.length)
const view = new Uint8Array(buffer);
// create file with view for file data and all the other info you pulled from sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use this file in any way you like from downloading to onsite integration.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>sql</category>
      <category>rails</category>
    </item>
    <item>
      <title>SVGs</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Thu, 17 Feb 2022 18:52:38 +0000</pubDate>
      <link>https://dev.to/bjupfield/svgs-4cm6</link>
      <guid>https://dev.to/bjupfield/svgs-4cm6</guid>
      <description>&lt;h1&gt;
  
  
  Scalable Vector Graphics
&lt;/h1&gt;

&lt;p&gt;SVGs are a possible alternative to images in html. They are as the title says a Vector Graph. The two main components are the viewbox and the path. Viewbox defines the area of the graph that the SVG will present, so if you say have a line of equation y = 5, and the viewbox is 0, 0, 20, 5, the line will be at the top of the SVG graphic with the graphic only presenting a line segment from x = 5 to x = 20 (the viewbox syntax is x1, y1, x2, y2). The path is the lines that are defined within the graph, which sadly do end and are defined by point to point. The syntax gets a little complicated for this so I'll just send you to the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths"&gt;MDN Web Doc&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Use
&lt;/h1&gt;

&lt;p&gt;SVGs are best used for replacing images that are not to complicated or needs to "scale" as they scale better than a normal .jpg or .png would. So, perhaps instead of a company logo or instead of the simple background image you should use SVGs to display that graphic. Also on a completely unrelated note here is a little program I made to create SVGs (work in progress) &lt;a href="https://github.com/bjupfield/my-website"&gt;Here&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>ResizeObserver &amp; UseState</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Fri, 11 Feb 2022 03:43:37 +0000</pubDate>
      <link>https://dev.to/bjupfield/resizeobserver-usestate-544k</link>
      <guid>https://dev.to/bjupfield/resizeobserver-usestate-544k</guid>
      <description>&lt;h1&gt;
  
  
  Just a Short Post
&lt;/h1&gt;

&lt;p&gt;I ran into a problem while using ResizeObserver and UseState which led to a reload loop. The problem I found out is that when a ResizeObserver is called on an element even though its not being resized it decides to call the attached function. So, since this is the case the solution is pretty simple, if you change a useState inside the function have a variable outside the function that changes after the first call,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const e = true;
observer.current = new ResizeObserver(entries =&amp;gt;{
            for(let entry of entries){
                if(e !== 1)
                {
                    //Very Useful Code
                }
                e = false;
            }
        }); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple stuff, but really annoying to find out that ResizeObserver calls on every single assignment.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Instantiation Difference Over Class Difference</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Mon, 17 Jan 2022 00:21:21 +0000</pubDate>
      <link>https://dev.to/bjupfield/instantiation-difference-over-class-difference-529p</link>
      <guid>https://dev.to/bjupfield/instantiation-difference-over-class-difference-529p</guid>
      <description>&lt;h2&gt;
  
  
  Creating A Single Class to Handle Multiple Types of Objects
&lt;/h2&gt;

&lt;p&gt;In this little blog post I will be displaying a project that I have been working on in UnityVr. As I'm I've been meaning to push this blogpost for a while plz excuse the horrible or even non-modeled objects that you see in the presentation. The focus for this blog post will be how I designed the program to handle multiple types of objects underneath a single class by instantiating the class widely differently to have different results. The Two Objects that I intend to make in the project are a "fireball effect" and a "flamethrower effect" which are both handled by the same particle class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fireball
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gI9BU089--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8k1luam6m6op5fu4132r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gI9BU089--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8k1luam6m6op5fu4132r.gif" alt="Ball Gif" width="600" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Completely unmodeled or animated, the real effect would have more fireballs with different models and light sources layered on.
&lt;/h6&gt;

&lt;h1&gt;
  
  
  Flamethrower
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1iGG_Nmw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek2svu5ntcauzfsvjjfy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1iGG_Nmw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek2svu5ntcauzfsvjjfy.gif" alt="Cone Gif" width="600" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Particle {
        public Vector3 oPos;
        public Vector3 postion;
        public Vector3 objectStart;
        public Vector3 velocity;
        public Vector3 sideVel;
        public Vector3 circleVel;
        public GameObject self1;

        public float time;
        public void update(Sprite mat, SwordController maths, float addti, int index, int index2){
            if(self1.GetComponent&amp;lt;SpriteRenderer&amp;gt;() == null){self1.AddComponent&amp;lt;SpriteRenderer&amp;gt;();}
            self1.GetComponent&amp;lt;SpriteRenderer&amp;gt;().sprite = mat;
            time += addti;
            self1.name = $"{index2}Particle{index}";
        }
        public void physicsUpdate(SwordController maths, float t, float adjustmentrate){
            Vector3 wholeVel = (velocity + sideVel + circleVel) * t;
            postion += wholeVel;
            Transform tr = self1.transform;
            tr.localPosition = postion;
            if(velocity != new Vector3()){
                Vector3 z = velocity + sideVel;
                Vector3 lineStart = oPos - velocity;
                float multiplier = (z.x * (lineStart.x - oPos.x) + z.y * (lineStart.y - oPos.y) + z.z * (lineStart.z - oPos.z)) / (Mathf.Pow(z.x , 2) + Mathf.Pow(z.y, 2) + Mathf.Pow(z.z, 2));
                Vector3 closestPoint = new Vector3(lineStart.x + z.x * multiplier, lineStart.y + z.y * multiplier, lineStart.z + z.z * multiplier);
                Vector3 zdirect = closestPoint - oPos;
                Vector3 cross = Vector3.Cross(zdirect, z);
                Vector3 cross2 = Vector3.Cross(z, cross);
                tr.localRotation = maths.fromForward(cross2.normalized,  zdirect.normalized);
            }
            else
            {
                tr.localRotation = maths.fromForward((postion - velocity * time - oPos).normalized, wholeVel);
            }
            if(circleVel != new Vector3() || sideVel != new Vector3()){
                Vector3 radius = (postion - velocity * time - oPos);
                if(circleVel != new Vector3()){
                    circleVel += -radius.normalized * (Mathf.Pow(circleVel.magnitude, 2) / radius.magnitude) * t;
                }
                if(sideVel != new Vector3()){
                    sideVel = radius.normalized * Mathf.Abs(sideVel.magnitude);
                }
            }
        }
        public void destroyObject(){
            Destroy(self1);
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  (To be honest I did fail on two sections of creating the catch all class the two if statements. The first if statement is used to decide how the particle should be rotated, as I'm sad to say I couldn't figure out an ideal way to handle it, and the second is just because the unity Vector3 struct did not like taking a magnitude of 0.)
&lt;/h6&gt;

&lt;p&gt;Both of these functions use the same particle class to operate (except for what I just mentioned), but because of how each is instantiated they provide objects that look completely different. Below are another two code Blocks that contain both the instantiation for the "fireball" and for the "flamethrower".&lt;/p&gt;

&lt;h3&gt;
  
  
  Fireball
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void particleCircleInstatiater(float t, int howmany, GameObject fireball){
        for(int i = howmany; i &amp;gt; 0; i--){
            Vector3 oPos = new Vector3(fireball.transform.position.x, fireball.transform.position.y, fireball.transform.position.z);
            Vector3 forVel = new Vector3(Random.Range(-1f,1f), Random.Range(-1f,1f), Random.Range(-1f,1f)).normalized * Random.Range(.8f, 1f); //not actuall velocity but simply the direction to figure out the circular velocity
            Vector3 pos = new Vector3() + forVel; //might need to create a seperate object to attach the particles to... attached might need to change
            Vector3 sideVel = maths.XDirectionFinder(forVel, Random.Range(0, Mathf.PI * 2)); //Again not real velocity but just to find circlevel... might need to change to a not random range may look better
            Vector3 circleVel = Vector3.Normalize(Vector3.Cross(sideVel, forVel)) * Random.Range(rotateSpeed[0], rotateSpeed[1]); //The only actual velocity
            int nameNum = int.Parse(fireball.name.Remove(0, 8));
            System.Array.Resize&amp;lt;Particle&amp;gt;(ref partArr2[nameNum], partArr2[nameNum].Length + 1);
            GameObject particle = new GameObject(name: $"{nameNum}Particle{partArr2[nameNum].Length-1}");
            particle.transform.SetParent(fireball.transform);
            partArr2[nameNum][partArr2[nameNum].Length-1] = new Particle{postion = pos, oPos = new Vector3(), velocity = new Vector3(), sideVel = new Vector3(), circleVel = circleVel, time = 0, self1 = particle};
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  "Flamethrower"
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void particleLinearInstatiater(float t, int howmany){
        for(int i = howmany ;i &amp;gt; 0; i--){
            Vector3 oPos = new Vector3(attached.transform.position.x, attached.transform.position.y, attached.transform.position.z);
            float randomRadius = Random.Range(radius[0], radius[1]);
            Vector3 randomPos = ((new Vector3(Random.Range(-1f,1f), Random.Range(-1f,1f), Random.Range(-1f,1f)).normalized) * randomRadius) + oPos;
            float randomForward = Random.Range(speed[0], speed[1]);
            Vector3 forVel = attached.transform.forward * randomForward;
            float multiplier = (oPos.x - randomPos.x + oPos.y - randomPos.y + oPos.z - randomPos.z) / (Mathf.Pow(forVel.x , 2) + Mathf.Pow(forVel.y, 2) + Mathf.Pow(forVel.z, 2));
            Vector3 closestPoint = new Vector3(oPos.x + forVel.x * multiplier, oPos.y + forVel.y * multiplier, oPos.z + forVel.z * multiplier);
            Vector3 sideVel;
            float randomDepAngle = randomForward * (Random.Range(anglespeed[0], anglespeed[1]) / 100f); //anglespeed is a percentage of forward to deal with random issues
            if(randomRadius == 0){
                sideVel = maths.XDirectionFinder(forVel.normalized, Random.Range(0, Mathf.PI * 2)).normalized * randomDepAngle;
            }
            else{
                sideVel = (randomPos - closestPoint).normalized * randomDepAngle;
            }
            Vector3 circleVel = Vector3.Normalize(Vector3.Cross(sideVel, forVel)) * Random.Range(rotateSpeed[0], rotateSpeed[1]);
            if(sideVel != new Vector3(0,0,0)){
                circleVel = Vector3.Normalize(Vector3.Cross(sideVel, forVel)) * Random.Range(rotateSpeed[0], rotateSpeed[1]);
            }
            else{
                circleVel = Vector3.Normalize(Vector3.Cross((randomPos - closestPoint).normalized, forVel)) * Random.Range(rotateSpeed[0], rotateSpeed[1]);
            }
            if(randomRadius == 0 &amp;amp;&amp;amp; anglespeed[1] == 0){
                circleVel = new Vector3(0, 0, 0);
                sideVel = new Vector3(0, 0, 0);
            }
            System.Array.Resize&amp;lt;Particle&amp;gt;(ref partArr2[partArr2.Length - 1], partArr2[partArr2.Length - 1].Length + 1);
            partArr2[partArr2.Length - 1][partArr2[partArr2.Length - 1].Length-1] = new Particle{postion = randomPos, oPos = closestPoint, objectStart = attached.transform.position, velocity = forVel, sideVel = sideVel, circleVel = circleVel, time = 0, self1 = new GameObject(name:${partArr2.Length1}Particle{partArr2[partArr2.Length - 1].Length-1}")};
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only difference between these two objects is the difference between the instantiation code. For one it creates an object that orbits around a central point, and the next can create an object that spirals around a central point going forward. Just off a few changes to the way you create the object the class can will operate in the same way, but have different results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;To keep this little post little, I will end it here. Instead of creating different classes for every single object that you want to create you can take a different approach of creating an object, usually simpler, that can handle a larger range of possibilities. This is shown through the code examples I have above, but of course this way of coding does have its drawbacks. For example, every single different object I would have to create a different instatiator, instead of having it contained within the class. But, if you are working on creating a system with a lot of different uses coding such that instantiation creates the difference in objects instead of the class definitions can help reduce repeated code and be easier to program, as for each function you already have the base class programmed.&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Introduction to My Blog</title>
      <dc:creator>Bennett Upfield</dc:creator>
      <pubDate>Fri, 26 Nov 2021 20:11:51 +0000</pubDate>
      <link>https://dev.to/bjupfield/introduction-to-my-blog-2pfi</link>
      <guid>https://dev.to/bjupfield/introduction-to-my-blog-2pfi</guid>
      <description>&lt;p&gt;Hello, to all you interviewers (and even the few random people who stumble upon this useless post), welcome to my Blog-Post. As you know I my application has the coding Bootcamp Flatiron as my primary source of education for programming, and that is where I was encouraged to start writing a blog-post to grow my online presence. Anyways refer to the two sections below.&lt;/p&gt;

&lt;h2&gt;
  
  
  General Post Content
&lt;/h2&gt;

&lt;p&gt;In these blogs, at least for the next few months, I will be posting on the random walkthroughs for coding problems that I've faced while learning at Flatiron. I will also be providing solutions to problems I face on a few coding projects that I am currently working on, my first post will be one of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is I
&lt;/h2&gt;

&lt;p&gt;My names Bennet Upfield. I've been programming for my own pleasure for around 2 years and have taken a few college courses on Computer Programming. When I took these courses they surprised me with how much I enjoyed them. This has taken me to enter into the Flatiron Bootcamp where I hope to enter into the programming Industry for the hope of finding enjoyable employment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anyway
&lt;/h2&gt;

&lt;p&gt;Go read the rest of my blog post, I'll try to keep them more engaging than this one.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
