Hi. So, unity project preset to 2d (stupid, stupid, should’ve done 3d preset and oriented everything along x and z, throw in NavMesh and be done with it, but i wanted to have a bit of training). First, please, no answers like “why reinvent the wheel?” and links to A* or other stuff, I’d love to get this solution of mine working…
Secondly, the logic is supposed to go roughly like this:
(agent-enemy has CircleCollider2D, walls are BoxCollider2D)
- cast a ray from current position to player
- if it hits nothing, add the end point as a waypoint, and we’re done. if it hits a wall, add a point next to the wall to list of waypoints, then (recursively, by calling the function again) go along the wall to where its collider ends, add that point as another waypoint, and (again, by calling itself recursively) cast a ray from that point to the player.
But, instead of pathing around the wall’s collider, it flawlessly paths INTO the center of the collider…
My (not yet complete, but the gist is there) code is this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class EnemyNavigator : MonoBehaviour {
Transform player;
Vector3 targetPosition;
Vector3 targetShot;
public float rotationSpeed = 0.3f;
public int maxPathfindIterations = 30;
private List<Vector3> path;
// Use this for initialization
void Start () {
player = GameObject.FindGameObjectWithTag("Player").transform;
}
public bool PathfindTowards(Vector3 position)
{
path = PathfindTowardsRecursive(position, null, 0);
if (path == null) return false; else return true;
}
private List<Vector3> PathfindTowardsRecursive(Vector3 position, Nullable<Vector3> from, int iteration=0){
if (iteration > maxPathfindIterations) return null;
Debug.Log("PF(" + iteration + "): iteration: " + iteration);
//raycast towards position, if collides, store collision point as path point, and raycast within range along the possible direction
RaycastHit2D rh, rh2;
Vector3 newPoint;
List<Vector3> localPath = new List<Vector3>();
if(!from.HasValue) from = transform.position;
//rh = Physics2D.Raycast(from.Value, position - from.Value);
rh = Physics2D.CircleCast(from.Value, 1, position - from.Value);
Debug.Log("PF(" + iteration + "): from: " + from.Value);
if (rh.collider != null)
{
Debug.Log("PF(" + iteration + "): colPoint: " + rh.point);
localPath.Add(rh.centroid);
Debug.DrawLine(from.Value, (Vector3)rh.point, Color.blue, 10);
float newTargetX, newTargetY;
//this is incomplete, handles/should handle only a case of vertical wall between enemy and player yet
if (transform.position.y > position.y) newTargetY = rh.collider.bounds.min.y - transform.lossyScale.y / 2;
else newTargetY = rh.collider.bounds.max.y + transform.lossyScale.y / 2;
if (Mathf.Abs(transform.position.x - rh.collider.bounds.max.x) < Mathf.Abs(transform.position.x - rh.collider.bounds.min.x))
newTargetX = rh.collider.bounds.max.x + transform.lossyScale.x / 2;
else
newTargetX = rh.collider.bounds.min.x - transform.lossyScale.x / 2;
//end of the incomplete part handling only vertical wall
localPath.AddRange(PathfindTowardsRecursive(new Vector3(newTargetX, newTargetY, 0), rh.point, iteration+1));
}
else
{
localPath.Add(position);
}
Debug.Log("PF-END(" + iteration + "): iteration: " + iteration);
return localPath;
}
}
Any ideas where and why I’m stupid? Thanks ![]()