201 lines
7.9 KiB
C#
201 lines
7.9 KiB
C#
/*
|
|
------------------- Code Monkey -------------------
|
|
|
|
Thank you for downloading this package
|
|
I hope you find it useful in your projects
|
|
If you have any questions let me know
|
|
Cheers!
|
|
|
|
unitycodemonkey.com
|
|
--------------------------------------------------
|
|
*/
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace GridPathfindingSystem {
|
|
|
|
public class UnitMovement {
|
|
|
|
private List<PathNode> pathList;
|
|
private int curX = 7;
|
|
private int curY = 0;
|
|
private float speed = 30f;
|
|
public delegate Vector3 DelGetPosition();
|
|
private DelGetPosition getPosition;
|
|
public delegate void DelSetPosition(Vector3 set);
|
|
private DelSetPosition setPosition;
|
|
public delegate void PathCallback(GridPathfinding.UnitMovementCallbackType cType, object obj);
|
|
private PathCallback pathCallback;
|
|
private GridPathfinding.UnitMovementCallbackType callbackType;
|
|
private object obj;
|
|
private bool isMoving = false;
|
|
private MapPos finalPos;
|
|
private MapPos mapPos;
|
|
private LastMoveTo lastMoveTo;
|
|
public bool destroyed = false;
|
|
private Vector3 lastDir = Vector3.zero;
|
|
|
|
//private int layerMask = 1 << 9;
|
|
|
|
public void Setup(MapPos mapPos, DelGetPosition getPosition, DelSetPosition setPosition, float speed) {
|
|
this.mapPos = mapPos;
|
|
this.getPosition = getPosition;
|
|
this.setPosition = setPosition;
|
|
this.speed = speed;
|
|
}
|
|
// Update is called once per frame
|
|
public void Update(float deltaTime) {
|
|
if (pathList == null || (pathList != null && pathList.Count <= 0)) {
|
|
return;
|
|
}
|
|
Vector3 pos = getPosition();
|
|
isMoving = true;
|
|
PathNode currPath = pathList[0];
|
|
Vector3 currPos;
|
|
float distanceCheck = 2f;
|
|
if (pathList.Count == 1) { // Last Pos
|
|
distanceCheck = 1f;
|
|
currPos = new Vector3(currPath.xPos * 10 + finalPos.offsetX, currPath.yPos * 10 + finalPos.offsetY);
|
|
} else {
|
|
currPos = new Vector3(currPath.xPos * 10, currPath.yPos * 10);
|
|
}
|
|
|
|
// Move to path
|
|
Vector3 dir = (currPos - pos).normalized;
|
|
lastDir = dir;
|
|
float moveAmount = Mathf.Min(deltaTime * speed, Vector3.Distance(pos, currPos));
|
|
Vector3 dirAmt = (dir * moveAmount);
|
|
setPosition(new Vector3(pos.x + dirAmt.x, pos.y + dirAmt.y));
|
|
pos = getPosition();
|
|
|
|
if (pathList.Count > 1) { //Not last pos
|
|
MapPos prevPos = new MapPos(mapPos.x, mapPos.y);
|
|
if (mapPos.offsetX > 0 || mapPos.offsetY > 0) {
|
|
// Last target had an offset
|
|
if (Mathf.RoundToInt(pos.x / 10f) == mapPos.x && Mathf.RoundToInt(pos.y / 10f) == mapPos.y) {
|
|
// Rounded position equals base MapPos without Offset
|
|
mapPos.x = Mathf.RoundToInt(pos.x / 10f);
|
|
mapPos.y = Mathf.RoundToInt(pos.y / 10f);
|
|
mapPos.offsetX = 0f;
|
|
mapPos.offsetY = 0f;
|
|
}
|
|
} else {
|
|
mapPos.x = Mathf.RoundToInt(pos.x / 10f);
|
|
mapPos.y = Mathf.RoundToInt(pos.y / 10f);
|
|
}
|
|
|
|
if (prevPos.x != mapPos.x || prevPos.y != mapPos.y) {
|
|
//Event_Speaker.Broadcast(Event_Trigger.Unit_Moved, mapPos);
|
|
//unit.OnUnitMoved(prevPos, mapPos);
|
|
}
|
|
}
|
|
|
|
if (Vector3.Distance(pos, currPos) < distanceCheck) {
|
|
// Next path
|
|
pathList.RemoveAt(0);
|
|
if (pathList.Count == 0) {
|
|
// Final destination reached
|
|
setPosition(currPos);
|
|
pathList = null;
|
|
|
|
mapPos.offsetX = finalPos.offsetX;
|
|
mapPos.offsetY = finalPos.offsetY;
|
|
mapPos.straightToOffset = finalPos.straightToOffset;
|
|
if (finalPos.straightToOffset) {
|
|
mapPos.x = finalPos.x;
|
|
mapPos.y = finalPos.y;
|
|
}
|
|
PathComplete();
|
|
}
|
|
}
|
|
}
|
|
public Vector3 GetLastDir() {
|
|
return lastDir;
|
|
}
|
|
public void SetSpeed(float spd) {
|
|
speed = spd;
|
|
}
|
|
public void PathComplete() {
|
|
if (destroyed) return;
|
|
isMoving = false;
|
|
if (pathCallback != null) {
|
|
pathCallback(callbackType, obj);
|
|
}
|
|
}
|
|
public void OnPathComplete(List<PathNode> path, MapPos _mapPos) {
|
|
if (destroyed) return;
|
|
MapPos previousFinalPos = finalPos;
|
|
finalPos = _mapPos;
|
|
|
|
//Debug.Log("Pathfind - "+finalPos);
|
|
//Optimize path, look for direct shortcuts.
|
|
|
|
/*
|
|
RaycastHit hit;
|
|
for (int i=0; i<path.Count-2; i++) {
|
|
Vector3 pos = new Vector3(path[i].xPos*10,0,path[i].zPos*10);
|
|
//If this is on top of a hitbox, don't shortcut
|
|
if (Physics.Raycast(new Vector3(pos.x, 1, pos.z), new Vector3(0,-1,0), out hit, 2, layerMask)) {
|
|
continue;
|
|
}
|
|
|
|
for (int j=i+1; j<path.Count-1; j++) {
|
|
Vector3 pos2 = new Vector3(path[j].xPos*10,0,path[j].zPos*10);
|
|
if (!Physics.Raycast(pos, (pos2-pos).normalized, out hit, Vector3.Distance(pos,pos2), layerMask)) {
|
|
if (j > i+1) {
|
|
path.RemoveAt(j-1);
|
|
j--;
|
|
}
|
|
} else {
|
|
//Debug.Log("hit");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
// See if going to path[0] involves going backwards
|
|
// Check if Distance(currentPos,path[1]) < Distance(path[0],path[1])
|
|
if (path.Count > 1 && (previousFinalPos == null || (previousFinalPos.offsetX == 0 && previousFinalPos.offsetY == 0))) {
|
|
if (Vector3.Distance(getPosition(), new Vector3(path[1].xPos * 10, path[1].yPos * 10)) <
|
|
Vector3.Distance(new Vector3(path[0].xPos * 10, path[0].yPos * 10), new Vector3(path[1].xPos * 10, path[1].yPos * 10))) {
|
|
//Currently closer, skip first position
|
|
path.RemoveAt(0);
|
|
}
|
|
}
|
|
pathList = path;
|
|
}
|
|
|
|
public bool MoveTo(MapPos _mapPos, GridPathfinding.UnitMovementCallbackType _callbackType = GridPathfinding.UnitMovementCallbackType.Simple, object _obj = null, PathCallback callback = null) {
|
|
lastMoveTo = new LastMoveTo(_mapPos, _callbackType, _obj, callback);
|
|
callbackType = _callbackType;
|
|
obj = _obj;
|
|
pathCallback = callback;
|
|
curX = mapPos.x;
|
|
curY = mapPos.y;
|
|
|
|
//return MyPathfinding.FindPath(curX,curY,_mapPos,OnPathComplete);
|
|
return false;
|
|
}
|
|
public bool MoveTo(List<MapPos> _mapPos, GridPathfinding.UnitMovementCallbackType _callbackType, object _obj, PathCallback callback) {
|
|
lastMoveTo = new LastMoveTo(_mapPos, _callbackType, _obj, callback);
|
|
callbackType = _callbackType;
|
|
obj = _obj;
|
|
pathCallback = callback;
|
|
curX = mapPos.x;
|
|
curY = mapPos.y;
|
|
|
|
//return MyPathfinding.FindPath(curX,curY,_mapPos,OnPathComplete);
|
|
return false;
|
|
}
|
|
public bool MoveTo(LastMoveTo _lastMoveTo) {
|
|
return MoveTo(_lastMoveTo.mapPos, _lastMoveTo.callbackType, _lastMoveTo.obj, _lastMoveTo.callback);
|
|
}
|
|
public void DestroySelf() {
|
|
destroyed = true;
|
|
}
|
|
}
|
|
|
|
} |