/// <summary> /// Called when a shot has a collision. /// Checks all registered hittables with the provided shot data to see which one was hit. /// </summary> /// <param name="shot"></param> public void OnShotHit(HitData hitData, Color color) { //combine removing with adding Vector3?hitToOverwrite = (!hitLimitReached)? (Vector3?)null : hits[hitIndex]; //global resultant - sum of all normalized resultants per hittable //resultant per hittable = sum of all triangles' (intersecting and not culled) normals Vector3 hitResultant; //if we have hits if (CheckAndStartSetup(hitData, out hitResultant, hitToOverwrite)) { /* //get a random color * Color color = new Color(Random.Range(0f, .9f), Random.Range(0f, .9f), Random.Range(0f, .9f), 1f);*/ //get transform matrix Matrix4x4 shotSpaceTRS = GetShotSpaceTRSMatrix(hitData, -hitResultant); foreach (Hittable hittable in hittables) { //set rest of data hittable.EndHitSetup(shotSpaceTRS, color); //check again for removal - non-hit ones were not checked if (hitLimitReached) { hittable.Clear(hitToOverwrite.Value); } } //store current hit hits[hitIndex++] = hitData.Position; //check if limit reached if (hitIndex == MAX_MARKS) { hitIndex = 0; hitLimitReached = true; } } }
/// <summary> /// Starts the setup for a new hit: /// - culls the detected triangles according to the current cull angle. /// - if any left, ads a new submesh and assigns culled triangles to it (or replaces an old one in case limit of hits was reached). /// - creates the hit material which will be have the data set in EndHitSetup. /// </summary> /// <param name="hitData">Current shot data.</param> /// <param name="hitToReplace">Hit location which will be overwritten by the new hit.</param> /// <returns>Resultant vector from non-culled triangles.</returns> public Vector3 StartHitSetup(HitData hitData, Vector3?hitToReplace) { //submesh triangles int[] submeshTris; //cull triangles based on hit direction and get resultant of rest of triangles' normal Vector3 resultant = FilterTris(hitData.Direction, out submeshTris);; //everything got culled if (submeshTris.Length == 0) { return(resultant); //Vector3.zero } //check if we 'have' the hit to replace int subMeshIndex = (hitToReplace.HasValue)? GetHitSubMeshIndex(hitToReplace.Value) : -1; //search for free slot if (subMeshIndex == -1 && emptySlots > 0) { subMeshIndex = materials.IndexOf(null); material = MaterialPooler.Instance.GetRandomBulletMaterial(renderer, this, hitData.Position); /* material = new Material(hitData.Mark);*/ materials[subMeshIndex] = material; hits[subMeshIndex - subMeshCountInitial] = hitData.Position; emptySlots--; } else { //if we have a hit to replace if (subMeshIndex != -1) { material = materials[subMeshIndex]; hits[subMeshIndex - subMeshCountInitial] = hitData.Position; hitOverwritten = true; } else //no hit to replace, create new { //save index subMeshIndex = mesh.subMeshCount; //make room fornew submesh mesh.subMeshCount++; material = MaterialPooler.Instance.GetRandomBulletMaterial(renderer, this, hitData.Position); /* //create mark material * material = new Material(hitData.Mark);*/ materials.Add(material); //store hit hits.Add(hitData.Position); } } //set the triangles of the new mark's submesh mesh.SetTriangles(submeshTris, subMeshIndex, false); return(resultant); }