Search Unity

[SOLVED] Problem with mesh collider in Skiing game

Discussion in 'Physics' started by glennseso, Apr 14, 2016.

  1. glennseso

    glennseso

    Joined:
    Nov 11, 2011
    Posts:
    34
    Hello there,

    I’m working in a 3D ski game, trying to achieve the best physics as possible.

    The engine itself is working pretty good using Terrains, but i’m considering to change to 3d models to have more details in the ground and etc.

    Even if I don’t change the Terrain for a 3d mesh terrain I still having another problem. When I want to create a ramp for jumps in instance.

    With a unity Terrain and a 3d ramp (mesh) the character stumbles when he tries to go into it.

    To solve this I tried to create a simple plane in 3dsMax, exported, so I split in 16 separated parts, but I didn’t moved it a millimeter and exported again.

    I created a test scene:

    http://gameronline.com.br/test/WebGLTest/

    The left plane is in one piece, the right one is in 16 separated pieces.

    I added in the left one a MeshCollider and in the right one I added one MeshCollider in each part.

    As you can see, even if the separated models (right one) have each part positioned “perfectly”, the box don’t behave the same.

    Just to explain why I want to use this separated model I made this test.

    I created 2 spheres in 3dsMax. One under Unity polys limit and another with a higher number than the limit.

    http://gameronline.com.br/test/Sphere1.png

    As you can see, Unity “breaks” the model in 3 parts, so each part have the maximum limit.

    http://gameronline.com.br/test/Sphere2.png

    This is the problem I tried to explain in the example above. If I have a big map, with a lot of details and the ground in one piece, it would work with my ski engine, but i’ll have that “stumble” problem.

    I thought in maybe work in a system to create a welded version of the above the skier.

    This new Minecraft feature can show what I tried to explain.



    In Snow, the terrain is huge and seems seamless. Snow was made in Cry Engine, so I’m not sure how it works.



    Is there any way to do something like this in Unity?

    Here is the project:

    https://www.dropbox.com/s/l8ruuejq9rdr7p7/CollisionTest.zip?dl=0

    Thanks in advance.
     
  2. glennseso

    glennseso

    Joined:
    Nov 11, 2011
    Posts:
    34
    Hello there,

    I would like to thank those who took time to read is long message :)

    I finally was able to solve this problem and I want to share the solution.

    Here's the test working:
    http://gameronline.com.br/test/WebGLTestWorking/

    To solve this I created 2 scripts:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent (typeof(MeshFilter))]
    6. [RequireComponent (typeof(MeshRenderer))]
    7. [RequireComponent (typeof(MeshCollider))]
    8. public class CombineMesh : MonoBehaviour
    9. {
    10.     static public CombineMesh Singleton;
    11.     public List<CombineInstance> combine;
    12.  
    13.     public int numberOfMeshes = 0;
    14.  
    15.     public List<MeshFilter> meshes;
    16.  
    17.     void Awake ()
    18.     {
    19.         Singleton = this;
    20.     }
    21.  
    22.     void Start ()
    23.     {
    24.         combine = new List<CombineInstance> ();
    25.     }
    26.  
    27.     public void UpdateMeshColliders (MeshFilter mesh)
    28.     {
    29.         meshes.Add (mesh);
    30.  
    31.         CombineInstance ci = new CombineInstance ();
    32.         ci.mesh = mesh.sharedMesh;
    33.         ci.transform = Matrix4x4.TRS(mesh.transform.position,mesh.transform.rotation,mesh.transform.localScale);// and the localPosition, localRotation and localScale of the child object.
    34.         combine.Add (ci);
    35.  
    36.         mesh.gameObject.active = false;
    37.  
    38.         transform.GetComponent<MeshFilter> ().mesh = new Mesh ();
    39.         transform.GetComponent<MeshFilter> ().mesh.CombineMeshes (combine.ToArray (), true, true);
    40.         transform.gameObject.active = true;
    41.         GetComponent<MeshCollider> ().sharedMesh = GetComponent<MeshFilter> ().sharedMesh;
    42.     }
    43. }
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MeshEntity : MonoBehaviour
    5. {
    6.  
    7.     void OnTriggerEnter (Collider other)
    8.     {
    9.         CombineMesh.Singleton.UpdateMeshColliders (this.GetComponent<MeshFilter>());
    10.     }
    11. }
    12.  
    I added CombineMesh to a empty game object and one MeshEntity for each mesh I want to add in the new mesh collider.

    Hope it help someone else.