/// <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); } } }