Modification of Playmaker Raycast Action. Need Help

I’m trying to add a Layer Mask to this Playmaker action specifically made for Volumetric Blood from the UAS. I’m trying to exclude specific bones in the Layer Mask for blood decals. Any help would be appreciated. It’s a modification of the Playmaker Raycast action.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip(“This action fixes a problem I was having with Volumetric Blood where the raycast could go through obstructing objects and allow blood to emit from objects that are behind the obstructing objects. Use Layer Mask to include all objects, including obstructing objects that don’t emit blood. Then use Ignore Tags for obstructing objects you don’t want emitting blood.”)]
public class KFXVBRaycast : FsmStateAction
{
//[ActionSection(“Setup Raycast”)]

	[Tooltip("Start ray at game object position. \nOr use From Position parameter.")]
	public FsmOwnerDefault fromGameObject;

	[Tooltip("Start ray at a vector3 world position. \nOr use Game Object parameter.")]
	public FsmVector3 fromPosition;

	[Tooltip("A vector3 direction vector")]
	public FsmVector3 direction;

	[Tooltip("Cast the ray in world or local space. Note if no Game Object is specified, the direction is in world space.")]
	public Space space;

	[Tooltip("The length of the ray. Set to -1 for infinity.")]
	public FsmFloat distance;

	[ActionSection("Result")] 

	[Tooltip("Event to send if the ray hits an object. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmEvent hitEvent;

	[Tooltip("Set a bool variable to true if hit something, otherwise false. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmBool storeDidHit;

	[Tooltip("Store the game object hit in a variable. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmGameObject storeHitObject;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the world position of the ray hit point and store it in a variable. This can be left to None if you're just emitting blood.")]
	public FsmVector3 storeHitPoint;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the normal at the hit point and store it in a variable.\nNote, this is a direction vector not a rotation. Use Look At Direction to rotate a GameObject to this direction. This can be left to None if you're just emitting blood.")]
	public FsmVector3 storeHitNormal;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the distance along the ray to the hit point and store it in a variable. This can be left to None if you're just emitting blood.")]
	public FsmFloat storeHitDistance;

	[ActionSection("Filter")] 

	[Tooltip("Set how often to cast a ray. 0 = once, don't repeat; 1 = everyFrame; 2 = every other frame... \nBecause raycasts can get expensive use the highest repeat interval you can get away with.")]
	public FsmInt repeatInterval;

	[UIHint(UIHint.Layer)]
	[Tooltip("Pick only from these layers. Also add layers that BLOCK objects that emit blood and then add their tags to Ignore Tags.")]
	public FsmInt[] layerMask;

	[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
	public FsmBool invertMask;

	[ActionSection("Debug")] 
	
	[Tooltip("The color to use for the debug line.")]
	public FsmColor debugColor;

	[Tooltip("Draw a debug line. Note: Check Gizmos in the Game View to see it in game.")]
	public FsmBool debug;
	
	[UIHint(UIHint.TagMenu)]
	[Tooltip("Tags for game objects you don't want BLOOD emitting from.")]
	public string[] ignoreTags;
	
	public bool InfiniteDecal;
	
	[Tooltip("Get the Drectional Light's intensity. You can use the Get Light Intensity Action from the Ecosystem Browser. If this is set to 0, blood spurts will be black.")]
	public FsmFloat lightIntensity;
	
	//public bool isVR = false;
	public GameObject BloodAttach;
	public GameObject[] BloodFX;
	
	[UIHint(UIHint.TagMenu)]
	[Tooltip("Bones with the following tags will be ignored for attached blood decals.")]
	public string[] ignoreBoneTagsForAttachedDecals;
	
	[UIHint(UIHint.Layer)]
	[Tooltip("Ignore bones on these layers for attached blood decals.")]
	public FsmInt[] ignoreBoneLayerMaskForAttachedDecals;
	
	[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
	public FsmBool invertMask2;
	
	//public FsmInt[] BoneLayers;
	
	[Tooltip("Use enemy's root object for Enemy Ground Height. Enemies should not be a child of any object and enemy's root transform should be near their feet and next to the ground. If this is checked true, Enemy Ground Height and Store Y can be ignored.")]
	public FsmBool useEnemyRoot;
	
	[UIHint(UIHint.Variable)]//
	[Tooltip("This gets the world position Vector3 of the enemy being shot and sets it to Ground Height. You will want to use Playmaker's Raycast action to get this Vector3.")]//
	public FsmVector3 EnemyGroundHeight;//
	
	[UIHint(UIHint.Variable)]//
	[Tooltip("This stores the world Y value in a float variable for Enemy Ground Height.")]//
	public FsmFloat storeWorldYOfEnemy;	//
	
	[Tooltip("Repeat every frame.")]
	public bool everyFrame;
	
	
	
	
	Transform GetNearestObject(Transform hit, Vector3 hitPos)
	{
		var closestPos = 100f;
		Transform closestBone = null;
		var childs = hit.GetComponentsInChildren<Transform>();

		foreach (var child in childs)
		{
			var dist = Vector3.Distance(child.position, hitPos);
			if (dist < closestPos)
				//if (child.tag != "Body")
				//if (child.tag != "Untagged")
				//if (child.tag != "Head")
				//	if (!ContainsTag2(child.transform.tag))
				//		if (ContainsLayer(child.gameObject.layer))//
				//if (BoneLayers == (BoneLayers | (1 << BoneLayers)))
						//if (child.tag != "Arms")
					//if (child.tag != "Legs")
			{
				closestPos = dist;
				closestBone = child;
			}
		}

		var distRoot = Vector3.Distance(hit.position, hitPos);
		if (distRoot < closestPos)
		
		{
			closestPos = distRoot;
			closestBone = hit;
		}
		return closestBone;
	}
	
	int effectIdx;

	private int repeat;
	private GameObject cachedGameObject;
	private Transform cachedTransform;
	


	public override void Reset()
	{
		fromGameObject = null;
		fromPosition = new FsmVector3 { UseVariable = true };
		direction = null; // new FsmVector3 { UseVariable = true };
		space = Space.Self;
		distance = 100;
		hitEvent = null;
		storeDidHit = null;
		storeHitObject = null;
		storeHitPoint = null;
		storeHitNormal = null;
		storeHitDistance = null;
		repeatInterval = new FsmInt { Value = 1 };
		layerMask = new FsmInt[0];
		invertMask = false;
		debugColor = Color.yellow;
		debug = false;
		EnemyGroundHeight = null;//
		storeWorldYOfEnemy = null;//
		everyFrame = false;//
		lightIntensity = 1.0f;//
		useEnemyRoot = false;//
		ignoreBoneLayerMaskForAttachedDecals = new FsmInt[0];//
	}

	public override void OnEnter()
	{
		DoRaycast(); //DoRaycast(Collider other); gives a null ref exception
		
		if (repeatInterval.Value == 0)
		{
			Finish();
		}
		{//
			DoGetVector3XYZ();//
		
			if(!everyFrame)//
				Finish();//
		}//
	}

	public override void OnUpdate() //I changed this from OnFixedUpdate(). May need to change it back.
	{
		{//
			DoGetVector3XYZ();//
		}//
		repeat--;
		
		if (repeat == 0)
		{
			DoRaycast(); 
		}
		
	}

	private void DoRaycast() 
	{
		repeat = repeatInterval.Value;
		
		if (distance.Value < 0.001f) return;

		var go = Fsm.GetOwnerDefaultTarget(fromGameObject);
		if (go != cachedGameObject)
		{
			cachedGameObject = go;
			cachedTransform = go != null ? go.transform : null;
		}
		
		var originPos = cachedTransform != null ? cachedTransform.position : fromPosition.Value;
		
		var rayLength = Mathf.Infinity;
		if (distance.Value > 0 )
		{
			rayLength = distance.Value;
		}

		var dirVector = direction.Value;
		if (cachedTransform != null && space == Space.Self)
		{
			dirVector = cachedTransform.TransformDirection(direction.Value);
		}

		RaycastHit hitInfo;
		
		Physics.Raycast(originPos, dirVector, out hitInfo, rayLength, ActionHelpers.LayerArrayToLayerMask(layerMask, invertMask.Value));
		
		
		Fsm.RaycastHitInfo = hitInfo;
		
		
		var didHit = hitInfo.collider != null;
		var didNotHit = hitInfo.collider == null;
		
		storeDidHit.Value = didHit;
		
			
		if (didNotHit)
	
			{
				
			return;
				
			}
			
		else if (ContainsTagThenNoBlood(hitInfo.collider.tag)) 
		// This checks the tags from string array "IgnoreTags" and excludes objects with those tags from emitting blood.
		// Check "bool ContainsTag(string tag)... at the bottom of this script for the for loop."
		{
			
			storeHitObject.Value = hitInfo.collider.gameObject;
			storeHitPoint.Value = Fsm.RaycastHitInfo.point;
			storeHitNormal.Value = Fsm.RaycastHitInfo.normal;
			storeHitDistance.Value = Fsm.RaycastHitInfo.distance;
			Fsm.Event(hitEvent);
			
		}
	
		else if (didHit) //Let there be BLOOD!
			
			{
				
				storeHitObject.Value = hitInfo.collider.gameObject;
				storeHitPoint.Value = Fsm.RaycastHitInfo.point;
				storeHitNormal.Value = Fsm.RaycastHitInfo.normal;
				storeHitDistance.Value = Fsm.RaycastHitInfo.distance;
				Fsm.Event(hitEvent);
			
				{
					
					float angle = Mathf.Atan2(hitInfo.normal.x, hitInfo.normal.z) * Mathf.Rad2Deg + 180;
					float EnemyRootObjectYPos = hitInfo.collider.transform.root.position.y; //For Ground Height
					
					var effectIdx = UnityEngine.Random.Range(0, BloodFX.Length);
					if (effectIdx == BloodFX.Length) effectIdx = 0;

					var instance = UnityEngine.Object.Instantiate(BloodFX[effectIdx], hitInfo.point, Quaternion.Euler(0, angle + 90, 0));
					effectIdx++;

					var settings = instance.GetComponent<BFX_BloodSettings>();
					
					if (useEnemyRoot.Value)
					settings.GroundHeight = EnemyRootObjectYPos; //For Ground Height
					
					else
					settings.GroundHeight = EnemyGroundHeight.Value.y;
					settings.FreezeDecalDisappearance = InfiniteDecal;
					settings.LightIntensityMultiplier = lightIntensity.Value; //DirLight.intensity;
					

					var nearestBone = GetNearestObject(hitInfo.transform.root, hitInfo.point);
					if(nearestBone != null)
						if (!ContainsTag2(nearestBone.transform.tag))
						//if (ignoreBoneLayerMaskForAttachedDecals())
						//ActionHelpers.LayerArrayToLayerMask(ignoreBoneLayerMaskForAttachedDecals, invertMask2.Value);
						//if (!ContainsLayer(nearestBone.gameObject.layer))//
						//if (ContainsLayer(ActionHelpers.LayerArrayToLayerMask(ignoreBoneLayerMaskForAttachedDecals, invertMask2.Value)))//
							
					{
						
						var attachBloodInstance = UnityEngine.Object.Instantiate(BloodAttach);
						var bloodT = attachBloodInstance.transform;
						bloodT.position = hitInfo.point;
						bloodT.localRotation = Quaternion.identity;
						bloodT.localScale = Vector3.one * Random.Range(0.7f, 1.0f);
						bloodT.LookAt(hitInfo.point + hitInfo.normal, direction.Value);
						bloodT.Rotate(90, 0, 0);
						bloodT.transform.parent = nearestBone;
			
			
						}
		
						if (debug.Value)
						
						{
							var debugRayLength = Mathf.Min(rayLength, 1000);
							var endPos = didHit ? storeHitPoint.Value : originPos + dirVector * debugRayLength;

							if (repeatInterval.Value == 0)
							
							{
								
								Debug.DrawLine(originPos, endPos, debugColor.Value, 0.1f);
								
							}
							
							else
							
							{
								
								Debug.DrawLine(originPos, endPos, debugColor.Value);
								
							}
						}
					}
				}
			}
			
	public float CalculateAngle(Vector3 from, Vector3 to)
	
	{

		return Quaternion.FromToRotation(Vector3.up, to - from).eulerAngles.z;

	}
	
	bool ContainsTagThenNoBlood(string tag)
	
	{
		for (int i = 0; i < ignoreTags.Length; i++)
			if (ignoreTags[i] == tag)
				return true;

		return false;
		
	}
	
	bool ContainsTag2(string tag)
	
	{
		for (int i = 0; i < ignoreBoneTagsForAttachedDecals.Length; i++)
			if (ignoreBoneTagsForAttachedDecals[i] == tag)
				return true;

		return false;
		
	}
	
	bool ContainsLayer(FsmInt bonelayermask)
	
	{
		for (int i = 0; i < ignoreBoneTagsForAttachedDecals.Length; i++)
			if (ignoreBoneLayerMaskForAttachedDecals[i] == bonelayermask)
				return true;

		return false;
		
	}
	
	void DoGetVector3XYZ()
	{
		//Debug.Log(storeY);
		if (EnemyGroundHeight == null) return;

		if (storeWorldYOfEnemy != null)
			storeWorldYOfEnemy.Value = EnemyGroundHeight.Value.y;
	
	}
}

}

Oops! Here’s a more recent version.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip(“This action fixes a problem I was having with Volumetric Blood where the raycast could go through obstructing objects and allow blood to emit from objects that are behind the obstructing objects. Use Layer Mask to include all objects, including obstructing objects that don’t emit blood. Then use Ignore Tags for obstructing objects you don’t want emitting blood.”)]
public class KFXVBRaycast : FsmStateAction
{
//[ActionSection(“Setup Raycast”)]

	[Tooltip("Start ray at game object position. \nOr use From Position parameter.")]
	public FsmOwnerDefault fromGameObject;

	[Tooltip("Start ray at a vector3 world position. \nOr use Game Object parameter.")]
	public FsmVector3 fromPosition;

	[Tooltip("A vector3 direction vector")]
	public FsmVector3 direction;

	[Tooltip("Cast the ray in world or local space. Note if no Game Object is specified, the direction is in world space.")]
	public Space space;

	[Tooltip("The length of the ray. Set to -1 for infinity.")]
	public FsmFloat distance;

	[ActionSection("Result")] 

	[Tooltip("Event to send if the ray hits an object. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmEvent hitEvent;

	[Tooltip("Set a bool variable to true if hit something, otherwise false. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmBool storeDidHit;

	[Tooltip("Store the game object hit in a variable. This can be left to None if you're just emitting blood.")]
	[UIHint(UIHint.Variable)]
	public FsmGameObject storeHitObject;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the world position of the ray hit point and store it in a variable. This can be left to None if you're just emitting blood.")]
	public FsmVector3 storeHitPoint;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the normal at the hit point and store it in a variable.\nNote, this is a direction vector not a rotation. Use Look At Direction to rotate a GameObject to this direction. This can be left to None if you're just emitting blood.")]
	public FsmVector3 storeHitNormal;

	[UIHint(UIHint.Variable)]
	[Tooltip("Get the distance along the ray to the hit point and store it in a variable. This can be left to None if you're just emitting blood.")]
	public FsmFloat storeHitDistance;

	[ActionSection("Filter")] 

	[Tooltip("Set how often to cast a ray. 0 = once, don't repeat; 1 = everyFrame; 2 = every other frame... \nBecause raycasts can get expensive use the highest repeat interval you can get away with.")]
	public FsmInt repeatInterval;

	[UIHint(UIHint.Layer)]
	[Tooltip("Pick only from these layers. Also add layers that BLOCK objects that emit blood and then add their tags to Ignore Tags.")]
	public FsmInt[] layerMask;

	[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
	public FsmBool invertMask;

	[ActionSection("Debug")] 
	
	[Tooltip("The color to use for the debug line.")]
	public FsmColor debugColor;

	[Tooltip("Draw a debug line. Note: Check Gizmos in the Game View to see it in game.")]
	public FsmBool debug;
	
	[UIHint(UIHint.TagMenu)]
	[Tooltip("Tags for game objects you don't want BLOOD emitting from.")]
	public string[] ignoreTags;
	
	public bool InfiniteDecal;
	
	[Tooltip("Get the Drectional Light's intensity. You can use the Get Light Intensity Action from the Ecosystem Browser. If this is set to 0, blood spurts will be black.")]
	public FsmFloat lightIntensity;
	
	//public bool isVR = false;
	public GameObject BloodAttach;
	public GameObject[] BloodFX;
	
	[UIHint(UIHint.TagMenu)]
	[Tooltip("Bones with the following tags will be ignored for attached blood decals.")]
	public string[] ignoreBoneTagsForAttachedDecals;
	
	[UIHint(UIHint.Layer)]
	[Tooltip("Ignore bones on these layers for attached blood decals.")]
	public FsmInt[] ignoreBoneLayerMaskForAttachedDecals; ////IMPORTANT NEED TO FIGURE OUT
	
	[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
	public FsmBool invertMask2;
	
	//public FsmInt[] BoneLayers;
	
	[Tooltip("Use enemy's root object for Enemy Ground Height. Enemies should not be a child of any object and enemy's root transform should be near their feet and next to the ground. If this is checked true, Enemy Ground Height and Store Y can be ignored.")]
	public FsmBool useEnemyRoot;
	
	[UIHint(UIHint.Variable)]//
	[Tooltip("This gets the world position Vector3 of the enemy being shot and sets it to Ground Height. You will want to use Playmaker's Raycast action to get this Vector3.")]//
	public FsmVector3 EnemyGroundHeight;//
	
	[UIHint(UIHint.Variable)]//
	[Tooltip("This stores the world Y value in a float variable for Enemy Ground Height.")]//
	public FsmFloat storeWorldYOfEnemy;	//
	
	[Tooltip("Repeat every frame.")]
	public bool everyFrame;
	
	
	
	
	Transform GetNearestObject(Transform hit, Vector3 hitPos)
	{
		var closestPos = 100f;
		Transform closestBone = null;
		var childs = hit.GetComponentsInChildren<Transform>();
		
		foreach (var child in childs)
		{
			var dist = Vector3.Distance(child.position, hitPos);
			if (dist < closestPos)
				//if (child.tag != "Body")
				//if (child.tag != "Untagged")
				//if (child.tag != "Head")
				//	if (!ContainsTagNoBloodDecals(child.transform.tag))
				//		if (ContainsLayer(child.gameObject.layer))//
				//if (BoneLayers == (BoneLayers | (1 << BoneLayers)))
						//if (child.tag != "Arms")
					//if (child.tag != "Legs")
			{
				closestPos = dist;
				closestBone = child;
			}
		}

		var distRoot = Vector3.Distance(hit.position, hitPos);
		if (distRoot < closestPos)
		
		{
			closestPos = distRoot;
			closestBone = hit;
		}
		return closestBone;
	}
	
	int effectIdx;

	private int repeat;
	private GameObject cachedGameObject;
	private Transform cachedTransform;
	
	private FsmGameObject bone;//
	private FsmInt storeValue;

	public override void Reset()
	{
		fromGameObject = null;
		fromPosition = new FsmVector3 { UseVariable = true };
		direction = null; // new FsmVector3 { UseVariable = true };
		space = Space.Self;
		distance = 100;
		hitEvent = null;
		storeDidHit = null;
		storeHitObject = null;
		storeHitPoint = null;
		storeHitNormal = null;
		storeHitDistance = null;
		repeatInterval = new FsmInt { Value = 1 };
		layerMask = new FsmInt[0];
		invertMask = false;
		debugColor = Color.yellow;
		debug = false;
		EnemyGroundHeight = null;//
		storeWorldYOfEnemy = null;//
		everyFrame = false;//
		lightIntensity = 1.0f;//
		useEnemyRoot = false;//
		ignoreBoneLayerMaskForAttachedDecals = new FsmInt[0];//
		bone = null;
		storeValue = null;
	}

	public override void OnEnter()
	{
		DoRaycast(); //DoRaycast(Collider other); gives a null ref exception
		
		if (repeatInterval.Value == 0)
		{
			Finish();
		}
		{//
			DoGetVector3XYZ();//
			//BoneContainsLayerThenNoDecals();
		
			if(!everyFrame)//
				Finish();//
		}//
	}

	public override void OnUpdate() //I changed this from OnFixedUpdate(). May need to change it back. Originally OnUpdate().
	{
		{//
			
			Debug.Log(storeValue);
			DoGetVector3XYZ();//
			//BoneContainsLayerThenNoDecals();
			
			
		}//
		repeat--;
		
		if (repeat == 0)
		{
			DoRaycast(); 
			
		}
		
	}

	private void DoRaycast() 
	{
		repeat = repeatInterval.Value;
		
		if (distance.Value < 0.001f) return;

		var go = Fsm.GetOwnerDefaultTarget(fromGameObject);
		if (go != cachedGameObject)
		{
			cachedGameObject = go;
			cachedTransform = go != null ? go.transform : null;
		}
		
		var originPos = cachedTransform != null ? cachedTransform.position : fromPosition.Value;
		
		var rayLength = Mathf.Infinity;
		if (distance.Value > 0 )
		{
			rayLength = distance.Value;
		}

		var dirVector = direction.Value;
		if (cachedTransform != null && space == Space.Self)
		{
			dirVector = cachedTransform.TransformDirection(direction.Value);
		}

		RaycastHit hitInfo;
		
		Physics.Raycast(originPos, dirVector, out hitInfo, rayLength, ActionHelpers.LayerArrayToLayerMask(layerMask, invertMask.Value));
		
		
		Fsm.RaycastHitInfo = hitInfo;
		
		
		var didHit = hitInfo.collider != null;
		var didNotHit = hitInfo.collider == null;
		
		storeDidHit.Value = didHit;
		
			
		if (didNotHit)
	
			{
				
			return;
				
			}
			
		else if (ContainsTagThenNoBlood(hitInfo.collider.tag)) 
		// This checks the tags from string array "IgnoreTags" and excludes objects with those tags from emitting blood.
		// Check "bool ContainsTag(string tag)... at the bottom of this script for the for loop."
		{
			
			storeHitObject.Value = hitInfo.collider.gameObject;
			storeHitPoint.Value = Fsm.RaycastHitInfo.point;
			storeHitNormal.Value = Fsm.RaycastHitInfo.normal;
			storeHitDistance.Value = Fsm.RaycastHitInfo.distance;
			Fsm.Event(hitEvent);
			
		}
	
		else if (didHit) //Let there be BLOOD!
			
			{
				
			storeHitObject.Value = hitInfo.collider.gameObject;
				storeHitPoint.Value = Fsm.RaycastHitInfo.point;
				storeHitNormal.Value = Fsm.RaycastHitInfo.normal;
				storeHitDistance.Value = Fsm.RaycastHitInfo.distance;
				Fsm.Event(hitEvent);
			
				{
					
					float angle = Mathf.Atan2(hitInfo.normal.x, hitInfo.normal.z) * Mathf.Rad2Deg + 180;
					float EnemyRootObjectYPos = hitInfo.collider.transform.root.position.y; //For Ground Height
					
					var effectIdx = UnityEngine.Random.Range(0, BloodFX.Length);
					if (effectIdx == BloodFX.Length) effectIdx = 0;

					var instance = UnityEngine.Object.Instantiate(BloodFX[effectIdx], hitInfo.point, Quaternion.Euler(0, angle + 90, 0));
					effectIdx++;

					var settings = instance.GetComponent<BFX_BloodSettings>();
					
					if (useEnemyRoot.Value)
					settings.GroundHeight = EnemyRootObjectYPos; //For Ground Height
					
					else
					settings.GroundHeight = EnemyGroundHeight.Value.y;
					settings.FreezeDecalDisappearance = InfiniteDecal;
					settings.LightIntensityMultiplier = lightIntensity.Value; //DirLight.intensity;
					
					
					var nearestBone = GetNearestObject(hitInfo.transform.root, hitInfo.point);
					if(nearestBone != null)
						if (!ContainsTagNoBloodDecals(nearestBone.transform.tag))
						//if (ignoreBoneLayerMaskForAttachedDecals())
						//ActionHelpers.LayerArrayToLayerMask(ignoreBoneLayerMaskForAttachedDecals, invertMask2.Value);
						//if (ignoreBoneLayerMaskForAttachedDecals != nearestBone.gameObject.layer)//
						//if (ContainsLayer(ActionHelpers.LayerArrayToLayerMask(ignoreBoneLayerMaskForAttachedDecals, invertMask2.Value)))//
							//Debug.Log(ignoreBoneLayerMaskForAttachedDecals);
						//if (ignoreBoneLayerMaskForAttachedDecals)
					{
							bone = nearestBone.transform.gameObject;
							storeValue = nearestBone.transform.gameObject.layer;
							//Debug.Log(bone);
							//Debug.Log(storeValue);
							//Debug.Log(nearestBone.gameObject.layer);
						var attachBloodInstance = UnityEngine.Object.Instantiate(BloodAttach);
						var bloodT = attachBloodInstance.transform;
						bloodT.position = hitInfo.point;
						bloodT.localRotation = Quaternion.identity;
						bloodT.localScale = Vector3.one * Random.Range(0.7f, 1.0f);
						bloodT.LookAt(hitInfo.point + hitInfo.normal, direction.Value);
						bloodT.Rotate(90, 0, 0);
						bloodT.transform.parent = nearestBone;
			
			
						}
		
						if (debug.Value)
						
						{
							var debugRayLength = Mathf.Min(rayLength, 1000);
							var endPos = didHit ? storeHitPoint.Value : originPos + dirVector * debugRayLength;

							if (repeatInterval.Value == 0)
							
							{
								
								Debug.DrawLine(originPos, endPos, debugColor.Value, 0.1f);
								
							}
							
							else
							
							{
								
								Debug.DrawLine(originPos, endPos, debugColor.Value);
								
							}
						}
					}
				}
			}
			
	public float CalculateAngle(Vector3 from, Vector3 to)
	
	{

		return Quaternion.FromToRotation(Vector3.up, to - from).eulerAngles.z;

	}
	
	bool ContainsTagThenNoBlood(string tag)
	
	{
		for (int i = 0; i < ignoreTags.Length; i++)
			if (ignoreTags[i] == tag)
				return true;

		return false;
		
	}
	
	bool ContainsTagNoBloodDecals(string tag)
	
	{
		for (int i = 0; i < ignoreBoneTagsForAttachedDecals.Length; i++)
			if (ignoreBoneTagsForAttachedDecals[i] == tag)
				return true;

		return false;
		
	}
	
	//void BoneContainsLayerThenNoDecals()
	
	//{
	//	//Debug.Log(storeValue);
	//	//if (bone.Value.layer == null) return;
	//	//if (storeValue != null)
		
		
	//	if (storeValue == null) return;
	//	storeValue = bone.Value.layer;
	//	//for (int i = 0; i < ignoreBoneTagsForAttachedDecals.Length; i++)
	//	//	if (ignoreBoneLayerMaskForAttachedDecals[i] == bonelayermask)
	//	//		return true;

	//	//return false;
		
	//}
	
	void DoGetVector3XYZ()
	{
		//Debug.Log(storeWorldYOfEnemy);
		if (EnemyGroundHeight == null) return;

		if (storeWorldYOfEnemy != null)
			storeWorldYOfEnemy.Value = EnemyGroundHeight.Value.y;
	
	}
}

}