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 /
avatar image
0
Question by Barachiel · Oct 03, 2015 at 05:28 PM · meshprocedural meshmeshfilter

Procedurally created mesh appearing offset from it's vert locations.

Hey all.

I'm building a mesh procedurally at runtime and it works fine. but the visible mesh and the mesh collider are located offset from the location of the vertices.

To check this, I ran a for loop to grab all the vertices in the mesh and instantiated a small cube at each location.

Here's a picture showing an example: Image and video hosting by TinyPic

In this, the cube at the bottom right is being used as an indicator of where world origin is.

As you can see, the mesh is in one location, while the verts (represented by the smaller cubes) is in another. The gameObject the mesh is a part of is created at the mouse position in world space using a ray (which works fine for placing primitives, so it doesn't appear to be the culprit).

The further away the mesh is created from world origin, the larger the offset. As you may have deduced from the image, the direction of the offset is also related to the world origin, always being in the opposite direction.

This here is the relevant bit of code for creating the mesh. New sets of points are added and calculated as you move the mouse around (with the button held down), creating a wall as you go.

     IEnumerator StartWall()
     {
         makeWall = true;
         oldMousePosition = Input.mousePosition;
         wallNumber += 1;
         bool startedMoving = false;
         List<Vector3> currentPoints = new List<Vector3>();
         List<Vector3> allPoints     = new List<Vector3>();
         List<int> currentTris   = new List<int>();
         List<int> allTris       = new List<int>();
         int segments = 0;
 
         ////INITILIZATION////
         #region Initializing The Wall Object
 
         mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(mouseRay, out mouseHit, 500f, floorMask))
         {
             startPoint = mouseHit.point;
         }
 
         Vector3 previousPoint           = startPoint;
         Vector3 nextPoint               = startPoint;
 
         Transform newWall               = new GameObject("Wall # " + wallNumber).transform;
         newWall.position = startPoint;
         newWall.parent = wallContainer;
         walls.Add(newWall);
 
         MeshFilter  newWallMeshFilter   = newWall.gameObject.AddComponent<MeshFilter>();
         MeshRenderer newWallRenderer    = newWall.gameObject.AddComponent<MeshRenderer>();
         MeshCollider newWallCollider    = newWall.gameObject.AddComponent<MeshCollider>();
         newWallRenderer.material = shinyWhite;
         Mesh newWallMesh         = new Mesh();
         newWallMesh.name          = "wall_mesh " + wallNumber;
         newWallMeshFilter.mesh   = newWallMesh;
         newWallCollider.sharedMesh = newWallMesh;
 
         #endregion
 
         while (makeWall)
         {
             if (mousePosition != oldMousePosition)
             {
                 startedMoving = true;
                 //Mesh Creation
                 mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                 if(Physics.Raycast(mouseRay, out mouseHit, 500f, floorMask))
                 {
                     if(Vector3.Distance(mouseHit.point, previousPoint) > smoothness)
                     {
                         nextPoint = mouseHit.point;
 
                         Instantiate(cubePrimitive, nextPoint, Quaternion.identity);
 
                         Vector3 direction = (nextPoint - previousPoint).normalized;
                         Vector3 up = new Vector3(0, 1, 0).normalized;
                         Vector3 right = Vector3.Cross(direction, up);
 
                         //Front
                         Vector3 point0 = previousPoint;
                         Vector3 point1 = nextPoint;
                         Vector3 point2 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z);
                         Vector3 point3 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z);
                         //Top
                         Vector3 point4 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z);
                         Vector3 point5 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z);
                         Vector3 point6 = new Vector3(nextPoint.x, nextPoint.y + wallHeight, nextPoint.z) + (right * wallWidth);
                         Vector3 point7;
                         if (allPoints.Count < 1)
                         {
                             point7 = new Vector3(previousPoint.x, previousPoint.y + wallHeight, previousPoint.z) + (right * wallWidth);
                         }
                         else
                         {
                             point7 = allPoints[allPoints.Count - 6];
                         }
                         //Back
                         Vector3 point8 = new Vector3(point6.x, point6.y - wallHeight, point6.z);
                         Vector3 point9 = new Vector3(point7.x, point7.y - wallHeight, point7.z);
                         Vector3 point10 = point7;
                         Vector3 point11 = point6;
 
                         currentPoints = new List<Vector3>()
                         {
                             //Front
                             point0, point1, point2, point3,
                             //Top
                             point4, point5, point6, point7,
                             //Back
                             point8, point9, point10, point11,
                         };
                         allPoints.AddRange(currentPoints);
                         allPointsTest = allPoints;
                         newWallMesh.vertices = allPoints.ToArray();
 
                         segments++;
 
                         currentTris = new List<int>()
                         {
                             0 + ((segments - 1) * 12), 2  + ((segments - 1) * 12), 1  + ((segments - 1) * 12),
                             0 + ((segments - 1) * 12), 3  + ((segments - 1) * 12), 2  + ((segments - 1) * 12),
                             4 + ((segments - 1) * 12), 6  + ((segments - 1) * 12), 5  + ((segments - 1) * 12),
                             4 + ((segments - 1) * 12), 7  + ((segments - 1) * 12), 6  + ((segments - 1) * 12),
                             8 + ((segments - 1) * 12), 10 + ((segments - 1) * 12), 9  + ((segments - 1) * 12),
                             8 + ((segments - 1) * 12), 11 + ((segments - 1) * 12), 10 + ((segments - 1) * 12),
                         };
                             
                         allTris.AddRange(currentTris);
                         newWallMesh.triangles = allTris.ToArray();
 
                         newWallMesh.RecalculateNormals();
                         newWallMesh.RecalculateBounds();
                         newWallMesh.Optimize();
                         newWallCollider.sharedMesh = null;
                         newWallCollider.sharedMesh = newWallMesh;
 
                         previousPoint = nextPoint;  //Assigns the current point(nextPoint) to the previousPoint variable for use in the next iteration.
                     }
                 }
                 oldMousePosition = mousePosition;
             }
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

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by maccabbe · Oct 03, 2015 at 05:44 PM

