This is sort of an abstract question here, but how would I write a function such that it’s inputs are:
- A math function such as y=4.5x^2 + 2.3x + 2 (Where x and y are in in game units)
- A domain for the function’s x value such as [4, 11] (Again, in in-game units)
And it outputs whether or not the function over the given domain collides with any 2D colliders?
Well instead of a raycast. You can just create an invisible object with a collider. Then move game object accordingly. It might look something like the following. NOTE THE SECOND FUNCTION:
using System.Data;
[...]
// Variables
bool hit;
float stepSize = 0.01f;
/*
* Main Function that moves obj
*/
bool CheckHit (string funcString, leftBoundry, rightBoundry) {
// Set bool hit to false/Reset
hit = false;
// For Loop
for (float x = leftBoundry; x <= rightBoundry; x += stepSize) {
// Calculate y position
float y = CalculateString(funcString, x);
// Move the object
transform.position = Vector2 (x, y);
}
// Return the hit variable
return hit;
}
/**
* Takes String and Returns a double
*/
float CalculateString(string func, float x) {
// Final string
string final = "";
// Holder for all the words
string[] words = func.Split(' ');
// Foreach statement to replace x
foreach (string word in words)
{
string temp;
if (word.Length > 1) {
temp = word.Replace("x"," * " + x.ToString());
} else {
temp = word.Replace("x", x.ToString());
}
final = final + " " + temp;
}
// Replace commas with full stops for the calculation function
final = final.Replace(",", ".");
// Calculate and return the string
float result = (float) Convert.ToDouble(new DataTable().Compute(final, null));
return result;
}
/*
* On Collision for when it hits an object
* Possibly change to OnTriggerEnter
*/
void OnCollisionEnter (Collision other) {
hit = true;
}
Small disclaimer. I have not tested this in Unity. I have however tested this in C# and the function works. Just ensure you use operators Seperately from numbers and other functions (Except for muliplicaiton). example:
string func = "14x / x + 5x"; // CORRECT
string func = "14x/x+x"; // WRONG
A simple solution would be to get function points more or less regularly spaced and check the line segment between each two consecutive points with Linecast. You would not need a lot of points, since the colliders usually aren’t too small - maybe a distance about 0.2 units between points could do the job.
Another possibly faster solution could be to check whether any of these points hit a collider with Physics2D.OverlapPoint - you could even add some “thickness” to the curve by using OverlapCircle instead.