Search Unity

Question Help searched to modify simply mesh-draw code

Discussion in 'Scripting' started by Greetz443, Nov 18, 2022.

  1. Greetz443

    Greetz443

    Joined:
    Dec 20, 2019
    Posts:
    18
    Hi

    I have a script here where you draw a 3D mesh in the X and Y axis with the mouse, but I want to do this on the X and Z axis so that you draw from above, how do I do this?

    I tried many things but it didnt work for me.



    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Linq;
    5.  
    6. namespace DrawMesh
    7. {
    8.     public class DrawController : MonoBehaviour
    9.     {
    10.         public static DrawController Instance { get; private set; }
    11.  
    12.         [SerializeField]
    13.         private MouseTarget mouseTarget;
    14.         [SerializeField]
    15.         private Transform drawMeshTemplate;
    16.         [SerializeField()]
    17.         private DrawSettings drawSettings;
    18.  
    19.         public event Action OnStartDraw;
    20.         public event Action OnDrawing;
    21.         public event Action<DrawMesh> OnEndDraw;
    22.         public event Action<bool> OnFreezing;
    23.         public event Action<float, float> OnLengthChanged;
    24.  
    25.         private float currentLength;
    26.         private DrawMesh drawingMesh;
    27.         private Camera mainCamera;
    28.         private bool isDrawing;
    29.         private bool isHitCantDraw;
    30.  
    31.         private List<Vector2> drawLineVertices = new List<Vector2>();
    32.         private List<Vector2> polygonPoints = new List<Vector2>();
    33.         private Dictionary<Vector2, float> drawLineVerticesAndWeights = new Dictionary<Vector2, float>();
    34.         private Plane zPlaneZero = new Plane(Vector3.forward, Vector3.zero);
    35.  
    36.         public DrawSettings DrawSettings { get { return drawSettings; } }
    37.  
    38.         private void Awake()
    39.         {
    40.             if (Instance != null)
    41.             {
    42.                 Destroy(gameObject);
    43.                 return;
    44.             }
    45.             Instance = this;
    46.         }
    47.  
    48.         private void Start()
    49.         {
    50.             mainCamera = Camera.main;
    51.             currentLength = 0;
    52.  
    53.             mouseTarget.Init(drawSettings);
    54.             drawMeshTemplate.gameObject.SetActive(false);
    55.         }
    56.  
    57.         private void Update()
    58.         {
    59.             if (Input.GetMouseButton(0))
    60.             {
    61.                 Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    62.                 if (zPlaneZero.Raycast(ray, out float enter))
    63.                 {
    64.                     Vector3 mousePosOffsetted = ray.GetPoint(enter);
    65.  
    66.                     if (isDrawing == false)
    67.                     {
    68.                         if (CheckCanDraw(mousePosOffsetted))
    69.                         {
    70.                             InitDraw();
    71.                         }
    72.                     }
    73.                     else
    74.                     {
    75.                         Drawing(mousePosOffsetted);
    76.                     }
    77.                 }
    78.             }
    79.  
    80.             if (Input.GetMouseButtonUp(0))
    81.             {
    82.                 if (isDrawing)
    83.                 {
    84.                     EndDraw();
    85.                 }
    86.             }
    87.         }
    88.  
    89.         private bool CheckCanDraw(Vector3 mousePosOffseted)
    90.         {
    91.             // Update mouseTarget and its target position
    92.             mouseTarget.transform.position = mousePosOffseted;
    93.             mouseTarget.SetTarget(mousePosOffseted);
    94.  
    95.             // Drawing from obstacles is not allowed
    96.             if (mouseTarget.HitCantDrawObject())
    97.             {
    98.                 return false;
    99.             }
    100.  
    101.             return true;
    102.         }
    103.  
    104.         private void InitDraw()
    105.         {
    106.             if (drawSettings.overlapType == OverlapType.FollowEdge)
    107.             {
    108.                 mouseTarget.SetTrigger(false);
    109.             }
    110.  
    111.             drawLineVertices.Clear();
    112.             drawLineVertices.Add(mouseTarget.transform.position);
    113.  
    114.             drawingMesh = Instantiate(drawMeshTemplate, Vector3.zero, Quaternion.identity).GetComponent<DrawMesh>();
    115.             drawingMesh.Init(drawSettings);
    116.             drawingMesh.gameObject.SetActive(true);
    117.  
    118.             OnStartDraw?.Invoke();
    119.             if (drawSettings.freezeObjects)
    120.             {
    121.                 OnFreezing?.Invoke(true);
    122.             }
    123.  
    124.             isDrawing = true;
    125.         }
    126.  
    127.         private void Drawing(Vector3 mousePosOffseted)
    128.         {
    129.             // Update mouseTarget position.
    130.             mouseTarget.SetTarget(mousePosOffseted);
    131.             float lengthIncrease = Vector2.Distance(mouseTarget.transform.position, drawLineVertices.Last());
    132.             if (lengthIncrease >= drawSettings.stepLength)
    133.             {
    134.                 switch (drawSettings.overlapType)
    135.                 {
    136.                     case OverlapType.None:
    137.                     case OverlapType.FollowEdge:
    138.                         AddNewToDrawLine(mouseTarget.transform.position, lengthIncrease);
    139.                         break;
    140.                     case OverlapType.CutOff:
    141.                         // No more new vertices are added to it as soon as a hit is detected.
    142.                         if (isHitCantDraw == false)
    143.                         {
    144.                             isHitCantDraw = mouseTarget.HitCantDrawObject();
    145.                         }
    146.                         if (isHitCantDraw == false)
    147.                         {
    148.                             AddNewToDrawLine(mouseTarget.transform.position, lengthIncrease);
    149.                         }
    150.                         break;
    151.                 }
    152.             }
    153.         }
    154.  
    155.         private void EndDraw()
    156.         {
    157.             // If the number of vertices is not enough, delete it.
    158.             if (drawLineVertices.Count < 2 || (drawSettings.startWidth == 0 && drawSettings.endWidth == 0))
    159.             {
    160.                 drawingMesh.Destroy();
    161.             }
    162.             else
    163.             {
    164.                 Vector2 centerOfMass = CalculateCenterOfMass();
    165.                 drawingMesh.EndDraw(centerOfMass);
    166.             }
    167.  
    168.             OnEndDraw?.Invoke(drawingMesh);
    169.             if (drawSettings.freezeObjects)
    170.             {
    171.                 OnFreezing?.Invoke(false);
    172.             }
    173.  
    174.             mouseTarget.SetTrigger(true);
    175.             isHitCantDraw = false;
    176.  
    177.             drawingMesh = null;
    178.             isDrawing = false;
    179.         }
    180.  
    181.         /// <summary>
    182.         /// Generate Polygon Points according to the Draw Line list and pass it into DrawMesh and call the Generate Mesh function.
    183.         /// </summary>
    184.         private void AddNewToDrawLine(Vector2 targetPos, float distanceIncrase)
    185.         {
    186.             // Determine whether the maximum length is exceeded
    187.             if (drawSettings.lengthLimit && currentLength + distanceIncrase > drawSettings.maxLength)
    188.             {
    189.                 return;
    190.             }
    191.  
    192.             currentLength += distanceIncrase;
    193.             OnLengthChanged?.Invoke(currentLength, drawSettings.maxLength);
    194.  
    195.             drawLineVertices.Add(targetPos);
    196.  
    197.             polygonPoints.Clear();
    198.             drawLineVerticesAndWeights.Clear();
    199.  
    200.             float cos = 0, sin = 0;
    201.             for (int i = 0; i < drawLineVertices.Count - 1; i++)
    202.             {
    203.                 // Calculate the angle of each side on the line, and then rotate 90° is what we need.
    204.                 float colliderAngle = GetAngleFromVector(drawLineVertices[i + 1] - drawLineVertices[i]);
    205.                 colliderAngle -= Mathf.Deg2Rad * 90f;
    206.                 cos = Mathf.Cos(colliderAngle);
    207.                 sin = Mathf.Sin(colliderAngle);
    208.  
    209.                 // Interpolate the corresponding width according to the width of the head and tail, and only take half to achieve the optimization purpose.
    210.                 float halfTempWidth = Mathf.Lerp(drawSettings.startWidth, drawSettings.endWidth, (float)i / drawLineVertices.Count) * 0.5f;
    211.                 drawLineVerticesAndWeights.Add(drawLineVertices[i], halfTempWidth);
    212.  
    213.                 // The points of PolygonCollider2D is a ring. In order to form such a vertex structure, it is necessary to insert the upper and lower points at the same time.
    214.                 polygonPoints.Add(new Vector2(drawLineVertices[i].x + halfTempWidth * cos, drawLineVertices[i].y + halfTempWidth * sin));
    215.                 polygonPoints.Insert(0, new Vector2(drawLineVertices[i].x - halfTempWidth * cos, drawLineVertices[i].y - halfTempWidth * sin));
    216.             }
    217.  
    218.             // The angle of the last point is the same as the previous one, and the width is the last width.
    219.             Vector2 lastVertex = drawLineVertices.Last();
    220.             float halfEndWidth = drawSettings.endWidth * 0.5f;
    221.  
    222.             drawLineVerticesAndWeights.Add(lastVertex, halfEndWidth);
    223.  
    224.             polygonPoints.Add(new Vector2(lastVertex.x + halfEndWidth * cos, lastVertex.y + halfEndWidth * sin));
    225.             polygonPoints.Insert(0, new Vector2(lastVertex.x - halfEndWidth * cos, lastVertex.y - halfEndWidth * sin));
    226.             drawingMesh.SetPoints(polygonPoints, distanceIncrase);
    227.             OnDrawing?.Invoke();
    228.         }
    229.  
    230.         /// <summary>
    231.         /// Get the angle based on the direction (in radians).
    232.         /// </summary>
    233.         private float GetAngleFromVector(Vector2 direction)
    234.         {
    235.             float radians = Mathf.Atan2(direction.y, direction.x);
    236.             return radians;
    237.         }
    238.  
    239.         /// <summary>
    240.         /// Each point is multiplied by its corresponding width (half is used here, a meaning), all accumulated and divided by the total width to get the position of the center of gravity.
    241.         /// </summary>
    242.         private Vector2 CalculateCenterOfMass()
    243.         {
    244.             Vector2 pointsSum = Vector2.zero;
    245.             float weightSum = 0;
    246.             foreach (var item in drawLineVerticesAndWeights)
    247.             {
    248.                 pointsSum += item.Key * item.Value;
    249.                 weightSum += item.Value;
    250.             }
    251.             return pointsSum / weightSum; ;
    252.         }
    253.  
    254. #if UNITY_EDITOR
    255.         private void OnDrawGizmos()
    256.         {
    257.             if (isDrawing && drawLineVertices != null && drawLineVertices.Count > 0)
    258.             {
    259.                 Gizmos.color = Color.black;
    260.                 Gizmos.DrawSphere(drawLineVertices[0], 0.1f);
    261.  
    262.                 for (int i = 0; i < drawLineVertices.Count - 1; i++)
    263.                 {
    264.                     Gizmos.color = Color.black;
    265.                     Gizmos.DrawSphere(drawLineVertices[i + 1], 0.1f);
    266.                     Gizmos.color = Color.cyan;
    267.                     Gizmos.DrawLine(drawLineVertices[i], drawLineVertices[i + 1]);
    268.                 }
    269.             }
    270.         }
    271. #endif
    272.     }
    273. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Trying many things is generally not necessary.

    You only need two steps to work with example code.

    In this case it sounds a LOT like you skipped Step #2 below.

    Go back to where you go the above and restart the process.

    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.


    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

    Finally, when you have errors, don't post here... just go fix your errors! Here's how:

    Remember: NOBODY here memorizes error codes. That's not a thing. The error code is absolutely the least useful part of the error. It serves no purpose at all. Forget the error code. Put it out of your mind.

    The complete error message contains everything you need to know to fix the error yourself.

    The important parts of the error message are:

    - the description of the error itself (google this; you are NEVER the first one!)
    - the file it occurred in (critical!)
    - the line number and character position (the two numbers in parentheses)
    - also possibly useful is the stack trace (all the lines of text in the lower console window)

    Always start with the FIRST error in the console window, as sometimes that error causes or compounds some or all of the subsequent errors. Often the error will be immediately prior to the indicated line, so make sure to check there as well.

    All of that information is in the actual error message and you must pay attention to it. Learn how to identify it instantly so you don't have to stop your progress and fiddle around with the forum.
     
  3. Greetz443

    Greetz443

    Joined:
    Dec 20, 2019
    Posts:
    18
    I appreciate that you went to so much trouble to give me a useless answer, I am now in a time-wasting mood and call a Jehovah's Witness. Thank you.

    But since only the crap X and Y drawing must be changed to X and Z can a !Jehovah's.Witness help me?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    If this is what is going on, then what you did should work.

    If this is not what is going on, nobody here is going to stare at 273 lines of code and tell you what is going on.

    If YOU are interested in fixing YOUR problem, I urge you to reconsider the above process, which works in actually 100% of the cases of software engineering problems.

    If not, well, I still wish you good luck and good progress in your game(s).
     
    exiguous likes this.
  5. Greetz443

    Greetz443

    Joined:
    Dec 20, 2019
    Posts:
    18
    We are programmers and do not read books, right? You look at the methods and see that you have to work in the "drawing" method, I posted here the whole code because it is better for the understanding. I am sure that for someone who is good at programming it can be solved in 10-20 minutes.

    And I have in the last years almost never asked for help and solved everything myself, except when I just do not get ahead. Your solution proposal does not work for me because it is not a tutorial code, either someone reads the code and helps me or not.
     
  6. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,164
    Read through the code seems like the entire thing you are working with vector 2 but doesn’t show the part where you apply the vector to the mesh vertices. In which case it would be that location where you input the vector 2 into the correct vector 3 axis.

    if it is just a camera issue rotate the object. Maybe try rotating the entire verts of the entire model and then call your vector 2 to use the new updated verts to the new rotation. This would grab all verts and do stuff with their position to make it the opposite of what it was. Or to make it 50% of the opposite of what it is.
     
  7. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Did you write the code yourself or have you "borrowed" it from somewhere? If the latter it does not really matter wether it is from a tutorial oder something else. If it's your code you should be able to bend it to your will, if it's "foreign" code you have to understand what it does to be able to bend it to your will. There is no way around it.

    So everyone who cannot solve it in your arbitrary timeframe is a bad programmer? And who want's to spend 20 minutes on stranger peoples code for no real benefit? And what if something from the code is missing? Or it depends on your setup (inspector variables)? I hope you see that there is little inducement for people here to even try to understand what your code does. Especially after your "arrogant" behavior.

    Explain those. Maybe it's easier to spot a mistake/error on one of those "many" and make it work than to create a solution from scratch.