Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by Payton-Dugas · Nov 08, 2019 at 01:08 PM · meshmeshrendererdrawmeshlags

Creating Lag with DrawMesh

I created this sort of prediction path for some kind of missile in 3D. First I was just using line render, until I quickly realized it was very limiting. So I switched to drawing my own meshes and it's rather beautiful. I just have one problem. In the scene when I'm running the drawMesh function everything runs quickly, but as soon as I switch to another scene there's about a 2 second lag and then everything resumes as normal. Line render didn't present any lag whatsoever, so I must have messed something up because drawing your own meshes should be more efficient.


I suspect somehow when creating my meshes the old ones never get delete, therefore when I change the scene it takes a bit to clear them all away. I'd expect the garbage collector to take care of this, but I'm probably setting something up slightly wrong. The longer you stay in the scene the longer the lag is so that's why I think this. This is just speculation though.


If anyone could take a look at my code and suggest a fix I'd appreciate it greatly.

Here's the code. It's a little complicated, but not much can be done about that. I'll include the area of code that I think is the culprit because the same code with line render worked. I'll also include the whole script in case you want to peek at it. It runs about 30 times per frame.

 void drawMesh(Vector3[] vertices, Material m)
     {
         var mf = GetComponent<MeshFilter>();
 
         var mesh = new Mesh();
         mf.mesh = mesh;
 
         mesh.vertices = vertices;
 
         var tris = new int[6]
         {
             // lower left triangle
             0, 2, 1,
             // upper right triangle
             2, 3, 1
         };
         mesh.triangles = tris;
 
         var normals = new Vector3[4]
         {
             -Vector3.forward,
             -Vector3.forward,
             -Vector3.forward,
             -Vector3.forward
         };
         mesh.normals = normals;
 
         var uv = new Vector2[4]
         {
             new Vector2(0, 0),
             new Vector2(1, 0),
             new Vector2(0, 1),
             new Vector2(1, 1)
         };
         mesh.uv = uv;
         Graphics.DrawMesh(mesh, Vector3.zero, Quaternion.identity, m, 0, null, 0, null, false, false);
     }
 }



