Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
1
Question by DaiMangouDev · Nov 11, 2014 at 06:42 AM · c#arrayvector3

How do I place the matching Vector3 array values of a Vector3 array in a new array ?

hello , I am attempting to place the values of an array that are the same; inside of a separate.

this is a code i adopted and tried to use to move an objects verts , however; this script assigned points called "handles" to each vert as a child of the object . As a result , moving the handles results in simply pulling the mesh apart by individual verts.

I tried to group all the verts with the same Vector3 positions into an array and setting all the vector3 values of that array to be equal to the position of the handle.

 using UnityEngine;
 using System.Collections;
 
 [ExecuteInEditMode]
 
 public class VertHandler : MonoBehaviour
 {
     Mesh mesh;
     Vector3[] verts;
     Vector3 vertPos;
     GameObject[] handles;
     void OnEnable()
     {
         mesh = GetComponent<MeshFilter>().mesh;
         verts = mesh.vertices;
         foreach (Vector3 vert in verts)
         {
             vertPos = transform.TransformPoint(vert);
             GameObject handle = new GameObject("handle");
             handle.transform.position = vertPos;
             handle.transform.parent = transform;
             handle.tag = "handle";
             //handle.AddComponent<Gizmo_Sphere>();
         }
     }
 
     void OnDisable()
     {
         GameObject[] handles = GameObject.FindGameObjectsWithTag("handle");
         foreach (GameObject handle in handles)
         {
             DestroyImmediate(handle);
         }
     }
 
     void Update()
     {
         handles = GameObject.FindGameObjectsWithTag("handle");
         for (int i = 0; i < verts.Length; i++)
         {
             verts[i] = handles[i].transform.localPosition;
         }
         mesh.vertices = verts;
         mesh.RecalculateBounds();
         mesh.RecalculateNormals();
     }
 }

 



Comment
Add comment · Show 3
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 Bunny83 · Nov 11, 2014 at 05:15 PM 2
Share

Well, all your examples are about exact duplicates but in your title you said "similar". There's a huge difference. When dealing with exact duplicates you can simply compare them. If you want similar values (like Vector3(2.5f,3,6) and Vector3(2.49999f,3,6.00001)) then you have to be more clear how you define similar in your case. In the comment below you had a different example using strings / objects / whatever. What is your actual usecase? Vector3 values or something else?

What's the point of storing the same (or almost the same) values in an array? In this case you could simply store the value once and a counter that tells you how many of those values you have. The easiest way for that would be a Dictionary which just stores a count for each unique Vector3.

Could you be a bit more specific if you want "similar" values or exact the same values?

avatar image DaiMangouDev · Nov 11, 2014 at 05:30 PM 0
Share

i need to sort through all the verts of a mesh, find all the vert positions that are the same , store all those positions in an array .

I will change the question to be more specific .

avatar image Bunny83 · Nov 11, 2014 at 06:17 PM 1
Share

Be careful with scripts like that. ExecuteInEdit$$anonymous$$ode can cause a lot of problems and can corrupt your assets as well as the current scene. It's usually better to write an editor script for things like that.

1 Reply

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

Answer by Bunny83 · Nov 11, 2014 at 06:05 PM

Ok, for mesh manipulations you actually want to store the indices of similar vertices so you can update them all at once. just copying the vector3 value won't help much since you don't know where it belongs in the actual vertices array.

I would suggest to use a helper class like:

 public class VertHandle
 {
     public Vector3 pos;
     public List<int> indices = new List<int>();
     public Transform handle;
 }

With that class you can create a unique handle for each vertex-group like this:

 List<VertHandle> GenerateHandles(Vector3[] aVertices, float aThreshold)
 {
     float sqrThreshold = aThreshold*aThreshold;
     List<VertHandle> result = new List<VertHandle>();
     for(int i = 0; i < aVertices.Length; i++)
     {
         VertHandle h = null;
         for(int n = 0; n < result.Count; n++)
         {
             if ((result[n].pos - aVertices[i]).sqrMagnitude < sqrThreshold)
             {
                 h = result[n];
                 break;
             }
         }
         // if there's no handle with that position yet, create one.
         if(h == null)
         {
             h = new VertHandle() { pos = aVertices[i]};
             h.handle = new GameObject("handle").transform;
             h.handle.parent = transform;
             h.handle.localPosition = aVertices[i];
             h.handle.tag = "handle";
             result.Add(h);
         }
         // add the current vertex to the indices list of that handle
         h.indices.Add(i);
     }
     return result;
 }


This gives you a list of handles. To apply the changes from the handles to your actual vertices, just use

 void ApplyChanges(List<VertHandle> aHandles, Vector3[] aVertices)
 {
     for(int i = 0; i < aHandles.Count; i++)
     {
         Vector3 pos = aHandles[i].handle.localPosition;
         for(int n = 0; n < aHandles[i].indices.Count; n++)
         {
             aVertices[aHandles[i].indices[n]] = pos;
         }
     }
 }

Keep in mind when destroying the handles to use

 foreach (VertHandle h in handles)
 {
     DestroyImmediate(h.handle.gameObject);
 }

Also make sure you store the handles List in your class in a member variable.

Comment
Add comment · Show 4 · 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 Bunny83 · Nov 11, 2014 at 06:40 PM 0
Share

Sorry, I forgot to add the VertHandle instance to the result list. Added the it in line 24!

It works for me. If i "edit" the default cube i get 8 handles. However you should use ".shared$$anonymous$$esh" ins$$anonymous$$d of ".mesh" as .mesh will cause a memory leak as it duplicates the mesh. It's ment to be used at runtime only.

edit
You might want to create a copy of the mesh before starting editing it:

 mesh = ($$anonymous$$esh)Instantiate(mf.shared$$anonymous$$esh); // create copy
 mesh.name = mf.shared$$anonymous$$esh.name;  // keep the old name (removes the "(clone)")
 mf.shared$$anonymous$$esh = mesh; // use this mesh from now on

This might cause the mesh to "leak" as well since if the old mesh isn't used anymore by another object it's orphaned. When you save the scene Unity will notice you that the mesh has leaked. Unfortunately there's no clean way to detect that case.

Also I should mention that the mesh you're editing will be saved in the scene itself. Usually it's better to store it as asset in the project. But again that should be done from an editor script and not a runtime script with ExecuteInEdit$$anonymous$$ode.

avatar image DaiMangouDev · Nov 11, 2014 at 08:59 PM 0
Share

hey,i'm having trouble putting this together correctly . I dont understand the definition of ApplyChanges. how did you put this code together ? sorry i'm not used to this method of coding using lists. oh , and and thank you for the answer.

avatar image Bunny83 · Nov 11, 2014 at 10:00 PM 1
Share

@ruchmair:

I've put my test script on my dropbox

avatar image DaiMangouDev · Nov 12, 2014 at 12:47 AM 0
Share

Great, worked really well. I don't think i could have written it by myself . thanks again. I' going to edit it so that I can "select the verts" themselves and move them as I would in 3D modeling software , then I will share the code .

There is also the issue of mesh deformation when the script is place on an object . I'm going to work on making the verts "visible" and selectable first.

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Saving and applying an array of Vector3 velocities on an array of GameObjects 1 Answer

C# - Creating an Array of Vector 3s 2 Answers

Distribute terrain in zones 3 Answers

How do I find the farthest verts of a mesh relative to its object position and store them in an array 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