Are you taking the transform into account?

The mesh stores the position of each vertex in local space while the displayed position adds the transform information on top of it. So a simple case would be a vertex with coordinates (0, 0, 0) in a transform where the position is (1, 0, 0) would display the vertex at (1, 0, 0).

To make cubes where each vertex is displayed you're going to have to line up their world coordinates. One way to do so would be to replace

 Instantiate(cubePrimitive, nextPoint, Quaternion.identity);

with

 Instantiate(cubePrimitive, transform.TransformPoint(nextPoint), Quaternion.identity)
Comment
Add comment · Show 3 · Share
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
avatar image Barachiel · Oct 03, 2015 at 06:54 PM 0
Share

Thanks for your reply!

The cubes were just for debugging purposes, to check where the verts were.

Since the mesh is created starting at the mouse point in world space, and then following it, it means that the visible object isn't anywhere near the mouse position, so I need to line up what is visible with the actual location of the verts.

Following your advice about the transform position being added on to it, however, I subtracted the objects position from the vert locations as I added them into the array. This worked really well and achieved exactly what I was hoping for, except for three verts where doing this threw them off. Not adjusting them caused them to behave, though I don't know why.

Regardless, this solved my issue. Thanks!

avatar image Bunny83 Barachiel · Oct 05, 2015 at 01:09 AM 0
Share

"subtracted"? That only works if the gameobject that has the $$anonymous$$eshRenderer for your mesh is not rotated or scaled. In general you should use transform.InverseTransformPoint to transform a worldspace position into localspace.

avatar image Barachiel Bunny83 · Oct 05, 2015 at 02:21 AM 0
Share

Hi there, thanks for the response. The mesh in question is being created from scratch and isn't something that needs to move, so it's fine always having the same rotation and scale. To future proof myself though, I'll mess around with that and see what I can do. Thanks!

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

30 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

Related Questions

Splitting vertices in a mesh specifically a plane 0 Answers

What's the right way of generating a procedural mesh from an known outline? 2 Answers

Procedural Mesh problem from Editor Window 1 Answer

Replace MeshFilter mesh by a other mesh in Editor 1 Answer

Simple plane generation 1 Answer


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