Adding A* Algorythm and carpet roads

This commit is contained in:
Nicolas SANS
2023-04-24 15:49:03 +02:00
parent 75018ee6cd
commit 690e3fbd0b
685 changed files with 134125 additions and 19 deletions

View File

@ -0,0 +1,38 @@
using UnityEngine;
namespace Pathfinding.Examples {
/// <summary>
/// Smooth Camera Following.
/// \author http://wiki.unity3d.com/index.php/SmoothFollow2
/// </summary>
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_examples_1_1_astar_smooth_follow2.php")]
public class AstarSmoothFollow2 : MonoBehaviour {
public Transform target;
public float distance = 3.0f;
public float height = 3.0f;
public float damping = 5.0f;
public bool smoothRotation = true;
public bool followBehind = true;
public float rotationDamping = 10.0f;
public bool staticOffset = false;
void LateUpdate () {
Vector3 wantedPosition;
if (staticOffset) {
wantedPosition = target.position + new Vector3(0, height, distance);
} else {
if (followBehind)
wantedPosition = target.TransformPoint(0, height, -distance);
else
wantedPosition = target.TransformPoint(0, height, distance);
}
transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
if (smoothRotation) {
Quaternion wantedRotation = Quaternion.LookRotation(target.position - transform.position, target.up);
transform.rotation = Quaternion.Slerp(transform.rotation, wantedRotation, Time.deltaTime * rotationDamping);
} else transform.LookAt(target, target.up);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 46fb00c7e6ad9485282a146ad398a2a5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,59 @@
using UnityEngine;
namespace Pathfinding.Examples {
/// <summary>Example script used in the example scenes</summary>
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_examples_1_1_door_controller.php")]
public class DoorController : MonoBehaviour {
private bool open = false;
public int opentag = 1;
public int closedtag = 1;
public bool updateGraphsWithGUO = true;
public float yOffset = 5;
Bounds bounds;
public void Start () {
// Capture the bounds of the collider while it is closed
bounds = GetComponent<Collider>().bounds;
// Initially open the door
SetState(open);
}
void OnGUI () {
// Show a UI button for opening and closing the door
if (GUI.Button(new Rect(5, yOffset, 100, 22), "Toggle Door")) {
SetState(!open);
}
}
public void SetState (bool open) {
this.open = open;
if (updateGraphsWithGUO) {
// Update the graph below the door
// Set the tag of the nodes below the door
// To something indicating that the door is open or closed
GraphUpdateObject guo = new GraphUpdateObject(bounds);
int tag = open ? opentag : closedtag;
// There are only 32 tags
if (tag > 31) { Debug.LogError("tag > 31"); return; }
guo.modifyTag = true;
guo.setTag = tag;
guo.updatePhysics = false;
AstarPath.active.UpdateGraphs(guo);
}
// Play door animations
if (open) {
GetComponent<Animation>().Play("Open");
} else {
GetComponent<Animation>().Play("Close");
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e96422fbb088f477baaf6f2ada396863
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,55 @@
using UnityEngine;
namespace Pathfinding.Examples {
/// <summary>
/// AI controller specifically made for the spider robot.
/// Deprecated: This script has been replaced by Pathfinding.Examples.MineBotAnimation. Any uses of this script in the Unity editor will be automatically replaced by one AIPath component and one MineBotAnimation component.
/// </summary>
[RequireComponent(typeof(Seeker))]
[System.Obsolete("This script has been replaced by Pathfinding.Examples.MineBotAnimation. Any uses of this script in the Unity editor will be automatically replaced by one AIPath component and one MineBotAnimation component.")]
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_examples_1_1_mine_bot_a_i.php")]
public class MineBotAI : AIPath {
/// <summary>
/// Animation component.
/// Should hold animations "awake" and "forward"
/// </summary>
public Animation anim;
/// <summary>Minimum velocity for moving</summary>
public float sleepVelocity = 0.4F;
/// <summary>Speed relative to velocity with which to play animations</summary>
public float animationSpeed = 0.2F;
/// <summary>
/// Effect which will be instantiated when end of path is reached.
/// See: OnTargetReached
/// </summary>
public GameObject endOfPathEffect;
#if UNITY_EDITOR
protected override int OnUpgradeSerializedData (int version, bool unityThread) {
if (unityThread) {
var components = gameObject.GetComponents<Component>();
int index = System.Array.IndexOf(components, this);
foreach (System.Type newType in new [] { typeof(AIPath), typeof(MineBotAnimation) }) {
var newComp = gameObject.AddComponent(newType);
foreach (var field in newComp.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)) {
var oldField = this.GetType().GetField(field.Name);
try {
if (oldField != null) field.SetValue(newComp, oldField.GetValue(this));
} catch (System.Exception e) {
Debug.LogError("Failed to upgrade some fields.\n" + e);
}
}
for (int i = components.Length - 1; i > index; i--) UnityEditorInternal.ComponentUtility.MoveComponentUp(newComp);
}
GameObject.DestroyImmediate(this);
return 0;
} else {
return base.OnUpgradeSerializedData(version, unityThread);
}
}
#endif
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3f35b84b127b849e38b74966118e7e0f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,73 @@
using UnityEngine;
namespace Pathfinding.Examples {
/// <summary>
/// Animation helper specifically made for the spider robot in the example scenes.
/// The spider robot (or mine-bot) which has been copied from the Unity Example Project
/// can have this script attached to be able to pathfind around with animations working properly.\n
/// This script should be attached to a parent GameObject however since the original bot has Z+ as up.
/// This component requires Z+ to be forward and Y+ to be up.\n
///
/// A movement script (e.g AIPath) must also be attached to the same GameObject to actually move the unit.
///
/// Animation is handled by this component. The Animator component refered to in <see cref="anim"/> should have a single parameter called NormalizedSpeed.
/// When the end of path is reached, if the <see cref="endOfPathEffect"/> is not null, it will be instantiated at the current position. However a check will be
/// done so that it won't spawn effects too close to the previous spawn-point.
/// [Open online documentation to see images]
/// </summary>
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_examples_1_1_mine_bot_animation.php")]
public class MineBotAnimation : VersionedMonoBehaviour {
/// <summary>
/// Animation component.
/// Should hold animations "awake" and "forward"
/// </summary>
public Animator anim;
/// <summary>
/// Effect which will be instantiated when end of path is reached.
/// See: <see cref="OnTargetReached"/>
/// </summary>
public GameObject endOfPathEffect;
bool isAtDestination;
IAstarAI ai;
Transform tr;
protected override void Awake () {
base.Awake();
ai = GetComponent<IAstarAI>();
tr = GetComponent<Transform>();
}
/// <summary>Point for the last spawn of <see cref="endOfPathEffect"/></summary>
protected Vector3 lastTarget;
/// <summary>
/// Called when the end of path has been reached.
/// An effect (<see cref="endOfPathEffect)"/> is spawned when this function is called
/// However, since paths are recalculated quite often, we only spawn the effect
/// when the current position is some distance away from the previous spawn-point
/// </summary>
void OnTargetReached () {
if (endOfPathEffect != null && Vector3.Distance(tr.position, lastTarget) > 1) {
GameObject.Instantiate(endOfPathEffect, tr.position, tr.rotation);
lastTarget = tr.position;
}
}
protected void Update () {
if (ai.reachedEndOfPath) {
if (!isAtDestination) OnTargetReached();
isAtDestination = true;
} else isAtDestination = false;
// Calculate the velocity relative to this transform's orientation
Vector3 relVelocity = tr.InverseTransformDirection(ai.velocity);
relVelocity.y = 0;
// Speed relative to the character size
anim.SetFloat("NormalizedSpeed", relVelocity.magnitude / anim.transform.lossyScale.x);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8503d71a898994d3288ce1708e2707fe
timeCreated: 1516539312
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,78 @@
using UnityEngine;
using System.Collections;
namespace Pathfinding.Examples {
/// <summary>Small sample script for placing obstacles</summary>
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_examples_1_1_object_placer.php")]
public class ObjectPlacer : MonoBehaviour {
/// <summary>
/// GameObject to place.
/// When using a Grid Graph you need to make sure the object's layer is included in the collision mask in the GridGraph settings.
/// </summary>
public GameObject go;
/// <summary>Flush Graph Updates directly after placing. Slower, but updates are applied immidiately</summary>
public bool direct = false;
/// <summary>Issue a graph update object after placement</summary>
public bool issueGUOs = true;
/// <summary>Update is called once per frame</summary>
void Update () {
if (Input.GetKeyDown("p")) {
PlaceObject();
}
if (Input.GetKeyDown("r")) {
StartCoroutine(RemoveObject());
}
}
public void PlaceObject () {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// Figure out where the ground is
if (Physics.Raycast(ray, out hit, Mathf.Infinity)) {
Vector3 p = hit.point;
GameObject obj = GameObject.Instantiate(go, p, Quaternion.identity) as GameObject;
if (issueGUOs) {
Bounds b = obj.GetComponent<Collider>().bounds;
GraphUpdateObject guo = new GraphUpdateObject(b);
AstarPath.active.UpdateGraphs(guo);
if (direct) {
AstarPath.active.FlushGraphUpdates();
}
}
}
}
public IEnumerator RemoveObject () {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// Check what object is under the mouse cursor
if (Physics.Raycast(ray, out hit, Mathf.Infinity)) {
// Ignore ground and triggers
if (hit.collider.isTrigger || hit.transform.gameObject.name == "Ground") yield break;
Bounds b = hit.collider.bounds;
Destroy(hit.collider);
Destroy(hit.collider.gameObject);
if (issueGUOs) {
// In Unity, object destruction is actually delayed until the end of the Update loop.
// This means that we need to wait until the end of the frame (or until the next frame) before
// we update the graph. Otherwise the graph would still think that the objects are there.
yield return new WaitForEndOfFrame();
GraphUpdateObject guo = new GraphUpdateObject(b);
AstarPath.active.UpdateGraphs(guo);
if (direct) {
AstarPath.active.FlushGraphUpdates();
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 687e3bc0934ac46d3957e59872965f3c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}

View File

@ -0,0 +1,21 @@
using UnityEngine;
using System.Collections;
using Pathfinding;
/// <summary>
/// Helper editor script to snap an object to the closest node.
/// Used in the "Turn Based" example scene for snapping obstacles to the hexagon grid.
/// </summary>
[ExecuteInEditMode]
[HelpURL("http://arongranberg.com/astar/docs/class_snap_to_node.php")]
public class SnapToNode : MonoBehaviour {
void Update () {
if (transform.hasChanged && AstarPath.active != null) {
var node = AstarPath.active.GetNearest(transform.position, NNConstraint.None).node;
if (node != null) {
transform.position = (Vector3)node.position;
transform.hasChanged = false;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c0acfdba178b145239678a03b9df938a
timeCreated: 1453723051
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
using UnityEngine;
using System.Linq;
namespace Pathfinding {
/// <summary>
/// Moves the target in example scenes.
/// This is a simple script which has the sole purpose
/// of moving the target point of agents in the example
/// scenes for the A* Pathfinding Project.
///
/// It is not meant to be pretty, but it does the job.
/// </summary>
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_target_mover.php")]
public class TargetMover : MonoBehaviour {
/// <summary>Mask for the raycast placement</summary>
public LayerMask mask;
public Transform target;
IAstarAI[] ais;
/// <summary>Determines if the target position should be updated every frame or only on double-click</summary>
public bool onlyOnDoubleClick;
public bool use2D;
Camera cam;
public void Start () {
//Cache the Main Camera
cam = Camera.main;
// Slightly inefficient way of finding all AIs, but this is just an example script, so it doesn't matter much.
// FindObjectsOfType does not support interfaces unfortunately.
ais = FindObjectsOfType<MonoBehaviour>().OfType<IAstarAI>().ToArray();
useGUILayout = false;
}
public void OnGUI () {
if (onlyOnDoubleClick && cam != null && Event.current.type == EventType.MouseDown && Event.current.clickCount == 2) {
UpdateTargetPosition();
}
}
/// <summary>Update is called once per frame</summary>
void Update () {
if (!onlyOnDoubleClick && cam != null) {
UpdateTargetPosition();
}
}
public void UpdateTargetPosition () {
Vector3 newPosition = Vector3.zero;
bool positionFound = false;
if (use2D) {
newPosition = cam.ScreenToWorldPoint(Input.mousePosition);
newPosition.z = 0;
positionFound = true;
} else {
// Fire a ray through the scene at the mouse position and place the target where it hits
RaycastHit hit;
if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity, mask)) {
newPosition = hit.point;
positionFound = true;
}
}
if (positionFound && newPosition != target.position) {
target.position = newPosition;
if (onlyOnDoubleClick) {
for (int i = 0; i < ais.Length; i++) {
if (ais[i] != null) ais[i].SearchPath();
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f903c2eb621d8418d88f8dad81b13dc6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}