/// <summary>
    /// CreateBloodDecal is used to create blood decal.
    /// This method should be called by receive damage behavior when receiving damage.
    /// Center = the position of the object which attempts to create the decal. But, if DecalData
    /// </summary>
    /// <param name="center"></param>
    /// <param name="DecalData"></param>
    public static void CreateBloodDecal(Vector3 center, DecalData _DecalData)
    {
        //create predefine global decal
        if (_DecalData.UseGlobalDecal)
        {
            GlobalDecalData globalDecalData = Instance.GlobalDecalDataDict[_DecalData.GlobalType];
            if (globalDecalData.Decal_OnGround.Length > 0)
            {
                Instance.StartCoroutine(Instance.CreateGlobalDecalOnGround(center, globalDecalData, _DecalData));
            }
            if (globalDecalData.Decal_OnWall.Length > 0)
            {
                Instance.StartCoroutine(Instance.CreateGlobalDecalOnWall(center, globalDecalData, _DecalData));;
            }
        }
        //Create custom decal defined by Unit
        else
        {
            switch (_DecalData.ProjectDirection)
            {
            //Create decal on ground
            case HorizontalOrVertical.Vertical:
                Instance.StartCoroutine(Instance.CreateDecalOnGround(center, _DecalData));
                break;

            //Create decal on wall
            case HorizontalOrVertical.Horizontal:
                Instance.StartCoroutine(Instance.CreateBloodDecalOnWall(center, _DecalData));
                break;
            }
        }
    }
    /// <summary>
    /// This method specifically target on creating blood decal on ground.
    /// </summary>
    IEnumerator CreateGlobalDecalOnGround(Vector3 Center, GlobalDecalData globalDecalData, DecalData _DecalData)
    {
        if (_DecalData.CreateDelay > 0)
        {
            yield return(new WaitForSeconds(_DecalData.CreateDelay));
        }
        float   Radius           = 1;
        Vector2 randomFromCircle = Random.insideUnitCircle;

        randomFromCircle *= Radius;
        Vector3 random = Vector3.zero;

        if (_DecalData.OnTransform != null)
        {
            random = new Vector3(_DecalData.OnTransform.position.x + randomFromCircle.x,
                                 _DecalData.OnTransform.position.y + 3,
                                 _DecalData.OnTransform.position.z + randomFromCircle.y);
        }
        else
        {
            random = new Vector3(Center.x + randomFromCircle.x, Center.y + 3, Center.z + randomFromCircle.y);
        }
        RaycastHit hitInfo;

        //If there is ground point projection exists, create the decal object.
        if (Physics.Raycast(random, Vector3.down, out hitInfo, 999, globalDecalData.GroundLayer))
        {
            //Randomly select a decalObject
            Object decalObject = Util.RandomFromArray <Object>(globalDecalData.Decal_OnGround);
            float  scaleRate   = Random.Range(globalDecalData.ScaleRateMin, globalDecalData.ScaleRateMax);

            //Instantiate the DecalObject
            GameObject DecalObject = (GameObject)Object.Instantiate(decalObject, hitInfo.point + hitInfo.normal * 0.1f, Quaternion.identity);
            DecalObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
            DecalObject.transform.RotateAround(DecalObject.transform.up, Random.Range(0, 360));
            DecalObject.transform.localScale *= scaleRate;
            if (globalDecalData.DecalLifetime > 0)
            {
                Destroy(DecalObject, globalDecalData.DecalLifetime);
            }
        }
    }
    /// <summary>
    /// This method specifically target on creating blood decal on wall.
    /// </summary>
    IEnumerator CreateGlobalDecalOnWall(Vector3 Center, GlobalDecalData globalDecalData, DecalData _DecalData)
    {
        if (_DecalData.CreateDelay > 0)
        {
            yield return(new WaitForSeconds(_DecalData.CreateDelay));
        }
        float Radius = 2;

        //check front/back/right/left direction if there's a collision:
        Collider[] wallColliders = Physics.OverlapSphere(Center, Radius, globalDecalData.WallLayer);
        if (wallColliders != null && wallColliders.Length > 0)
        {
            Collider wall          = wallColliders[0];
            Vector3  closestPoints = wall.ClosestPointOnBounds(Center);
            closestPoints.y += Random.Range(0.1f, 0.5f);
            //Randomize the point
            closestPoints += Random.onUnitSphere * 1;
            RaycastHit hitInfo;
            //Find the point to create wall decal
            if (Physics.Raycast(Center, closestPoints - Center, out hitInfo, 20, globalDecalData.WallLayer))
            {
                //Randomly select a decal object
                Object decalObjectProtocal = Util.RandomFromArray <Object>(globalDecalData.Decal_OnWall);
                //if wall decal instantiation point exists, create the decal object.
                GameObject DecalObject = (GameObject)Object.Instantiate(decalObjectProtocal,
                                                                        hitInfo.point + hitInfo.normal * 0.1f,
                                                                        Quaternion.identity);
                DecalObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
                DecalObject.transform.RotateAround(DecalObject.transform.up, Random.Range(0, 360));
                float scaleRate = Random.Range(globalDecalData.ScaleRateMin, globalDecalData.ScaleRateMax);
                DecalObject.transform.localScale *= scaleRate;
                if (globalDecalData.DecalLifetime > 0)
                {
                    Destroy(DecalObject, globalDecalData.DecalLifetime);
                }
            }
        }
    }
 /// <summary>
 /// This method specifically target on creating blood decal on wall.
 /// </summary>
 IEnumerator CreateGlobalDecalOnWall(Vector3 Center, GlobalDecalData globalDecalData, DecalData _DecalData)
 {
     if(_DecalData.CreateDelay > 0)
     {
         yield return new WaitForSeconds(_DecalData.CreateDelay);
     }
     float Radius = 2;
     //check front/back/right/left direction if there's a collision:
     Collider[] wallColliders = Physics.OverlapSphere(Center, Radius, globalDecalData.WallLayer);
     if (wallColliders != null && wallColliders.Length > 0)
     {
         Collider wall = wallColliders[0];
         Vector3 closestPoints = wall.ClosestPointOnBounds(Center);
         closestPoints.y += Random.Range(0.1f, 0.5f);
         //Randomize the point
         closestPoints += Random.onUnitSphere * 1;
         RaycastHit hitInfo;
         //Find the point to create wall decal
         if (Physics.Raycast(Center, closestPoints - Center, out hitInfo, 20, globalDecalData.WallLayer))
         {
             //Randomly select a decal object
             Object decalObjectProtocal = Util.RandomFromArray<Object>(globalDecalData.Decal_OnWall);
             //if wall decal instantiation point exists, create the decal object.
             GameObject DecalObject = (GameObject)Object.Instantiate(decalObjectProtocal,
                                                                     hitInfo.point + hitInfo.normal * 0.1f,
                                                                     Quaternion.identity);
             DecalObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
             DecalObject.transform.RotateAround(DecalObject.transform.up, Random.Range(0, 360));
             float scaleRate = Random.Range(globalDecalData.ScaleRateMin , globalDecalData.ScaleRateMax);
             DecalObject.transform.localScale *= scaleRate;
             if (globalDecalData.DecalLifetime > 0)
                 Destroy(DecalObject, globalDecalData.DecalLifetime);
         }
     }
 }
    /// <summary>
    /// This method specifically target on creating blood decal on ground.
    /// </summary>
    IEnumerator CreateGlobalDecalOnGround(Vector3 Center, GlobalDecalData globalDecalData, DecalData _DecalData)
    {
        if(_DecalData.CreateDelay > 0)
        {
            yield return new WaitForSeconds(_DecalData.CreateDelay);
        }
        float Radius = 1;
        Vector2 randomFromCircle = Random.insideUnitCircle;
        randomFromCircle *= Radius;
        Vector3 random = Vector3.zero;
        if(_DecalData.OnTransform != null)
        {
            random = new Vector3(_DecalData.OnTransform.position.x + randomFromCircle.x,
                                 _DecalData.OnTransform.position.y + 3,
                                 _DecalData.OnTransform.position.z + randomFromCircle.y);
        }
        else
        {
            random = new Vector3(Center.x + randomFromCircle.x, Center.y + 3, Center.z + randomFromCircle.y);
        }
        RaycastHit hitInfo;
        //If there is ground point projection exists, create the decal object.
        if (Physics.Raycast(random, Vector3.down, out hitInfo, 999, globalDecalData.GroundLayer))
        {
            //Randomly select a decalObject
            Object decalObject = Util.RandomFromArray<Object>(globalDecalData.Decal_OnGround);
            float scaleRate = Random.Range(globalDecalData.ScaleRateMin, globalDecalData.ScaleRateMax);

            //Instantiate the DecalObject
            GameObject DecalObject = (GameObject)Object.Instantiate(decalObject, hitInfo.point + hitInfo.normal * 0.1f, Quaternion.identity);
            DecalObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
            DecalObject.transform.RotateAround(DecalObject.transform.up, Random.Range(0, 360));
            DecalObject.transform.localScale *= scaleRate;
            if(globalDecalData.DecalLifetime > 0)
            {
               Destroy(DecalObject, globalDecalData.DecalLifetime);
            }
        }
    }