Check if the player is off/on the path. (3D; c#)
Im currently making a small horror game but have hit a snag. I cant figure out how to check if the player has gone off the path and into the woods. Now i dont want to stop them from doing this(personaly i think it makes it more interesting) but when they do i want them to take a type of damage so to speak(the player has an insanity/fear(still undecided) level that drops procedurally but i want this to accelerate when they do go off the path(the player doesnt die but it does trigger more difficultys)) now i have all the rest of that but i cannot figure out how to see if the player has gone off the path/road/trail(what ever lol;) any idea or tip would be useful i tried colliders but they restricted movement especially while running away from monsters, im wondering if there is a way to check if the player is on a different texture but how would that work with overlapping textures, and indifferent opacitys.
Anything would help idea, code, concepts, the works
Oh yea, this is 3d and i code in c#
Thank you!
Answer by felipin · Jul 03, 2018 at 03:34 AM
I don't know if I got you, but I wrote a component that could help you. This component describes a path using a array of points and has a method GetClosestPosition
that returns the closest point on the path, so you can define the damage by the distance between this point and player position. If you're gonna copy and paste this component to your project, see how it's works (there're some Gizmos that could help you figure out how it works) add some points to the path and assign a player transform.
(This is not the best code, I'd not use GetClosestPosition
inside a Update method, but works)
class Path : MonoBehaviour {
public Vector3[] points = new Vector3[0];
public Transform player;
private void OnDrawGizmos() {
const float sphereSize = 0.2f;
if (points.Length > 0) {
Gizmos.DrawSphere(points[0], sphereSize);
for (int i = 1; i < points.Length; i++) {
Gizmos.DrawSphere(points[i - 1], sphereSize);
Gizmos.DrawSphere(points[i], sphereSize);
Gizmos.DrawLine(points[i - 1], points[i]);
}
if (player) {
Gizmos.color = Color.red;
var cloesestPosition = GetClosestPosition(player.position);
Gizmos.DrawSphere(player.position, sphereSize);
Gizmos.DrawSphere(cloesestPosition, sphereSize);
Gizmos.DrawLine(cloesestPosition, player.position);
Gizmos.color = Color.white;
}
}
}
public Vector3 GetClosestPosition(Vector3 position) {
if (points.Length == 0) {
return position;
}
return GetClosestPosition(GetClosestPoint(position), position);
}
private Vector3 GetClosestPosition(int closestIndex, Vector3 position) {
Assert.IsTrue(closestIndex >= 0 && closestIndex < points.Length);
if (points.Length == 1) {
return points[0];
}
if (closestIndex == 0) {
return GetClosestPointOnLineSegment(points[closestIndex], points[closestIndex + 1], position);
}
else if (closestIndex == points.Length - 1) {
return GetClosestPointOnLineSegment(points[closestIndex], points[closestIndex - 1], position);
}
var a = GetClosestPointOnLineSegment(points[closestIndex], points[closestIndex + 1], position);
var b = GetClosestPointOnLineSegment(points[closestIndex], points[closestIndex - 1], position);
var ad = (position - a).sqrMagnitude;
var bd = (position - b).sqrMagnitude;
return ad < bd ? a : b;
}
private int GetClosestPoint(Vector3 position) {
int closestPointIndex = 0;
float closestSqrtDistance = float.MaxValue;
for (int i = 0; i < points.Length; i++) {
var sqrtDistance = (points[i] - position).sqrMagnitude;
if (sqrtDistance < closestSqrtDistance) {
closestSqrtDistance = sqrtDistance;
closestPointIndex = i;
}
}
return closestPointIndex;
}
private static Vector3 GetClosestPointOnLineSegment(Vector3 a, Vector3 b, Vector3 p) {
var ap = p - a;
var ab = b - a;
float dot = Vector3.Dot(ap, ab);
float distance = Vector3.Dot(ap, ab) / ab.sqrMagnitude;
if (distance < 0) {
return a;
}
return (distance > 1) ? b : a + ab * distance;
}
}
This is great! I wasn’t expecting a full code set lol; this would be great but the path brances forks and loops with dead ends alot so a straight line wont work but its still a great piece of code!! And a very creative solution.
Im gonna try to modify it to have paths as best i can thank you!
Your answer
Follow this Question
Related Questions
Any ideas in relate to a cube rolling? thank you! 0 Answers
Ground check BoxCast is detecting when player hits bottom of platform. UNITY 2D C# 0 Answers
How to prevent the player to move beyond certain x-position value 3 Answers
Transfering script to other game objects via code (Unity 2D) 0 Answers
Raw Image changing texture in inspector but not in game. 1 Answer