Пример #1
0
        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();
            }
        }
Пример #2
0
 public void SpawnImpact(ImpactTypes t, Vector3 pos, Quaternion rot)
 {
     tno.SendQuickly("SpawnEffect", Target.All, t, pos, rot);
 }
Пример #3
0
    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;
            });
        });
    }
Пример #4
0
    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;
            });
        });
    }
Пример #5
0
	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;
			});
		});
	}