Hello guys, been trying to create a target (you know, the round one with red and white colors), and the score you get depends on where you hit the target.
but ran into an issue
the way I created it, is with cylinders, one behind another, and mesh colliders, the problem is that the arrow pierces through the first cylinder and crosses to another one behind, and therefore gives the wrong score
any idea how to solve this? tryed modifying the arrow’s collider but it did’nt work though, still pierces
I would go with a single cylinder collider and distance calculation from center point.
Following code NOT tested
using UnityEngine;
public class Target : MonoBehaviour
{
[System.Serializable]
public struct Area
{
[Min(0)] public float DistanceFromCenter;
[Min(0)] public int Points;
}
// Create an empty GameObject you place at the center of the target
// The up direction of this empty must be perpendicular to the target surface
[SerializeField] private Transform center;
// Fill inspector
// Order the elements from the smallest to the largest distance
[SerializeField] private Area[] targetAreas;
private void OnCollisionEnter(Collision collision)
{
Plane targetPlane = new Plane(center.up, center.position); // This may be created once in the Start method if the target does not move or rotate
Vector3 contactPoint = targetPlane.ClosestPointOnPlane(collision.contacts[0].point); // Taking the 1st contact point may not be the perfect solution
float distanceFromCenter = Vector3.Distance(contactPoint, center.position);
for (int i = 0 ; i < targetAreas.Length ; i++)
{
if(distanceFromCenter < targetAreas*.DistanceFromCenter)*
{ Debug.Log(“The arrow reached the area giving " + targetAreas*.Points + " points”);* break; } } } // The code below is just to visualise in editor more easily private void OnDrawGizmosSelected() { if (center == null || targetAreas == null) return; for (int i = 0 ; i < targetAreas.Length ; i++) { DrawWireCircle(center.position, center.up, targetAreas*.DistanceFromCenter, 8);* } } private void DrawWireCircle(Vector3 center, Vector3 normal, float radius, int sides) { float deltaAngle = Mathf.PI * 2 / sides; Vector3 right = Vector3.Dot(normal, Vector3.up) >= 1 ? Vector3.Cross(-Vector3.forward, normal).normalized : Vector3.Cross(normal, Vector3.up).normalized; Vector3 up = Vector3.Cross(right, normal); for (int i = 0 ; i < sides ; i++) { Vector3 from = right * Mathf.Cos(i * deltaAngle) + up * Mathf.Sin(i * deltaAngle); Vector3 to = right * Mathf.Cos((i + 1) * deltaAngle) + up * Mathf.Sin((i + 1) * deltaAngle); Gizmos.DrawLine(from * radius + center, to * radius + center); } } } [169814-target.png|169814]
the way i would do it is create empty gameobject in middle of the target and have the target as one colider then calculate distance between stuck arrow and middle of the target gameobject