How do I create a box (or even in a sphere or capsule)in which objects that are placed inside will stay and can’t get out, and will bounce from wall to wall? using c#
You cannot do it with a box, capsule, or sphere collider. It is possible to create a mesh collider in the shape of a box, sphere, or capsule and a mesh collider to do the job. Meshes (and therefore colliders) are one sided. For example imagine you had a plane as a floor that your object hit. If you flipped the plane over, the object would pass right through.
This questions come up occasionally. Usually I refer the asker to the [ReverseNormals script in the Unity Wiki.][1] But I took a bit of time and wrote an editor script that creates a cloned object with reversed normals. To get what you want do the following:
- Copy and past the editor script below into a file named ‘ReverseNormals.cs’.
- Place that script in the Assets/Editor folder
- Do GameObject > CreateOther > Cube (or whatever object you want to use).
- Remove the collider from the object by clicking on the gear menu in the upper right corner of the collider component and selecting ‘Remove Component’.
- Select the created object in the hierarchy.
- Select Window/Reverse Normals.
- Delete the original object (the duplicate will have ‘clone’ in the name).
- With the clone object selected, do Component > Physics > Mesh Collider
Note if you have a standard setup with the camera looking at the outside of the object, you now backside of the inside of the object. Unless you use a shader with backface culling turned off, you now need to move your camera inside the object to see all the walls. You could turn off the renderer of the object and have an object bounce around inside an invisible object.
Here is the editor script:
using UnityEngine;
using UnityEditor;
public class ReverseNormals : EditorWindow {
private string error = "";
[MenuItem("Window/Reverse Normals")]
public static void ShowWindow() {
EditorWindow.GetWindow(typeof(ReverseNormals));
}
void OnGUI() {
//Transform curr = Selection.activeTransform;
GUILayout.Label ("Creates a clone of the game object with with
" +
“the normals reversed”);
GUILayout.Space(20);
if (GUILayout.Button ("Reverse Normals")) {
error = "";
ReverseTheNormals();
}
GUILayout.Space(20);
GUILayout.Label(error);
}
void ReverseTheNormals() {
Transform curr = Selection.activeTransform;
MeshFilter mf;
if (curr == null) {
error = "No appropriate object selected.";
Debug.Log (error);
return;
}
mf = curr.GetComponent<MeshFilter>();
if (mf == null || mf.sharedMesh == null) {
error = "No mesh on the selected object";
Debug.Log (error);
return;
}
// Create the duplicate game object
GameObject go = Instantiate (curr.gameObject) as GameObject;
mf = go.GetComponent<MeshFilter>();
mf.sharedMesh = Instantiate (mf.sharedMesh) as Mesh;
curr = go.transform;
// Fix the normals
Vector3[] normals = mf.sharedMesh.normals;
if (normals != null) {
for (int i = 0; i < normals.Length; i++)
normals _= -normals*;*_
* }*
* mf.sharedMesh.normals = normals;*
* // Reverse the triangles*
* for (int i = 0; i < mf.sharedMesh.subMeshCount; i++)*
* {*
* int[] triangles = mf.sharedMesh.GetTriangles(i);*
* for (int j = 0; j < triangles.Length; j += 3)*
* {*
* int temp = triangles[j];*
* triangles[j] = triangles[j + 1];*
* triangles[j + 1] = temp;*
* }*
* mf.sharedMesh.SetTriangles(triangles, i);*
* }*
* // Set selection to new game object*
* Selection.activeObject = curr.gameObject;*
* // Save a copy to disk*
* string name = “Assets/Editor/”+go.name+Random.Range (0, int.MaxValue).ToString()+“.asset”;*
* AssetDatabase.CreateAsset(mf.sharedMesh, name);*
AssetDatabase.SaveAssets();
* }*
}
Note that getting something to bounce around inside the object will require you to setup the colliders of both the container and the object bouncing to have a bouncy physic material. You can get a selection of physic materials from:
Assets > Import Package > Physic Materials
And these go on the Colliders components of both objects.