Exemplo n.º 1
0
 public static bool RefractiveObjectIsValid(RefractiveObject obj)
 {
     Collider[] colliders = obj.gameObject.GetComponentsInChildren <Collider>(true);
     if (colliders.Length != 1)
     {
         return(false);
     }
     else
     {
         Collider coll = colliders[0];
         if (coll is BoxCollider)
         {
             return(true);
         }
         else if (coll is SphereCollider)
         {
             return(true);
         }
         else if (coll is CapsuleCollider)
         {
             return(true);
         }
         else if (coll is MeshCollider)
         {
             return(((MeshCollider)coll).convex);
         }
         else
         {
             return(false);
         }
     }
 }
Exemplo n.º 2
0
    /// <summary>
    /// Raycast that behaves like light, refracting and reflecting off surfaces. It is assumed that the Lightcast starts in air instead of another medium.
    /// </summary>
    /// <param name="start">Start of cast in world coordinates.</param>
    /// <param name="direction">Direction of cast in world space.</param>
    /// <param name="hit">Info about what was hit.</param>
    /// <param name="points">All the points the cast passed through.</param>
    /// <param name="maxDistance">Maximum distance, it is recommended to NOT use infinity.</param>
    /// <param name="layerMask">Raycast layer mask.</param>
    public static bool Lightcast(Vector3 start, Vector3 direction, out LightcastHit hit, out Vector3[] points, float maxDistance = Mathf.Infinity, int layerMask = ~0)
    {
        direction = direction.normalized;
        hit       = new LightcastHit(new RaycastHit(), maxDistance);
        bool           hitSomething      = false;
        List <Vector3> pointList         = new List <Vector3>();
        float          remainingDistance = maxDistance;

        while (remainingDistance > 0f)
        {
            pointList.Add(start);
            RaycastHit rayHit;
            if (Physics.Raycast(start, direction, out rayHit, remainingDistance, layerMask))
            {
                remainingDistance -= (start - rayHit.point).magnitude;
                RefractiveObject refractiveOther = rayHit.collider.GetComponent <RefractiveObject>();
                ReflectiveObject reflectiveOther = rayHit.collider.GetComponent <ReflectiveObject>();
                if (refractiveOther != null)
                {
                    bool    totalReflection;
                    Vector3 tempStart = rayHit.point;
                    Vector3 tempDir   = Refract(direction, rayHit.normal, 1f, refractiveOther.RefractiveIndex, out totalReflection);
                    if (!totalReflection)
                    {
                        //ray is now inside refractive object
                        Collider refractiveColl = rayHit.collider;
                        while (remainingDistance > 0f)
                        {
                            pointList.Add(tempStart);
                            //check where the ray hits and wheter it exits the collider or gets reflected again...
                            if (refractiveColl.Raycast(new Ray(tempStart + (tempDir.normalized * maxRefractiveObjectSize), tempDir * -1f), out rayHit, maxRefractiveObjectSize))
                            {
                                remainingDistance -= (tempStart - rayHit.point).magnitude;
                                if (remainingDistance > 0f)
                                {
                                    pointList.Add(rayHit.point);
                                    tempStart = rayHit.point;
                                    tempDir   = Refract(tempDir, -rayHit.normal, refractiveOther.RefractiveIndex, 1f, out totalReflection);
                                    if (!totalReflection)
                                    {
                                        //ray didn't get reflected and left refractive object
                                        start     = tempStart;
                                        direction = tempDir;
                                        break;
                                    }
                                }
                                else
                                {
                                    //ray just reflected and refracted around inside without ever getting anywhere...
                                    Vector3 finalPoint = tempStart + (tempDir.normalized * remainingDistance);
                                    pointList.Add(finalPoint);
                                    break;
                                }
                            }
                            else
                            {
                                //something went wrong
                                Debug.LogWarning("collidercast didn't hit anything!");
                                remainingDistance = 0f;
                                break;
                            }
                        }
                    }
                    else
                    {
                        //ray was totally reflected and never entered the refractive object
                        start     = tempStart;
                        direction = tempDir;
                    }
                }
                else if (reflectiveOther != null)
                {
                    start     = rayHit.point;
                    direction = Vector3.Reflect(direction, rayHit.normal);
                }
                else
                {
                    pointList.Add(rayHit.point);
                    hit = new LightcastHit(rayHit, maxDistance - remainingDistance);
                    break;
                }
            }
            else
            {
                pointList.Add(start + (direction.normalized * remainingDistance));
                break;
            }
        }
        points = pointList.ToArray();
        return(hitSomething);
    }