Search Unity

Rubber Simulation Script

Discussion in 'Scripting' started by pegorari, Apr 1, 2010.

  1. pegorari

    pegorari

    Joined:
    Nov 19, 2009
    Posts:
    60
    Hello guys,

    I made a small script that simulates Rubber, like 3dsMax flex modifier does, but using vertex colors to set the effect intensity.

    Besides rubber objects, can also help to make more realistic the character animation, with some gravity, elasticity and inertia on some mesh part, like a big belly when moving.

    I hope you enjoy!


    Browser example: http://bit.ly/cQMs4h


    Code (csharp):
    1.  
    2. /* ******************************************************************************************************* *
    3.  * RUBBER EFFECT                                                                                           *
    4.  * You need to set the Vertex Colors of your 3d model, on your prefered 3d Modelling Tool                  *
    5.  * by Rodrigo Pegorari - 2010 - [url]http://rodrigopegorari.net[/url]                                                 *
    6.  * based on the Processing 'Chain' code example ([url]http://www.processing.org/learning/topics/chain.html[/url])     *
    7.  * ******************************************************************************************************* */
    8.  
    9. using UnityEngine;
    10. using System.Collections;
    11.  
    12. public class RubberEffect : MonoBehaviour
    13. {
    14.  
    15.     public RubberType Presets;
    16.  
    17.     public enum RubberType
    18.     {
    19.         Custom,
    20.         RubberDuck,
    21.         HardRubber,
    22.         Jelly,
    23.         SoftLatex
    24.     }
    25.  
    26.     public float EffectIntensity = 1;
    27.     public float gravity = 0;
    28.     public float damping = 0.7f;
    29.     public float mass = 1;
    30.     public float stiffness = 0.2f;
    31.    
    32.  
    33.     private Mesh WorkingMesh;
    34.     private Mesh OriginalMesh;
    35.     private float[] ColorIntensity;
    36.     private VertexRubber[] vr;
    37.  
    38.     internal class VertexRubber
    39.     {
    40.         public float v_gravity;
    41.         public float v_mass;
    42.         public float v_stiffness;
    43.         public float v_damping;
    44.         public Vector3 pos;
    45.  
    46.         Vector3 vel = new Vector3();
    47.  
    48.         public VertexRubber(Vector3 v_target, float m, float g, float s, float d)
    49.         {
    50.             v_gravity = g;
    51.             v_mass = m;
    52.             v_stiffness = s;
    53.             v_damping = d;
    54.  
    55.             pos = v_target;
    56.         }
    57.  
    58.         public void update(Vector3 target)
    59.         {
    60.  
    61.             Vector3 force = new Vector3();
    62.             Vector3 acc = new Vector3();
    63.  
    64.             force.x = (target.x - pos.x) * v_stiffness;
    65.             acc.x = force.x / v_mass;
    66.             vel.x = v_damping * (vel.x + acc.x);
    67.             pos.x += vel.x;
    68.  
    69.             force.y = (target.y - pos.y) * v_stiffness;
    70.             force.y -= v_gravity / 10;
    71.             acc.y = force.y / v_mass;
    72.             vel.y = v_damping * (vel.y + acc.y);
    73.             pos.y += vel.y;
    74.  
    75.             force.z = (target.z - pos.z) * v_stiffness;
    76.             acc.z = force.z / v_mass;
    77.             vel.z = v_damping * (vel.z + acc.z);
    78.             pos.z += vel.z;
    79.  
    80.         }
    81.  
    82.     }
    83.  
    84.    
    85.     void Start(){
    86.  
    87.         Debug.Log(Presets);
    88.         MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter));
    89.         OriginalMesh = filter.sharedMesh;
    90.  
    91.         WorkingMesh = Instantiate(filter.sharedMesh) as Mesh;
    92.         filter.sharedMesh = WorkingMesh;
    93.  
    94.         ColorIntensity = new float[OriginalMesh.vertices.Length];
    95.  
    96.         vr = new VertexRubber[OriginalMesh.vertices.Length];
    97.  
    98.         for (int i = 0; i < OriginalMesh.vertices.Length; i++)
    99.         {
    100.             ColorIntensity[i] = (1 - ((OriginalMesh.colors[i].r + OriginalMesh.colors[i].g + OriginalMesh.colors[i].b) / 3)) * EffectIntensity;
    101.             vr[i] = new VertexRubber(transform.TransformPoint(OriginalMesh.vertices[i]), mass, gravity, stiffness, damping);
    102.         }
    103.  
    104.     }
    105.  
    106.  
    107.     void Update()
    108.     {
    109.  
    110.         checkPreset();
    111.  
    112.         Vector3[] V3_WorkingMesh = OriginalMesh.vertices;
    113.  
    114.  
    115.         for (int i = 0; i < V3_WorkingMesh.Length; i++)
    116.         {
    117.             if (!float.Equals(ColorIntensity[i],0f)){
    118.  
    119.                 Vector3 v3_target = transform.TransformPoint(V3_WorkingMesh[i]);
    120.  
    121.                 vr[i].v_gravity = gravity;
    122.                 vr[i].v_mass = mass;
    123.                 vr[i].v_stiffness = stiffness;
    124.                 vr[i].v_damping = damping;
    125.  
    126.                 vr[i].update(v3_target);
    127.  
    128.                 v3_target = transform.InverseTransformPoint(vr[i].pos);
    129.  
    130.                 V3_WorkingMesh[i] = Vector3.Lerp(V3_WorkingMesh[i], v3_target, ColorIntensity[i] * EffectIntensity);
    131.  
    132.             }
    133.  
    134.         }
    135.  
    136.         WorkingMesh.vertices = V3_WorkingMesh;
    137.         WorkingMesh.RecalculateBounds();
    138.  
    139.     }
    140.  
    141.     void checkPreset() {
    142.            
    143.         switch (Presets)
    144.         {
    145.             case RubberType.HardRubber:
    146.                 gravity = 0f;
    147.                 mass = 8f;
    148.                 stiffness = 0.5f;
    149.                 damping = 0.9f;
    150.                 EffectIntensity = 0.5f;
    151.                 break;
    152.             case RubberType.Jelly:
    153.                 gravity = 0f;
    154.                 mass = 1f;
    155.                 stiffness = 0.95f;
    156.                 damping = 0.95f;
    157.                 EffectIntensity = 1f;
    158.                 break;
    159.             case RubberType.RubberDuck:
    160.                 gravity = 0f;
    161.                 mass = 2f;
    162.                 stiffness = 0.5f;
    163.                 damping = 0.85f;
    164.                 EffectIntensity = 1f;
    165.                 break;
    166.             case RubberType.SoftLatex:
    167.                 gravity = 1f;
    168.                 mass = 0.9f;
    169.                 stiffness = 0.3f;
    170.                 damping = 0.25f;
    171.                 EffectIntensity = 1f;
    172.                 break;
    173.         }
    174.    
    175.     }
    176.  
    177. }
    178.  
    179.  
     
  2. Peter G

    Peter G

    Joined:
    Nov 21, 2009
    Posts:
    610
    Awesome :D
     
  3. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
  4. the_gnoblin

    the_gnoblin

    Joined:
    Jan 10, 2009
    Posts:
    722
    Thank you!
    Very useful and makes people smile ).
     
  5. caitlyn

    caitlyn

    Joined:
    Jun 20, 2008
    Posts:
    402
    Great job!

    I've been looking for a quick and easy way to do this myself in my free time, without resorting to joints and colliders. Thanks for a wonderful share with the community.

    BTW the project package link on your site is borked. ;)
     
  6. pegorari

    pegorari

    Joined:
    Nov 19, 2009
    Posts:
    60
    I'm glad you like it, guys!

    Caitlyn: the package link is ok now, thanks!
     
  7. Ony

    Ony

    Joined:
    Apr 26, 2009
    Posts:
    1,977
    Just found this and it works great, thanks!
     
  8. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I had forgotten about this script. I wonder if it might somehow be used with a ragdoll to make interaction with it more realistic... hmmm...
     
  9. Peter G

    Peter G

    Joined:
    Nov 21, 2009
    Posts:
    610
    Or you can use soft bodies with Unity 3.
     
  10. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    The soft bodies in Unity 3 are more like "deflated bodies"... :(

    This rubber duck is much nicer.

    But I couldn't get it to work with a model of my own. The mesh just shattered (made in Blender).
    Any tips on what the limitations are for a mesh to use with this script?
     
  11. Adamo

    Adamo

    Joined:
    Dec 17, 2010
    Posts:
    55
    9.95/10 Ecellent!!
    Thank you for sharing!
     
  12. Artimese

    Artimese

    Joined:
    Nov 22, 2009
    Posts:
    794
    Genius.... i love it! works perfectly!
     
  13. gedo831

    gedo831

    Joined:
    Apr 22, 2011
    Posts:
    1
    Is there any way to apply this rubber effect to an animated object?
     
  14. Fishypants

    Fishypants

    Joined:
    Jan 25, 2009
    Posts:
    444
    This is super awesome! Is there a way to modify it to work with bone rotation only? Say you have a character with a pony tail, and you wanted the bones rotation to be effected by inertia?
     
  15. Ravel

    Ravel

    Joined:
    Nov 21, 2010
    Posts:
    605
    coulc you possibly make a "metal body" example? If its possible ofcourse
     
  16. JohnV2017

    JohnV2017

    Joined:
    Aug 18, 2017
    Posts:
    1
    Hi, does he work in Maya ?
     
  17. artmanyogi

    artmanyogi

    Joined:
    Sep 12, 2017
    Posts:
    1
    how do you load this script into 3ds max?
     
  18. juanrosero1407

    juanrosero1407

    Joined:
    Sep 8, 2018
    Posts:
    1
    Hello!! , I need to do something like that, but when a sphere collides with the duck, how can I do this? Thanks for your answer.
     
  19. raobott

    raobott

    Joined:
    Jan 30, 2015
    Posts:
    1
    how to make this script work?
     
  20. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,634
    What problems are you having? Do you have errors? The script is almost 10 years old so there may be things that need to be updated to current API.
     
  21. Altum

    Altum

    Joined:
    Dec 24, 2013
    Posts:
    1
    It works fine in Unity 2021.3.20f1. You just need to make read/write available in settings of the exported mesh. And also don't forget to vertex paint you mesh before exporting in Unity.