Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Bugs with my ship building collision system

Discussion in 'Scripting' started by kennethrunescape2019, Dec 27, 2019.

  1. kennethrunescape2019

    kennethrunescape2019

    Joined:
    Feb 5, 2019
    Posts:
    109
    I have been trying to make a ship building game where player's can build their own ship out of blocks.

    Here how the collision system currently works:

    The ship mesh and the ship rigidbody are two separate objects. The script on the mesh is coded to make the ship mesh copy the movements of the rigidbody. When something comes in contact with the ship mesh, it spawns a "ghost cube" on the rigidbody at the location of the block that was collided with on the mesh.

    These ghost cubes consist of nothing but a box collider and are used in place of a mesh collider on the rigidbody (because unity no longer supports non-convex colliders on non-kinematic rigidbodies).

    Ghost cubes are set to despawn after 3 seconds after a collision as to prevent the game from being overwhelmed by large numbers of ghost cubes. The problem is after the ghost cube despawns, the collider on the mesh no longer seems to detect collision with the object touching it unless it backs off and hits it again, therefore not spawning another ghost cube in the place of the old one. Can someone please help me?

    Code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GhostCube : MonoBehaviour
    6. {
    7.  
    8.     public GameObject ghostCube;
    9.     public float timer = 3.0f;
    10.  
    11.     private void Update()
    12.     {
    13.         timer = Mathf.Clamp(timer, 0.0f, 3.0f);
    14.         if(timer > 0)
    15.         {
    16.             timer -= 1 * Time.deltaTime;
    17.         } else
    18.         {
    19.             destroyGhostCube();
    20.         }
    21.     }
    22.     public void destroyGhostCube ()
    23.     {
    24.         Destroy(ghostCube);
    25.     }
    26. }
    27.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [System.Serializable]
    6. public class ShipCore : MonoBehaviour
    7. {
    8.  
    9.     [System.Serializable]
    10.     public class ShipBlueprint
    11.     {
    12.         public List<ShipBuildableData> buildables;
    13.     }
    14.     public ShipBlueprint blueprint;
    15.  
    16.     public MeshRenderer meshRenderer;
    17.     public MeshFilter meshFilter;
    18.     public MeshCollider shipCollider;
    19.  
    20.     int vertexIndex = 0;
    21.  
    22.     List<Vector3> vertices = new List<Vector3>();
    23.     List<int> triangles = new List<int>();
    24.     List<Vector2> uvs = new List<Vector2>();
    25.  
    26.     public Rigidbody body;
    27.     ShipBody bodyScript;
    28.  
    29.     public GameObject ghostCubePrefab;
    30.     public List<GhostCube> ghosts = new List<GhostCube>();
    31.  
    32.     private void Start()
    33.     {
    34.         bodyScript = body.GetComponent<ShipBody>();
    35.         initShip();
    36.         createMesh();
    37.     }
    38.  
    39.     private void Update()
    40.     {
    41.         transform.position = body.transform.position;
    42.         transform.rotation = body.transform.rotation;
    43.         if(bodyScript != null)
    44.         {
    45.             ghosts = bodyScript.ghosts();
    46.         }
    47.     }
    48.  
    49.     private void updateShip()
    50.     {
    51.  
    52.     }
    53.  
    54.     private void initShip ()
    55.     {
    56.         for(int b = 0; b < blueprint.buildables.Count; b++)
    57.         {
    58.             addVoxel(blueprint.buildables[b].pos);
    59.         }
    60.     }
    61.  
    62.     private void addVoxel (Vector3 pos)
    63.     {
    64.         for(int f = 0; f < 6; f++)
    65.         {
    66.             if(!checkVoxel(pos + VoxelDataShip.faceChecks[f]))
    67.             {
    68.                 vertices.Add(pos + VoxelDataShip.voxelVerts[VoxelDataShip.voxelTris[f, 0]]);
    69.                 vertices.Add(pos + VoxelDataShip.voxelVerts[VoxelDataShip.voxelTris[f, 1]]);
    70.                 vertices.Add(pos + VoxelDataShip.voxelVerts[VoxelDataShip.voxelTris[f, 2]]);
    71.                 vertices.Add(pos + VoxelDataShip.voxelVerts[VoxelDataShip.voxelTris[f, 3]]);
    72.  
    73.                 addTexture(blueprint.buildables[0].GetTextureID(f));
    74.  
    75.                 triangles.Add(vertexIndex);
    76.                 triangles.Add(vertexIndex + 1);
    77.                 triangles.Add(vertexIndex + 2);
    78.                 triangles.Add(vertexIndex + 2);
    79.                 triangles.Add(vertexIndex + 1);
    80.                 triangles.Add(vertexIndex + 3);
    81.                 vertexIndex += 4;
    82.             }
    83.         }
    84.     }
    85.  
    86.     private bool checkVoxel (Vector3 pos)
    87.     {
    88.         int checkIndex = blueprint.buildables.FindIndex(ci => ci.pos == pos);
    89.         if(checkIndex != -1)
    90.         {
    91.             if(blueprint.buildables[checkIndex].isSolid == true && blueprint.buildables[checkIndex].destroyed == false)
    92.             {
    93.                 return true;
    94.             }
    95.         }
    96.         return false;
    97.     }
    98.  
    99.     private void createMesh ()
    100.     {
    101.         Mesh mesh = new Mesh();
    102.         mesh.vertices = vertices.ToArray();
    103.         mesh.triangles = triangles.ToArray();
    104.         mesh.uv = uvs.ToArray();
    105.  
    106.         mesh.RecalculateNormals();
    107.  
    108.         meshFilter.mesh = mesh;
    109.  
    110.         shipCollider.sharedMesh = mesh;
    111.     }
    112.  
    113.     void addTexture (int textureID)
    114.     {
    115.         float y = textureID / 16;
    116.         float x = textureID - (y * 16);
    117.  
    118.         x *= 1f / (float)16;
    119.         y *= 1f / (float)16;
    120.  
    121.         y = 1f - y - (1f / (float)16);
    122.  
    123.         uvs.Add(new Vector2(x, y));
    124.         uvs.Add(new Vector2(x, y + (1f / (float)16)));
    125.         uvs.Add(new Vector2(x + (1f / (float)16), y));
    126.         uvs.Add(new Vector2(x + (1f / (float)16), y + (1f / (float)16)));
    127.  
    128.     }
    129.  
    130.     //Ghost cubes are simply colliders added to the rigidbody:
    131.     private void spawnGhostCube (Vector3 pos)
    132.     {
    133.         GameObject newCube = Instantiate(ghostCubePrefab, transform.position, transform.rotation) as GameObject;
    134.         newCube.transform.parent = body.transform;
    135.         newCube.transform.localPosition = pos;
    136.     }
    137.  
    138.     private Vector3 getGhostPos (Vector3 colPos)
    139.     {
    140.         Vector3 contactRelative = transform.InverseTransformPoint(colPos);
    141.         Vector3 contactRounded = new Vector3(Mathf.Round(contactRelative.x), Mathf.Round(contactRelative.y), Mathf.Round(contactRelative.z));
    142.         for(int c = 0; c < blueprint.buildables.Count; c++)
    143.         {
    144.             if(blueprint.buildables[c].pos == contactRounded)
    145.             {
    146.                 return blueprint.buildables[c].pos;
    147.             }
    148.         }
    149.         return new Vector3(1000, 1000, 1000);
    150.     }
    151.  
    152.     private void OnCollisionEnter (Collision collision)
    153.     {
    154.         if(collision.collider.gameObject.tag != "Ghost Cube")
    155.         {
    156.             Vector3 ghostPos = getGhostPos(collision.contacts[0].point);
    157.             if (ghostPos != new Vector3(1000, 1000, 1000))
    158.             {
    159.                 int existingPos = ghosts.FindIndex(p => p.transform.localPosition == ghostPos);
    160.                 if (existingPos == -1)
    161.                 {
    162.                     spawnGhostCube(ghostPos);
    163.                 }
    164.             }
    165.         }
    166.     }
    167. }
    168.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ShipBody : MonoBehaviour
    6. {
    7.     public List<GhostCube> ghosts ()
    8.     {
    9.         List<GhostCube> ghostCubes = new List<GhostCube>();
    10.         GhostCube[] ghostCubesArray = GetComponentsInChildren<GhostCube>();
    11.         for(int g = 0; g < ghostCubesArray.Length; g++)
    12.         {
    13.             ghostCubes.Add(ghostCubesArray[g]);
    14.         }
    15.         return ghostCubes;
    16.     }
    17. }
    18.  
     
    Last edited: Dec 27, 2019
  2. kennethrunescape2019

    kennethrunescape2019

    Joined:
    Feb 5, 2019
    Posts:
    109
    Is there something wrong with my code or project? Or is this a bug on unity's part?