Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 entity476 · Nov 08, 2012 at 11:44 AM · collidermeshupdateproceduraldeform

Breaking down Unity's Procedural Example "sculpt vertices"

Taken from the "sculpt vertices" of the Unity's "Procedural Examples":

 function Update () {
 
     // When no button is pressed we update the mesh collider
     if (!Input.GetMouseButton (0))
     {
         // Apply collision mesh when we let go of button
         ApplyMeshCollider();
         return;
     }
         
     // Did we hit the surface?
     var hit : RaycastHit;
     var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
     if (Physics.Raycast (ray, hit))
     {
         var filter : MeshFilter = hit.collider.GetComponent(MeshFilter);
         if (filter)
         {
             // Don't update mesh collider every frame since physX
             // does some heavy processing to optimize the collision mesh.
             // So this is not fast enough for real time updating every frame
             if (filter != unappliedMesh)
             {
                 ApplyMeshCollider();
                 unappliedMesh = filter;
             }
             
             // Deform mesh
             var relativePoint = filter.transform.InverseTransformPoint(hit.point);
             DeformMesh(filter.mesh, relativePoint, pull * Time.deltaTime, radius);
         }
     }
 }
 
 function ApplyMeshCollider () {
     if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) {
         unappliedMesh.GetComponent(MeshCollider).mesh = unappliedMesh.mesh;
     }
     unappliedMesh = null;
 }

Could someone explain me the functionality of this piece of code? Especially the part of the mesh collider update. What exactly does and when? Which commands and under which sequence they function in order to hold it from not updating every frame?

I have examined the code thoroughly, but due to my minor programming level, I cannot understand some parts. Also by trying the example in run-time, I couldn't figure out the collider's behavior.

Thank you in advance Unity Community.

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
2
Best Answer

Answer by markpdolby · Nov 08, 2012 at 01:11 PM

 // When no button is pressed we update the mesh collider
     if (!Input.GetMouseButton (0))
     {
        // Apply collision mesh when we let go of button
        ApplyMeshCollider();
        return;
     }

Here the mesh collider is updated when the user is not pressing the left mouse button, however the mesh collider is only likely to be updated once as the function ApplyMeshCollider will only update the collider if the unappliedMesh is not null and it is set to null at the end of the function everytime. So what this essentially means is when the user lets go of the left mouse button the collider is updated at most one time, and the return statement means the rest of the code is not reached. When the user does press the left mouse button this section of the code is called:

 // Did we hit the surface?
     var hit : RaycastHit;
     var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
     if (Physics.Raycast (ray, hit))
     {
        var filter : MeshFilter = hit.collider.GetComponent(MeshFilter);
        if (filter)
        {
          // Don't update mesh collider every frame since physX
          // does some heavy processing to optimize the collision mesh.
          // So this is not fast enough for real time updating every frame
          if (filter != unappliedMesh)
          {
           ApplyMeshCollider();
           unappliedMesh = filter;
          }
 
          // Deform mesh
          var relativePoint = filter.transform.InverseTransformPoint(hit.point);
          DeformMesh(filter.mesh, relativePoint, pull * Time.deltaTime, radius);
        }
     }

This bit of code is doing the following; create a ray cast from the point of the mouse cursor (best way to imagine it is sending out a laser from your cursor which can hit objects in the scene), then check if the ray cast has hit anything in the scene, if it has hit something then try to get the mesh filter of that object, if the object does have a mesh filter then check if the two meshes are the same mesh (So if the deformed mesh you want to apply is the same as the current mesh then dont update the collider), if the two meshes are different then give the collider the new mesh and set the unapplied mesh to null.

I hope that clears a few things up for you.

EDIT: Ok so I managed to get the mesh collider to update properly, it probably isn't the base way to do it but hopefully you can build on it from there:

 var CanUpdate = false;
 
 
 function ApplyMeshCollider () {
     
     if (unappliedMesh && unappliedMesh.GetComponent(MeshCollider)) {
         if(CanUpdate)
         {
             unappliedMesh.GetComponent(MeshCollider).sharedMesh = null;
         }
         unappliedMesh.GetComponent(MeshCollider).sharedMesh = unappliedMesh.sharedMesh;
     }
     //unappliedMesh = null;
     CanUpdate = !CanUpdate;
 }

So try placing the variable at the top of the script with the rest and replacing the ApplyMeshCollider function with my one and see if that gives a better result.

Comment
Add comment · Show 6 · 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 entity476 · Nov 08, 2012 at 06:59 PM 0
Share

That definitely clears more than a few things up! Thank you markpdolby for taking the time so soon to enlighten me. However, I apologize to say that I have some further questions (that probably exist because of my unawareness and not your explanations of course).

