public void SpawnEffect(ImpactTypes t, Vector3 pos, Quaternion rot) { var pool = ImpactEffectPools[(int)t]; var effect = pool.Get(); effect.myPool = pool; effect.transform.position = pos; effect.transform.rotation = rot; effect.gameObject.SetActive(true); var sound = effect.GetComponent <AudioSource>(); if (sound != null) { sound.Play(); } }
public void SpawnImpact(ImpactTypes t, Vector3 pos, Quaternion rot) { tno.SendQuickly("SpawnEffect", Target.All, t, pos, rot); }
public void Impact(Vector3 point, Vector3 force, ImpactShapes impactShape, ImpactTypes impactType) { // See if we can do this right now if (!CanDoImpact(point, force)) { return; } // We're now set on course to calculate the impact deformation m_Calculating = true; // Set up m_Hull InitializeHull(); // Figure out the true impact force if (force.magnitude > m_MaxForcePerImpact) { force = force.normalized * m_MaxForcePerImpact; } float impactFactor = (force.magnitude - m_ForceResistance) * m_ForceMultiplier; if (impactFactor <= 0) { return; } // Localize the point and the force to account for transform scaling (and maybe rotation or translation) Vector3 impactPoint = transform.InverseTransformPoint(point); Vector3 impactForce = transform.InverseTransformDirection(force.normalized) * impactFactor; // Limit the force by the extents of the initial bounds to keep things reasonable float impactForceX = Mathf.Max(Mathf.Min(impactForce.x, m_InitialBounds.extents.x), -m_InitialBounds.extents.x); float impactForceY = Mathf.Max(Mathf.Min(impactForce.y, m_InitialBounds.extents.y), -m_InitialBounds.extents.y); float impactForceZ = Mathf.Max(Mathf.Min(impactForce.z, m_InitialBounds.extents.z), -m_InitialBounds.extents.z); impactForce = new Vector3(impactForceX, impactForceY, impactForceZ); // Run the mesh deformation on another thread ThreadManager.RunAsync(() => { // Do all the math to deform this mesh m_Hull.Impact(impactPoint, impactForce, impactShape, impactType); // Queue the final mesh setting on the main thread once the deformations are done ThreadManager.QueueOnMainThread(() => { // Clear out the current Mesh and MeshCollider (if we have one) for now MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>(); if (meshFilter != null) { meshFilter.sharedMesh = null; } MeshCollider meshCollider = gameObject.GetComponent <MeshCollider>(); if (meshCollider != null) { meshCollider.sharedMesh = null; } // Get the newly-adjusted Mesh so we can work with it Mesh newMesh = m_Hull.GetMesh(); // If this is a fracture, then create a new GameObject for the chunk that broke off if (impactType == ImpactTypes.Fracture) { Mesh subHullMesh = m_Hull.GetSubHullMesh(); if (subHullMesh != null) { // Create the new GameObject GameObject newGO = (GameObject)GameObject.Instantiate(gameObject); // Set the new Mesh onto the MeshFilter and MeshCollider MeshFilter newMeshFilter = newGO.GetComponent <MeshFilter>(); MeshCollider newMeshCollider = newGO.GetComponent <MeshCollider>(); if (newMeshFilter != null) { newMeshFilter.sharedMesh = subHullMesh; } if (newMeshCollider != null) { newMeshCollider.sharedMesh = subHullMesh; } // If using convex MeshColliders, it's possible for colliders to overlap right after a // fracture, which causes exponentially more fractures... So, right after a fracture, // temporarily disable impacts to both the old GameObject, and the new one we just created DelayCollisions(); Meshinator subHullMeshinator = newGO.GetComponent <Meshinator>(); if (subHullMeshinator != null) { subHullMeshinator.DelayCollisions(); } // Figure out the approximate volume of our Hull and SubHull meshes. This // will be used to calculate the rigidbody masses (if a rigidbodies are present) // for the old and new GameObjects. if (gameObject.GetComponent <Rigidbody>() != null && newGO.GetComponent <Rigidbody>() != null) { Vector3 hullSize = newMesh.bounds.size; float hullVolume = hullSize.x * hullSize.y * hullSize.z; Vector3 subHullSize = subHullMesh.bounds.size; float subHullVolume = subHullSize.x * subHullSize.y * subHullSize.z; float totalVolume = hullVolume + subHullVolume; float totalMass = gameObject.GetComponent <Rigidbody>().mass; gameObject.GetComponent <Rigidbody>().mass = totalMass * (hullVolume / totalVolume); newGO.GetComponent <Rigidbody>().mass = totalMass * (subHullVolume / totalVolume); // Set the old velocity onto the new GameObject's rigidbody newGO.GetComponent <Rigidbody>().velocity = gameObject.GetComponent <Rigidbody>().velocity; // Set the centers of mass to be within the new meshes gameObject.GetComponent <Rigidbody>().centerOfMass = newMesh.bounds.center; newGO.GetComponent <Rigidbody>().centerOfMass = subHullMesh.bounds.center; } } } // Set the hull's new mesh back onto this game object if (meshFilter != null) { meshFilter.sharedMesh = newMesh; } // If this GameObject has a MeshCollider, put the new mesh there too if (meshCollider != null) { meshCollider.sharedMesh = newMesh; } // Drop our cached Hull if we're not supposed to keep it around if (m_CacheOption == CacheOptions.None) { m_Hull = null; } // Our calculations are done m_Calculating = false; }); }); }
public void Impact(Vector3 point, Vector3 impactDirection, Vector3 force, ImpactShapes impactShape, ImpactTypes impactType) { // See if we can do this right now if (!CanDoImpact(point, force)) { return; } // We're now set on course to calculate the impact deformation m_Calculating = true; // Set up m_Hull InitializeHull(); // Figure out the true impact force if (force.magnitude > m_MaxForcePerImpact) { force = force.normalized * m_MaxForcePerImpact; } float impactFactor = (force.magnitude - m_ForceResistance) * m_ForceMultiplier; if (impactFactor <= 0) { return; } // set impactpoint and impactforce to be used for debugging debugImpactPoint = point; // Localize the point and the force to account for transform scaling (and maybe rotation or translation) Vector3 impactPoint = transform.InverseTransformPoint(point); Vector3 impactForce = transform.InverseTransformDirection(force.normalized) * impactFactor; // Limit the force by the extents of the initial bounds to keep things reasonable float impactForceX = Mathf.Max(Mathf.Min(impactForce.x, m_InitialBounds.extents.x), -m_InitialBounds.extents.x); float impactForceY = Mathf.Max(Mathf.Min(impactForce.y, m_InitialBounds.extents.y), -m_InitialBounds.extents.y); float impactForceZ = Mathf.Max(Mathf.Min(impactForce.z, m_InitialBounds.extents.z), -m_InitialBounds.extents.z); impactForce = new Vector3(impactForceX, impactForceY, impactForceZ); //DEBUG if (debug) { debugImpactPoint = point; debugImpactForce = impactForce; // make sure the debug vertices are the same as the actual fractures Random.seed = 1; debugFractureVertices = createFractureVertices(impactDirection, impactForce, debugImpactPoint); Random.seed = 1; impactOccurred = true; } List <Vector3> fractureVertices = createFractureVertices(impactDirection, impactForce, impactPoint); // Run the mesh deformation on another thread ThreadManager.RunAsync(() => { // Do all the math to deform this mesh m_Hull.Impact(impactPoint, impactForce, impactShape, impactType, fractureVertices); // Queue the final mesh setting on the main thread once the deformations are done ThreadManager.QueueOnMainThread(() => { // Clear out the current Mesh and MeshCollider (if we have one) for now MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>(); if (meshFilter != null) { meshFilter.sharedMesh = null; } MeshCollider meshCollider = gameObject.GetComponent <MeshCollider>(); if (meshCollider != null) { meshCollider.sharedMesh = null; } // Get the newly-adjusted Mesh so we can work with it Mesh newMesh = m_Hull.GetMesh(impactPoint, impactForce.magnitude, fractureVertices); // Add inner meshes foreach (Mesh innerMesh in m_Hull.GetInnerMeshes()) { // Create the new GameObject GameObject newGO = (GameObject)GameObject.Instantiate(gameObject); // Set the new Mesh onto the MeshFilter and MeshCollider MeshFilter newMeshFilter = newGO.GetComponent <MeshFilter>(); MeshCollider newMeshCollider = newGO.GetComponent <MeshCollider>(); if (newMeshFilter != null) { newMeshFilter.sharedMesh = innerMesh; } if (newMeshCollider != null) { newMeshCollider.sharedMesh = innerMesh; } // apply force to rigidbodies // newGO.rigidbody.AddForce(impactPoint * impactForce.magnitude); } // Set the hull's new mesh back onto this game object if (meshFilter != null) { meshFilter.sharedMesh = newMesh; } // If this GameObject has a MeshCollider, put the new mesh there too if (meshCollider != null) { meshCollider.sharedMesh = newMesh; } // Drop our cached Hull if we're not supposed to keep it around if (m_CacheOption == CacheOptions.None) { m_Hull = null; } // Our calculations are done m_Calculating = false; }); }); }
public void Impact(Vector3 point, Vector3 force, ImpactShapes impactShape, ImpactTypes impactType) { // See if we can do this right now if (!CanDoImpact(point, force)) return; // We're now set on course to calculate the impact deformation m_Calculating = true; // Set up m_Hull InitializeHull(); // Figure out the true impact force if (force.magnitude > m_MaxForcePerImpact) force = force.normalized * m_MaxForcePerImpact; float impactFactor = (force.magnitude - m_ForceResistance) * m_ForceMultiplier; if (impactFactor <= 0) return; // Localize the point and the force to account for transform scaling (and maybe rotation or translation) Vector3 impactPoint = transform.InverseTransformPoint(point); Vector3 impactForce = transform.InverseTransformDirection(force.normalized) * impactFactor; // Limit the force by the extents of the initial bounds to keep things reasonable float impactForceX = Mathf.Max(Mathf.Min(impactForce.x, m_InitialBounds.extents.x), -m_InitialBounds.extents.x); float impactForceY = Mathf.Max(Mathf.Min(impactForce.y, m_InitialBounds.extents.y), -m_InitialBounds.extents.y); float impactForceZ = Mathf.Max(Mathf.Min(impactForce.z, m_InitialBounds.extents.z), -m_InitialBounds.extents.z); impactForce = new Vector3(impactForceX, impactForceY, impactForceZ); // Run the mesh deformation on another thread ThreadManager.RunAsync(()=> { // Do all the math to deform this mesh m_Hull.Impact(impactPoint, impactForce, impactShape, impactType); // Queue the final mesh setting on the main thread once the deformations are done ThreadManager.QueueOnMainThread(()=> { // Clear out the current Mesh and MeshCollider (if we have one) for now MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>(); if (meshFilter != null) meshFilter.sharedMesh = null; MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>(); if (meshCollider != null) meshCollider.sharedMesh = null; // Get the newly-adjusted Mesh so we can work with it Mesh newMesh = m_Hull.GetMesh(); // If this is a fracture, then create a new GameObject for the chunk that broke off if (impactType == ImpactTypes.Fracture) { Mesh subHullMesh = m_Hull.GetSubHullMesh(); if (subHullMesh != null) { // Create the new GameObject GameObject newGO = (GameObject)GameObject.Instantiate(gameObject); // Set the new Mesh onto the MeshFilter and MeshCollider MeshFilter newMeshFilter = newGO.GetComponent<MeshFilter>(); MeshCollider newMeshCollider = newGO.GetComponent<MeshCollider>(); if (newMeshFilter != null) newMeshFilter.sharedMesh = subHullMesh; if (newMeshCollider != null) newMeshCollider.sharedMesh = subHullMesh; // If using convex MeshColliders, it's possible for colliders to overlap right after a // fracture, which causes exponentially more fractures... So, right after a fracture, // temporarily disable impacts to both the old GameObject, and the new one we just created DelayCollisions(); Meshinator subHullMeshinator = newGO.GetComponent<Meshinator>(); if (subHullMeshinator != null) subHullMeshinator.DelayCollisions(); // Figure out the approximate volume of our Hull and SubHull meshes. This // will be used to calculate the rigidbody masses (if a rigidbodies are present) // for the old and new GameObjects. if (gameObject.rigidbody != null && newGO.rigidbody != null) { Vector3 hullSize = newMesh.bounds.size; float hullVolume = hullSize.x * hullSize.y * hullSize.z; Vector3 subHullSize = subHullMesh.bounds.size; float subHullVolume = subHullSize.x * subHullSize.y * subHullSize.z; float totalVolume = hullVolume + subHullVolume; float totalMass = gameObject.rigidbody.mass; gameObject.rigidbody.mass = totalMass * (hullVolume / totalVolume); newGO.rigidbody.mass = totalMass * (subHullVolume / totalVolume); // Set the old velocity onto the new GameObject's rigidbody newGO.rigidbody.velocity = gameObject.rigidbody.velocity; // Set the centers of mass to be within the new meshes gameObject.rigidbody.centerOfMass = newMesh.bounds.center; newGO.rigidbody.centerOfMass = subHullMesh.bounds.center; } } } // Set the hull's new mesh back onto this game object if (meshFilter != null) meshFilter.sharedMesh = newMesh; // If this GameObject has a MeshCollider, put the new mesh there too if (meshCollider != null) meshCollider.sharedMesh = newMesh; // Drop our cached Hull if we're not supposed to keep it around if (m_CacheOption == CacheOptions.None) m_Hull = null; // Our calculations are done m_Calculating = false; }); }); }