Reputation: 189
I'm doing a puzzle game where I have a sphere made up of multiple mesh colliders as slots, and the player is supposed to move puzzle pieces(also mesh colliders) into contact with the sphere where they will stick to the mesh collider 'slot' they collided with. However, my script behaves strangely. It adheres sometimes, and on other times it floats off into the game world by itself. How would I get it to work?
Here's the sphere the puzzle pieces are supposed to stick to, and one of the puzzle pieces itself:
The sphere is composed of several meshes each with their own mesh collider. The irregularly shaped object on the left is one of the puzzle pieces. When the player moves it towards the sphere it should stick to the first mesh collider on the sphere it comes into contact with.
And here's my script:
using UnityEngine;
using System.Collections;
public class StickyObject : MonoBehaviour {
DragToMove1 otherScript;
GameObject mainObj, jigsphere;
bool stuck;
public LayerMask layerMask;
// Use this for initialization
void Start ()
{
otherScript = this.GetComponent<DragToMove1>();
mainObj = GameObject.Find("GameObject");
stuck = false;
}
// Update is called once per frame
void Update ()
{
if (stuck)
{
}
}
void OnCollisionEnter(Collision c)
{
if (!stuck)
{
//By contact point
ContactPoint touched = c.contacts[0];
Debug.Log ("Collision with " + this.name);
touched.otherCollider.gameObject.transform.parent = this.transform;
Debug.Log ("Parented to " + touched.otherCollider);
stuck = true;
if (otherScript != null)
{
otherScript.Stuck();
otherScript.selected = false;
}
mainObj.SendMessage ("Wake");
}
}
bool getStuck()
{
return stuck;
}
}
Upvotes: 1
Views: 9773
Reputation: 1
First of all, you create an empty GameObject which contains MeshFilter, MeshCollider, MeshRenderer, (Rigidbody if u need that for ur usecase). Then you gotta go and put that code what unity provided in the start method of the script.
https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class ExampleClass : MonoBehaviour
{
void Start()
{
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
int i = 0;
while (i < meshFilters.Length)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
i++;
}
transform.GetComponent<MeshFilter>().mesh = new Mesh();
transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);
transform.gameObject.SetActive(true);
}
}
but you add after CombineMeshes(combine) transform.GetComponent<MeshCollider>().sharedMesh = transform.GetComponent<MeshFilter>().mesh;
After that your combined mesh has also colliders
Upvotes: 0
Reputation: 2608
If they are floating off into space, you might want to try disabling the object's rigidbody once the piece has been "stuck". You can set its constraints so that it can't move or rotate in any direction.
Upvotes: 2
Reputation: 249
The mesh collider generates it's collision data from the actual mesh. So basically combining both meshes into one would generate the proper collider that you need.
You can either use the builtin CombineMeshes methods which does precisely that or you could do it manually.
There is an old script in the forums to do just that - link.
And if you do it yourself you will have to move all vertex data from one mesh into the other. Than you need to generate new triangles from the new vertex data. Besides if the meshes use two different texture you will need to merge those and remap the texture coordinates of one of them.
Upvotes: 1