Therefore, I'd like to be more specific and also explain what I meant by "collider's behavior" at the first post, which I didn't want to overcrowd with text. So, and I don't know if you're familiar with the particular unity's example, here's what I see now: We have the mesh (this sphere in particular) and when we click on it, there's some deformation to the mesh. The collider is also updated (note: after this very first click) to "follow" the new mesh. I can see that by disabling the $$anonymous$$esh Renderer in the Inspector, so the $$anonymous$$esh Collider (green mesh) appears to agree with the deformed mesh. However, when I click again on the sphere, the mesh is deformed again, but now the Collider remains at the previous state (after the first deformation). I noticed that when I disable and then enable back the $$anonymous$$esh Collider (in the Inspector), the Collider takes the latest deformed mesh.

As far as I could explain the above, considering your explanations: At first the mesh filter is null and the Collider is not updated (the If() statement in the Apply$$anonymous$$eshCollider function is not fulfilled). From now on I am not sure if I follow well: Since we click on the mesh (translated of course that the ray cast "finds" the mesh), which is the same with the current (thus the Collider updating is skipped), the Deform$$anonymous$$esh function deforms it. While the Update function keeps executing and while the mouse button is still pressed, it is found that now the new mesh is different, but the unapplied$$anonymous$$esh is still null, so the collider is not updated, though the unapplied$$anonymous$$esh is set to the new mesh. When the mouse button is released, however, the unapplied$$anonymous$$esh is not null anymore and the collider is updated (the If() statement in the Apply$$anonymous$$eshCollider function is now fulfilled).

But then I don't understand why the Apply$$anonymous$$eshCollider function is called when the mouse button is pressed, since the collider is not updated (because the unapplied$$anonymous$$esh will be set to null). Also, why the collider doesn't seem to get updated a second time (after the mesh has been deformed again), so that someone could manipulate the already displaced vertices again. And how's that related to the fact that the Collider is updated, when I dis/enable the component in the Inspector.

I would really need this extra information, though I don't see why your answer wouldn't be already marked as correct. $$anonymous$$oreover, sorry that took me so much time to comment back, but I was trying to realise what I have understood anymore, after your answer. Thank you again! And I hope I have not confused you.

avatar image markpdolby · Nov 09, 2012 at 10:22 AM 0
Share

I have been looking into the scene myself and I am having the same problems as you are, I get the feeling that it might of worked for the Unity version at the time the tutorial was released but something in the recent version has broken it. The reason I believe this is the case is because for the $$anonymous$$eshCollider they use .mesh which has been depreciated for .shared$$anonymous$$esh (http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$eshCollider-shared$$anonymous$$esh.html) I will have a look at the code and see if there is a way to update the mesh collider properly in the current version of unity.

avatar image markpdolby · Nov 09, 2012 at 10:43 AM 0
Share

Updated my answer with a potential fix for updating the mesh collider properly.

avatar image entity476 · Nov 09, 2012 at 01:46 PM 0
Share

Oh, thank you that's great! I will make some tests with your new code during the day (or tomorrow). Then I'll come back with my findings. So far I just dropped two lines disabling and enabling the Collider component, but this gives a pause, until the new collider is built, for meshes with quite a lot vertices. But your contribution seems more sophisticated. I really appreciate it that you took the time to look into it and answer back!

EDIT: I hate markpdolby to disturb you again, but could you please explain me the workflow/logic of your new suggestion on the Apply$$anonymous$$eshCollider function (line by line if possible...)? I couldn't figure out myself no matter how much I tried...

avatar image markpdolby · Nov 12, 2012 at 04:14 PM 1
Share

function Apply$$anonymous$$eshCollider () {

 if (unapplied$$anonymous$$esh && unapplied$$anonymous$$esh.GetComponent($$anonymous$$eshCollider)) {
    unapplied$$anonymous$$esh.GetComponent($$anonymous$$eshCollider).shared$$anonymous$$esh = null;
    unapplied$$anonymous$$esh.GetComponent($$anonymous$$eshCollider).shared$$anonymous$$esh = unapplied$$anonymous$$esh.shared$$anonymous$$esh;
 }

}

Turns out that you dont actually need the CanUpdate part, so what I am doing here is essentially mimicking the turning on and off of the mesh collier in the editor which was giving the correct collider outline. Hope that clears it up a bit.

Show more comments

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

11 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

Related Questions

Why attach a kinematic rigidbody to a collider that moves a lot? 1 Answer

Turn Off Mesh.Bake Scaled Mesh PhysX CollisionData ? 0 Answers

Trouble with Inaccurate Mesh Collider 0 Answers

Shared Meshes, do they auto-update? 0 Answers

How to assign procedural mesh to a collider 6 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