Here's the complete file. I separated the function "Visualize Aim" because I don't think anything else useful is going on outside of that.

 using System.Collections;
 using UnityEngine;
 
 public class AimCannon : MonoBehaviour
 {
     public static bool cannonActive;
 
     [SerializeField] private Transform cannonY;
 
     // Calculating Aim Variables
     private Vector3 last_mouse_pos, mouse_pos;
     private float aimSpeed = 10;
     private int trailDensity = 30;
     private float trail_timeDistance = 4;
     private int thrustMultiple = 5;
     private float baseThrust = 70;
     private int lnSegments;
     private DistanceData closestPlane;
     private DistanceData lastClosestPlane;
     private float stickToPlane = 10f;
 
     // Draw mesh
     [SerializeField] private Material grey, red;
     private float startWidth = .05f;
     private float endWidth = 1.5f;
 
     void Start()
     {
         cannonActive = true;
         Physics.gravity = Vector3.down * 5f;
     }
 
     void Update()
     {
         if(InstNewPlanes.allPlanes.Count > 0)
         {
             updateTarget();
             visualizeAim();
             updateThrust();
         }
     }
 
     private void FixedUpdate()
     {
         isStillFiring();
         aimCannon();
     }
 
     /// <summary>
     /// Uses user input to aim cannonY
     /// </summary>
     void aimCannon()
     {
         Vector3 difference = last_mouse_pos - mouse_pos;
         float y_dif = difference.y;
         float x_dif = difference.x;
         float y_rot = y_dif * aimSpeed;
         float x_rot = -x_dif * aimSpeed;
         cannonY.Rotate(Vector3.right, y_rot, Space.Self);
         transform.Rotate(Vector3.up, x_rot, Space.Self);
     }
 
     /// <summary>
     /// Updates some target, idk
     /// </summary>
     void updateTarget()
     {
         if(Input.touchCount == 1)
         {
             Touch touch = Input.GetTouch(0);
             if(touch.phase == TouchPhase.Began)
             {
                 mouse_pos = mouseToWorldPosition();
                 last_mouse_pos = mouse_pos;
             }
             else if(touch.phase == TouchPhase.Moved)
             {
                 last_mouse_pos = mouse_pos;
                 mouse_pos = mouseToWorldPosition();
             }
             else if(touch.phase == TouchPhase.Stationary)
             {
                 last_mouse_pos = mouse_pos;
             }
             else if(touch.phase == TouchPhase.Ended)
             {
                 last_mouse_pos = new Vector3(0, 0, 0);
                 mouse_pos = new Vector3(0, 0, 0);
             }
         }
     }
 
     class DistanceData
     {
         public GameObject plane;
         public float distance;
         public bool closest;
         public DistanceData(GameObject p, float d)
         {
             plane = p;
             distance = d;
             closest = false;
         }
 
         public DistanceData(GameObject p, float d, bool c)
         {
             plane = p;
             distance = d;
             closest = c;
         }
     }
 
     /// <summary>
     /// Gets the closest plane to the aim
     /// </summary>
     /// <param name="posns"></param>
     /// <returns></returns>
     DistanceData findClosestPlane(ArrayList posns)
     {
         ArrayList planeDataArray = new ArrayList();
         IEnumerator ienum = InstNewPlanes.allPlanes.GetEnumerator();
         while (ienum.MoveNext())
         {
             float dis = 1000;
             GameObject currentPlane = (GameObject)ienum.Current;
             foreach(Vector3 posn in posns)
             {
                 if(Vector3.Distance(posn, currentPlane.transform.position)<(dis))
                 {
                     dis = Vector3.Distance(posn, currentPlane.transform.position);
                 }
             }
             planeDataArray.Add(new DistanceData(currentPlane, dis));
         }
         return returnClosestPlane(planeDataArray);
     }
 
     /// <summary>
     /// Finds the closest plane to the aim
     /// </summary>
     /// <param name="l"></param>
     /// <returns></returns>
     DistanceData returnClosestPlane(ArrayList l)
     {
         float dis = 1000;
         DistanceData data = null;
         foreach(DistanceData d in l)
         {
             if (d.distance < dis)
             {
                 dis = d.distance;
                 data = d;
             }
         }
         if (closestPlane != null)
         {
             if (data.distance < closestPlane.distance / stickToPlane)
                 return closestPlane;
         }
 
         return data;
     }
 
     /// <summary>
     /// Ends the aim visualization as the right distance 
     /// </summary>
     /// <param name="closest"></param>
     /// <param name="pos1"></param>
     /// <param name="pos2"></param>
     /// <returns></returns>
     bool endTrial(Vector3 closest, Vector3 pos1, Vector3 pos2)
     {
         if(Vector3.Distance(closest, pos1) <
             Vector3.Distance(closest, pos2))
         {
             return true;
         }
         return false;
     }



     /// <summary>
     /// Helps visualize aim so you can hit your targets
     /// </summary>
     void visualizeAim()
     {
         if (InstNewPlanes.allPlanes.Count == 0)
             return;
         //Line render set up variables
         float cannonYangle = (210 - getAngle(cannonY).y)*Mathf.PI/180;
         int lnSize = 0;
         ArrayList lnPositions = new ArrayList();
         ArrayList vectorPoints = new ArrayList();
 
         float x_angle = -cannonY.transform.rotation.eulerAngles.x * Mathf.PI / 180;
         float y_angle = getAngle(cannonY).y * Mathf.PI / 180;
         float y_vel = FireCannon.thrust * Mathf.Sin(x_angle);
         float flat_vel = FireCannon.thrust * Mathf.Cos(x_angle);
         float x_vel = Mathf.Cos(y_angle) * flat_vel;
         float z_vel = Mathf.Sin(y_angle) * flat_vel;
         for (int i = 0; i < trailDensity; i += 1)
         {
             lnSize++;
             Vector3 trail_pos;
             float t = i / (trailDensity / trail_timeDistance);
             float x = x_vel * t;
             float z = z_vel * t;
             float y = y_vel * t - 5f * t * t / 2;
             trail_pos = new Vector3(x, y, z);
             lnPositions.Add(trail_pos);
         }
         closestPlane = findClosestPlane(lnPositions);
         for (int i = 0; i < lnSize-1; i++)
         {
             float fi = i;
             float w1 = Mathf.Lerp(startWidth, endWidth, fi / (lnSize - 1));
             float w2 = Mathf.Lerp(startWidth, endWidth, (fi+1) / (lnSize - 1));
             Vector3 lnPos1 = (Vector3) lnPositions[i];
             Vector3 lnPos2 = (Vector3)lnPositions[i+1];
             Vector3 bl = new Vector3(
                 lnPos1.x - Mathf.Cos(cannonYangle) * w1,
                 lnPos1.y,
                 lnPos1.z - Mathf.Sin(cannonYangle) * w1);
             Vector3 br = new Vector3(
                 lnPos1.x + Mathf.Cos(cannonYangle) * w1,
                 lnPos1.y,
                 lnPos1.z + Mathf.Sin(cannonYangle) * w1);
             Vector3 tl = new Vector3(
                 lnPos2.x - Mathf.Cos(cannonYangle) * w2,
                 lnPos2.y,
                 lnPos2.z - Mathf.Sin(cannonYangle) * w2);
             Vector3 tr = new Vector3(
                 lnPos2.x + Mathf.Cos(cannonYangle) * w2,
                 lnPos2.y,
                 lnPos2.z + Mathf.Sin(cannonYangle) * w2);
             var vertices = new Vector3[4]
             {
                 bl,
                 br,
                 tl,
                 tr
             };
             vectorPoints.Add(vertices);
             if (endTrial(closestPlane.plane.transform.position, lnPos1, lnPos2))
             {
                 lnSegments = i;
                 int j = 0;
                 foreach(Vector3[] verts in vectorPoints)
                 {
                     if (j > lnSegments / 3)
                         drawMesh(verts, red);
                     else
                         drawMesh(verts, grey);
                     j++;
                 }
                 return;
             }
         }
     }



     /// <summary>
     /// Updates the thrust of the plane dependant on distance of planes
     /// </summary>
     void updateThrust()
     {
         if(lastClosestPlane == null)
             lastClosestPlane = closestPlane;
         else if(lastClosestPlane.plane != closestPlane.plane)
         {
             FireCannon.thrust = baseThrust + lnSegments * 3;
             lastClosestPlane = closestPlane;
         }
     }
 
     /// <summary>
     /// When the play shoots down 10 planes this object is destroyed
     /// </summary>
     void isStillFiring()
     {
         if (!cannonActive)
         {
             Destroy(this);
         }
     }
 
     /// <summary>
     /// Mouse to World Position
     /// </summary>
     /// <returns></returns>
     Vector3 mouseToWorldPosition()
     {
         Vector3 mouse_pos = Input.mousePosition;
         mouse_pos.z = 5;
         Vector3 world_pos = Camera.main.ScreenToWorldPoint(mouse_pos);
         return world_pos;
     }
 
     /// <summary>
     /// Helper function to get angles becasue... Unity
     /// </summary>
     /// <param name="trans"></param>
     /// <param name="direction"></param>
     /// <returns></returns>
     public Vector3 getAngle(Transform transform)
     {
         Vector3 forward = transform.forward;
         float angleInDegreesZ = Mathf.Atan2(transform.right.y, transform.right.x) * Mathf.Rad2Deg;
         float angleInDegreesX = Mathf.Atan2(forward.y, forward.z) * Mathf.Rad2Deg;
         float angleInDegreesY = Mathf.Atan2(forward.z, forward.x) * Mathf.Rad2Deg;
         Vector3 returnAngle = new Vector3(angleInDegreesX, angleInDegreesY, angleInDegreesZ);
         return returnAngle;
     }
 
     void drawMesh(Vector3[] vertices, Material m)
     {
         var mf = GetComponent<MeshFilter>();
 
         var mesh = new Mesh();
         mf.mesh = mesh;
 
         mesh.vertices = vertices;
 
         var tris = new int[6]
         {
             // lower left triangle
             0, 2, 1,
             // upper right triangle
             2, 3, 1
         };
         mesh.triangles = tris;
 
         var normals = new Vector3[4]
         {
             -Vector3.forward,
             -Vector3.forward,
             -Vector3.forward,
             -Vector3.forward
         };
         mesh.normals = normals;
 
         var uv = new Vector2[4]
         {
             new Vector2(0, 0),
             new Vector2(1, 0),
             new Vector2(0, 1),
             new Vector2(1, 1)
         };
         mesh.uv = uv;
         Graphics.DrawMesh(mesh, Vector3.zero, Quaternion.identity, m, 0, null, 0, null, false, false);
     }
 }
 





Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

128 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Bounds of dynamic mesh not updating 1 Answer

Why zero height mesh gets black independent of shader 1 Answer

How to Cut a Mesh - The Forest Style Tree Cutting 0 Answers

Particle System: Material doesn't cover the entire sphere mesh 1 Answer

How to change one child object to another with the same armature? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges