Detect Shield Mesh Sides Hit

Hey everyone trying to make a 3d mesh shield that can take damage based on side hit. So detect top, bottom, fore, aft, left, right shield hits and those sides take float damage. Right now its working as a single shield and takes damage. Any ideas?

Current weapon script…

using UnityEngine;
using System.Collections;
 
[RequireComponent(typeof(LineRenderer))]
 
public class BeamArray : MonoBehaviour 
{
    LineRenderer line;
    public Material lineMaterial;
	bool phaser = false;
	public AudioClip sound;
 
    void Start()
    {
      	line = GetComponent<LineRenderer>();
       	line.SetVertexCount(2);
       	line.renderer.material = lineMaterial;
       	line.SetWidth(0.1f, 0.25f);
		line.enabled = false;
    }
	
    void Update()
    {
		var script = GameObject.Find("aaMain Camera").GetComponent<SelectTarget>();
		if(Input.GetKeyDown("space") && phaser == false && script.gui == "yes")
		{
			phaser = true;
			StartCoroutine (pulsetime());
		}
	}
		IEnumerator pulsetime()
        {
			var script = GameObject.Find("aaMain Camera").GetComponent<SelectTarget>();
          	line.enabled = true;
			AudioSource.PlayClipAtPoint(sound, Camera.main.transform.position);
          	RaycastHit hit;
       		if (Physics.Linecast(transform.position, script.selectedTarget.transform.position, out hit))
      		{
         		// call ApplyDamage(10) in the hit object:
       			hit.transform.SendMessage("ApplyDamage", 700, SendMessageOptions.DontRequireReceiver);
			}
			//wait the cooldown time in a loop
			float delay = 1.680f;
			while (delay > 0)
			{
				//update beam endpoints
				if(script.Shields == false)
				{
					line.SetPosition(0, transform.position);
         			line.SetPosition(1, script.selectedTarget.transform.position);
				}
				if(script.Shields == true)
				{
					line.SetPosition(0, transform.position);
         			line.SetPosition(1, hit.point);
					script.selectedTarget.GetComponent<MeshRenderer>().enabled = true;
				}
				//decrement delay time
				delay -= Time.deltaTime;
				//let unity free until next frame
				yield return null;
			}
				line.enabled = false;
				phaser = false;
				script.selectedTarget.GetComponent<MeshRenderer>().enabled = false;
        }
}

No, it’s not beyond the capabilities of Unity.

How about you calculate the vector that points from your ship to the target ship, and then using that vector and the enemy ship’s “Forward” vector, you can calculate where the ship was hit:

Vector3 toTarget = script.selectedTarget.transform.position - transform.position;
Vector3 targetForward = script.selectedTarget.transform.forward; // change to transform.up if it's 2d and the ship faces upwards

float angle = Vector3.Angle(toTarget, targetForward);
	
if (angle < 45) {
	// less than 45 degrees difference, means we hit him from behind:
	DamageShield("Behind");
} else if (angle > 135) {
	// more than 135 degrees means the vectors are almost facing each other, so we hit the forward shields:
	DamageShield("Forward");
} else {
	// degree is between 45 and 135 so we hit from one of the sides. Need to calculate which:
	Vector3 targetRight = script.selectedTarget.transform.right;
	
	// calculate angle between firing vector and target's right vector
	float rightAngle = Vector3.Angle(toTarget, targetRight);
	
	if (rightAngle < 45) {
	    // degree less than 45 percent, so we hit behind the right vector, which means we hit the left side of the shields
		DamageShield("Left");
	} else {
		DamageShield("Right");
	}
}

Of course there are other ways to go about it (several colliders for instance), but this is the simplest way and it should do just fine for most games.

If you want to be even more accurate, instead of using the shooter’s position in toTarget, use the position where the weapon hit the shields.


Edit: A solution for working with 6 sides (3d), would be to calculate the angle between the vector pointing from the target center to the hit position, and the 6 directions of the target (forward, back, top, bottom, left, right). The one with the smallest angle is the one that was hit:

if(script.Shields == true)
{
   print("shields true and getting side hit");

   // vector from the target center to the hit position
   Vector3 hitDirection = hit.point - script.selectedTarget.transform.position;
   Transform targetTransform = script.selectedTarget.transform;

   float angleForward = Vector3.Angle(hitDirection, targetTransform.forward);
   float angleBack = Vector3.Angle(hitDirection, -(targetTransform.forward));
   float angleRight = Vector3.Angle(hitDirection, targetTransform.right);
   float angleLeft = Vector3.Angle(hitDirection, -(targetTransform.right));
   float angleTop = Vector3.Angle(hitDirection, targetTransform.up);
   float angleBot = Vector3.Angle(hitDirection, -(targetTransform.up));

   string shieldHit = "";
   float minAngle = 180;

   if (angleForward < minAngle) {
     shieldHit = "Forward";
     minAngle = angleForward;
   }

   if (angleBack < minAngle) {
     shieldHit = "Back";
     minAngle = angleBack;
   }

   if (angleRight < minAngle) {
     shieldHit = "Right";
     minAngle = angleRight;
   }

   if (angleLeft < minAngle) {
     shieldHit = "Left";
     minAngle = angleLeft;
   }

   if (angleTop < minAngle) {
     shieldHit = "Top";
     minAngle = angleTop;
   }

   if (angleBot < minAngle) {
     shieldHit = "Bottom";
     minAngle = angleBot;
   }

   print("Shields hit: " + shieldHit);
}

Note: A cleaner solution would use an array and a for loop, but this is more readable so I use it like this for the sake of the answer.