I want to change GUI button text when I click a UI button. onGUI() method which I have written, is below.
This method is used to create new buttons when the button is clicked and to show the Sub-parts of a tree structure.
If I show you the change I want to make in the code, for example, when I click UI Latin Button, currentPart.EnglishTitle changes like currentPart.LatinTitle. I also mentioned this part as a comment in the code
currentPart is a HumanBodyPart object. HumanBodyPart is a class that stores my nodes of my tree structure.
I give you the necessary parts of my code. If there is a missing part in the code that I have given, I can edit the desired parts.
onGUI() method is here...
private void OnGUI()
{
Vector3 scale = new Vector3(Screen.width / nativeSize.x, Screen.height / nativeSize.y, 1.0f);
GUI.matrix = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, scale);
float spacing = 25;
float x = 7 + spacing;
float y = 63;
HumanBodyPart mainBodyPart = bodyVisualizer.BodyData.Body.SubParts[0];
List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
List<HumanBodyPart> allPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
scrollPosition = GUI.BeginScrollView(new Rect(7, y, 264, 485), scrollPosition, new Rect(7, y, 528, scrollPosition_y));
while (nextPartsToRender.Count > 0)
{
HumanBodyPart currentPart = nextPartsToRender[0];
nextPartsToRender.RemoveAt(0);
//The place I want to change above is the place "currentPart.English" in a bottom line
if (GUI.Button(new Rect(currentPart.DrawDepth * spacing + x, y, 200, 20), currentPart.EnglishTitle))
{
if (!currentPart.IsClicked)
{
currentPart.IsClicked = true;
HumanBodyVisualizer.ShowMode showModeFullBody = HumanBodyVisualizer.ShowMode.Invisible;
bodyVisualizer.ShowBody(showModeFullBody);
AllSubPartsAndRoot.Insert(AllSubPartsAndRoot.Count, currentPart);
addAllSubPartsOfClickButton(currentPart, AllSubPartsAndRoot, AllSubPartsAndRoot.Count - 1);
HumanBodyVisualizer.ShowMode showModeCurrentPart = HumanBodyVisualizer.ShowMode.LowTransparent;
for (int i = 0; i < AllSubPartsAndRoot.Count; i++)
{
bodyVisualizer.ShowBodyPart(showModeCurrentPart, AllSubPartsAndRoot[i]);
}
}
else
{
currentPart.IsClicked = false;
List<HumanBodyPart> RemoveBodyParts = new List<HumanBodyPart>();
RemoveBodyParts.Insert(0, currentPart);
addAllSubPartsOfClickButton(currentPart, RemoveBodyParts, 1);
for (int i = 0; i < RemoveBodyParts.Count; i++)
{
if (AllSubPartsAndRoot.Contains(RemoveBodyParts[i]))
{
bodyVisualizer.ShowBodyPart(HumanBodyVisualizer.ShowMode.Invisible, RemoveBodyParts[i]);
AllSubPartsAndRoot.Remove(RemoveBodyParts[i]);
}
}
if (AllSubPartsAndRoot.Count == 0)
{
bodyVisualizer.ShowBody(HumanBodyVisualizer.ShowMode.LowTransparent);
}
else
{
for (int ii = 0; ii < AllSubPartsAndRoot.Count; ii++)
{
bodyVisualizer.ShowBodyPart(HumanBodyVisualizer.ShowMode.LowTransparent, AllSubPartsAndRoot[ii]);
}
}
}
}
if (currentPart.SubParts.Count != 0)
{
if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing, y, 20, 20), ">"))
{
if (!currentPart.IsExpanded)
{
currentPart.IsExpanded = true;
}
else
currentPart.IsExpanded = false;
}
if (currentPart.IsExpanded)
{
nextPartsToRender.InsertRange(0, currentPart.SubParts);
allPartsToRender.InsertRange(allPartsToRender.Count - 1, currentPart.SubParts);
scrollPosition_y = allPartsToRender.Count * spacing;
}
}
y += spacing;
index++;
}
// End the scroll view that we began above.
GUI.EndScrollView();
}
public Button turkishButton;
public Button englishButton;
public Button latinButton;
The above is UI buttons in the script.
In general you shouldn't use OnGUI but rather the Unity UI system.
You could just have a string with the text to display and do e.g.
private string onGuiButtonLabel;
public Button turkishButton;
public Button englishButton;
public Button latinButton;
private void Awake()
{
turkishButton.onClick.AddListener(()=>{onGuiButtonLabel = "Turkish";})
englishButton.onClick.AddListener(()=>{onGuiButtonLabel = "English";})
latinButton.onClick.AddListener(()=>{onGuiButtonLabel = "Latin";})
}
and then in OnGUI you use
if (GUI.Button(new Rect(currentPart.DrawDepth * spacing + x, y, 200, 20), onGuiButtonLabel))
or maybe use a kind of Dictionary with an enum like
public Language
{
English,
Turkish,
Latin
}
private Dictionary<Language, string>() titles;
private Language curentLanguage;
// or wherever you want to initialize it
private void Awake()
{
titles = new Dictionary<Language, string>()
{
{Language.English, currentPart.EnglishTitle}
{Language.Turkish, currentPart.TurkishTitle}
{Language.Latin, currentPart.LatinTitle}
}
turkishButton.onClick.AddListener(()=>{curentLanguage = Language.Turkish;})
englishButton.onClick.AddListener(()=>{curentLanguage = Language.English;})
latinButton.onClick.AddListener(()=>{curentLanguage = Language.Latin;})
}
and then in OnGUI use
if (GUI.Button(new Rect(currentPart.DrawDepth * spacing + x, y, 200, 20), titles[currentLanguage]))
I'm trying to learn about compute shaders, and this project is really awesome. It is https://github.com/TheAllenChou/unity-cj-lib
But when I run it, there are errors I can't figure out how to get rid of:
ArgumentNullException: Value cannot be null. Parameter name: shader
ArgumentNullException: Value cannot be null. Parameter name: material
Compute shader (ParticleLogic): Property (particleBuffer) at kernel index (1) is not set
Any idea on how to fix? I'm using Unity 2019.3.0a7
It's only happening for the code for the "Turbulent Rainbow GPU Particles" example, so I've been going to the files and changing filepaths, and trying to feed it a material manually.
I just don't think I understand what's happening enough to ever fix it on my own, so I am reaching out for assistance. Appreciate any help.
Relevant code...
using UnityEngine;
using CjLib;
namespace TurbulentRainbowGpuParticles
{
public class Main : MonoBehaviour
{
public ComputeShader m_shader;
private const int kNumParticles = 10000;
/*
private struct Particle
{
// 4 floats
Vector3 m_position;
float m_damping;
// 4 floats
Quaternion m_rotation;
// 4 floats
Vector3 m_linearVelocity;
float m_scale;
// 4 floats
Quaternion m_angularVelocity;
// 4 floats
Vector4 m_lifetime;
// 4 floats
Color m_color;
};
*/
private ComputeBuffer m_computeBuffer;
private ComputeBuffer m_instanceArgsBuffer;
//private Particle[] m_debugBuffer;
private Mesh m_mesh;
private Material m_material;
private MaterialPropertyBlock m_materialProperties;
private int m_csInitKernelId;
private int m_csStepKernelId;
private int m_csParticleBufferId;
private int m_csScaleId;
private int m_csDampingId;
private int m_csSpeedId;
private int m_csLifetimeId;
private int m_csNumParticlesId;
private int m_csTimeId;
void OnEnable()
{
m_mesh = new Mesh();
m_mesh = PrimitiveMeshFactory.BoxFlatShaded();
int particleStride = sizeof(float) * 24;
m_computeBuffer = new ComputeBuffer(kNumParticles, particleStride);
uint[] instanceArgs = new uint[] { 0, 0, 0, 0, 0 };
m_instanceArgsBuffer = new ComputeBuffer(1, instanceArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
instanceArgs[0] = (uint) m_mesh.GetIndexCount(0);
instanceArgs[1] = (uint) kNumParticles;
instanceArgs[2] = (uint) m_mesh.GetIndexStart(0);
instanceArgs[3] = (uint) m_mesh.GetBaseVertex(0);
m_instanceArgsBuffer.SetData(instanceArgs);
//m_debugBuffer = new Particle[kNumParticles];
m_csInitKernelId = m_shader.FindKernel("Init");
m_csStepKernelId = m_shader.FindKernel("Step");
m_csParticleBufferId = Shader.PropertyToID("particleBuffer");
m_csScaleId = Shader.PropertyToID("scale");
m_csDampingId = Shader.PropertyToID("damping");
m_csSpeedId = Shader.PropertyToID("speed");
m_csLifetimeId = Shader.PropertyToID("lifetime");
m_csNumParticlesId = Shader.PropertyToID("numParticles");
m_csTimeId = Shader.PropertyToID("time");
m_material = new Material(Shader.Find("CjLib/Example/TurbulentRainbowGpuParticles"));
m_material.enableInstancing = true;
m_material.SetBuffer(m_csParticleBufferId, m_computeBuffer);
m_materialProperties = new MaterialPropertyBlock();
m_shader.SetFloats(m_csScaleId, new float[] { 0.15f, 0.3f });
m_shader.SetFloat(m_csDampingId, 6.0f);
m_shader.SetFloats(m_csSpeedId, new float[] { 3.0f, 4.0f, 1.0f, 6.0f });
m_shader.SetFloats(m_csLifetimeId, new float[] { 0.1f, 0.5f, 0.5f, 0.1f });
m_shader.SetInt(m_csNumParticlesId, kNumParticles);
m_shader.SetBuffer(m_csInitKernelId, m_csParticleBufferId, m_computeBuffer);
m_shader.SetBuffer(m_csStepKernelId, m_csParticleBufferId, m_computeBuffer);
m_shader.Dispatch(m_csInitKernelId, kNumParticles, 1, 1);
//m_computeBuffer.GetData(m_debugBuffer);
}
void Update()
{
m_shader.SetFloats(m_csTimeId, new float[] { Time.time, Time.fixedDeltaTime });
m_shader.Dispatch(m_csStepKernelId, kNumParticles, 1, 1);
//m_computeBuffer.GetData(m_debugBuffer);
Graphics.DrawMeshInstancedIndirect(m_mesh, 0, m_material, new Bounds(Vector3.zero, 20.0f * Vector3.one), m_instanceArgsBuffer, 0, m_materialProperties, UnityEngine.Rendering.ShadowCastingMode.On);
}
void OnDisable()
{
if (m_computeBuffer != null)
{
m_computeBuffer.Dispose();
m_computeBuffer = null;
}
if (m_instanceArgsBuffer != null)
{
m_instanceArgsBuffer.Dispose();
m_instanceArgsBuffer = null;
}
}
}
}
Fix:
Switch to the latest stable Unity version,
Fix Shader.Find via this method (unity Shader returns a NULL when using Shader.Find)
(optional) If you get C# language specification error like I did, visit TimeWalk-Org's post https://forum.unity.com/threads/feature-xxx-cannot-be-used-because-it-is-not-part-of-the-c-4-0-language-specification.575008/
The thing that I want to do is writing a method which can call in onGUI() method.
I wrote this method. However when I run the program , method did not show the effect.
private void ShowSubPartsOnClick(float x, float y, float widthLABEL, float heigth, HumanBodyPart bodyPart)
{
x = x + 14;
for(int i = 0; i < bodyPart.SubParts.Count; i++)
{
y = y + 14;
GUI.Label(new Rect(x+14,y,widthLABEL,heigth), bodyPart.SubParts[i].EnglishTitle);
if(GUI.Button(new Rect(x, y, 14, heigth),"+"))
{
ShowSubPartsOnClick(x, y, widthLABEL, heigth, bodyPart.SubParts[i]);
}
}
}
}
private void OnGUI()
{
GUI.Label(new Rect(text.transform.position.x+14, text.transform.position.y, text.rectTransform.sizeDelta.x, 14),bodyVisualizer.BodyData.Body.SubParts[0].EnglishTitle);
if(GUI.Button(new Rect(text.transform.position.x, text.transform.position.y, 14, 14), "+"))
{
ShowSubPartsOnClick(text.transform.position.x, text.transform.position.y, text.rectTransform.sizeDelta.x, 14, bodyVisualizer.BodyData.Body.SubParts[0]);
}
}
How can I fix this or what is the problem?
The challenge here is functions like GUI.Label and GUI.Button must be invoked directly from OnGUI to work:
From Unity Forums: "The only place you can draw/create GUI elements is by triggering them from inside an OnGUI function."
Given the recommendation there, one solution is to run an iterative depth first search via a while loop. See attached example.
That being said, I'd highly recommend using Unity Canvas instead of OnGUI. It's much more powerful and its programmatic logic is not constrained to a single function.
OnGUI Snippet:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HumanBodyPart
{
public string EnglishTitle;
public List<HumanBodyPart> SubParts;
public bool IsExpanded;
public int DrawDepth;
public HumanBodyPart(string title, HumanBodyPart[] subParts)
{
this.EnglishTitle = title;
this.SubParts = new List<HumanBodyPart>();
this.SubParts.AddRange(subParts);
this.IsExpanded = false;
this.DrawDepth = 0;
}
}
public class Script : MonoBehaviour
{
[SerializeField]
Text text;
HumanBodyPart mainBodyPart;
private void Start()
{
HumanBodyPart subSubSubBodyPart = new HumanBodyPart("SubSubSubBodyPart", new HumanBodyPart[] { });
HumanBodyPart subSubBodyPart1 = new HumanBodyPart("SubSubBodyPart1", new HumanBodyPart[] { subSubSubBodyPart });
HumanBodyPart subSubBodyPart2 = new HumanBodyPart("SubSubBodyPart2", new HumanBodyPart[] { });
HumanBodyPart subBodyPart = new HumanBodyPart("SubBodyPart", new HumanBodyPart[] { subSubBodyPart1, subSubBodyPart2});
mainBodyPart = new HumanBodyPart("BodyPart", new HumanBodyPart[] { subBodyPart });
UpdateDrawDepths(mainBodyPart);
}
private void UpdateDrawDepths(HumanBodyPart currentBodyPart, int currentDrawDepth=0)
{
currentBodyPart.DrawDepth = currentDrawDepth;
foreach (HumanBodyPart bodyPart in currentBodyPart.SubParts)
{
UpdateDrawDepths(bodyPart, currentDrawDepth + 1);
}
}
private void OnGUI()
{
float spacing = 30;
float x = text.transform.position.x + spacing;
float y = text.transform.position.y;
int drawDepth = 0;
List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
while (nextPartsToRender.Count > 0)
{
HumanBodyPart currentPart = nextPartsToRender[0];
GUI.Label(new Rect(currentPart.DrawDepth * spacing + x, y, 200, 20), currentPart.EnglishTitle);
nextPartsToRender.RemoveAt(0);
if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing, y, 20, 20), "+"))
{
currentPart.IsExpanded = true;
}
if (currentPart.IsExpanded)
{
nextPartsToRender.InsertRange(0, currentPart.SubParts);
}
y += spacing;
}
}
}
In one of my loops which I use to change the settings of my buttons, I also use the AddListener function rather then the one in the Inspector. I have 5 items, giving a range of "i" from 0-4, but when I print "i" trough the function it should call, it always logs 5, no matter what button I press, which is weird since "i" never even reaches 5. Any idea?
P.s. I use a CustomEditor to show the 2 buttons "Preview Layout" and "Delete Preview" in the inspector.
Code:
using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.UI;
public class RateMeManager : MonoBehaviour {
public GameObject rateMeCanvas;
public Sprite emptyStar, fullStar, button;
public float spriteWidth, spriteHeight, spritePadding;
[HideInInspector]
public GameObject currentCanvas, tempButton;
void Start () {
RemovePreview();
GenerateStars();
}
// Update is called once per frame
public void GenerateStars () {
RectTransform myRectTransform;
if (currentCanvas != null)
{
GameObject temp;
temp = currentCanvas;
DestroyImmediate(temp);
}
currentCanvas = Instantiate(rateMeCanvas, Vector3.zero, Quaternion.identity) as GameObject;
GameObject subCanvas = currentCanvas.transform.FindChild("subCanvas").gameObject;
myRectTransform = subCanvas.GetComponent<RectTransform>();
myRectTransform.sizeDelta = new Vector2((5*spriteWidth) + (4*spritePadding), spriteHeight);
myRectTransform.anchoredPosition = Vector2.zero;
Button[] buttons = subCanvas.GetComponentsInChildren<Button>();
float[] positions = new float[] {((2*spriteWidth)+(2*spritePadding))*-1, ((1 * spriteWidth) + (1 * spritePadding)) * -1 , 0, ((1 * spriteWidth) + (1 * spritePadding)), ((2 * spriteWidth) + (2 * spritePadding))};
for (int i = 0; i < buttons.Length; i++)
{
Debug.Log(i);
tempButton = buttons[i].gameObject;
tempButton.GetComponent<Button>().image.sprite = emptyStar;
myRectTransform = buttons[i].GetComponent<RectTransform>();
myRectTransform.sizeDelta = new Vector2(spriteWidth, spriteHeight);
myRectTransform.anchoredPosition = new Vector2(positions[i], 0);
tempButton.GetComponent<Button>().onClick.AddListener(() => OnGivenRate(i));
}
}
public void RemovePreview()
{
DestroyImmediate(currentCanvas);
}
private void OnGivenRate(int stars)
{
Debug.Log("pressed star: " + stars);
}
public class RateMeEditor
{
[CustomEditor(typeof(RateMeManager))]
public class button : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
RateMeManager myScript = (RateMeManager)target;
if (GUILayout.Button("Preview Layout"))
{
myScript.GenerateStars();
}
if (GUILayout.Button("Delete Preview"))
{
myScript.RemovePreview();
}
}
}
}
}
Your error is here:
tempButton.GetComponent<Button>().onClick.AddListener(() => OnGivenRate(i));
You have to store i in a variable before passing it to OnGivenRate or use a closure.
Because at the end of the loop i is equal to 5. It's why when you click on your button i displays 5.
So do:
var rate = i;
tempButton.GetComponent<Button>().onClick.AddListener(() => OnGivenRate(rate));
or
Action<int> OnGivenRateClosure(int rate)
{
return () => OnGivenRate(rate);
}
with
tempButton.GetComponent<Button>().onClick.AddListener(OnGivenRateClosure(i));
You reference to i on your for-loop:
tempButton.GetComponent().onClick.AddListener(() => OnGivenRate(i));
And you use an anonymous method to call OnGivenRate(i). This piece of code will live outside the scope of your for-loop, yet it will have access to i variable. The variable, when it is referenced by the () => OnGivenRate(i) anonymous method, will most likely have i=5 (when the for-loop is exited).
You're accessing a closure, so the called function inside the for loop gets the i value only after a while, when the loop is in another cycle and i has been already modified.
Another thing. When you write:
for(int i = 0; i < 5; i++)
the code executes the statements inside the for loop with i values of 0, 1, 2, 3, 4, but the last value of i is 5. In fact, when the cycle with 4 ended, i is incremented, the check "i < 5" is made, it results false, so the loop exits.
Your code is redundant. You already have buttons as array before the for loop then you converted it a gameObject(tempButton) then into a button again.... This looks like a reference problem. Just replace your for loop with the code below.
To display 0 to 4:
for (int i = 0; i < buttons.Length; i++)
{
buttons[i].image.sprite = emptyStar;
myRectTransform = buttons[i].GetComponent<RectTransform>();
myRectTransform.sizeDelta = new Vector2(spriteWidth, spriteHeight);
myRectTransform.anchoredPosition = new Vector2(positions[i], 0);
buttons[i].onClick.AddListener(() => OnGivenRate(i));
}
To display 1 to 5:
for (int i = 0; i < buttons.Length; i++)
{
buttons[i].image.sprite = emptyStar;
myRectTransform = buttons[i].GetComponent<RectTransform>();
myRectTransform.sizeDelta = new Vector2(spriteWidth, spriteHeight);
myRectTransform.anchoredPosition = new Vector2(positions[i], 0);
buttons[i].onClick.AddListener(() => OnGivenRate(i+1));
}
Notice the difference: buttons[i].onClick.AddListener(() => OnGivenRate(i+1));
This is the class i created MapsLevels:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace TowerDefense
{
public class Level
{
private List<Texture2D> tileTextures = new List<Texture2D>();
private List<int[,]> MapsArrays = new List<int[,]>();
private Queue<Vector2> waypoints = new Queue<Vector2>();
int[,] map = new int[,]
{
{1,1,1,0,0,0,0,0,},
{0,0,1,0,0,0,0,0,},
{0,0,1,1,0,0,1,1,},
{0,0,0,1,0,0,1,0,},
{0,0,1,1,0,0,1,0,},
{0,0,1,0,0,0,1,0,},
{0,0,1,1,1,0,1,0,},
{0,0,0,0,1,1,1,0,},
};
int[,] map1 = new int[,]
{
{0,0,0,1,1,1,1,0,},
{0,0,0,1,0,0,1,0,},
{0,0,0,1,1,0,1,0,},
{1,1,0,0,1,0,1,0,},
{0,1,0,0,1,0,1,0,},
{0,1,1,1,1,0,1,0,},
{0,0,0,1,1,0,1,1,},
{0,0,0,0,0,0,0,0,},
};
int[,] map2 = new int[,]
{
{1,1,0,0,1,0,0,0,},
{0,1,0,0,1,0,1,1,},
{0,1,0,0,1,0,1,0,},
{0,1,1,1,1,1,1,0,},
{0,0,0,0,0,1,0,0,},
{0,1,1,1,1,1,1,1,},
{0,1,0,1,0,0,0,0,},
{0,1,0,1,0,0,0,0,},
};
public Level()
{
waypoints.Enqueue(new Vector2(0, 0) * 64);
waypoints.Enqueue(new Vector2(2, 0) * 64);
waypoints.Enqueue(new Vector2(2, 3) * 64);
waypoints.Enqueue(new Vector2(3, 2) * 64);
waypoints.Enqueue(new Vector2(4, 2) * 64);
waypoints.Enqueue(new Vector2(4, 4) * 64);
waypoints.Enqueue(new Vector2(3, 4) * 64);
waypoints.Enqueue(new Vector2(3, 5) * 64);
waypoints.Enqueue(new Vector2(2, 5) * 64);
waypoints.Enqueue(new Vector2(2, 7) * 64);
waypoints.Enqueue(new Vector2(7, 7) * 64);
MapsArrays.Add(map);
MapsArrays.Add(map1);
MapsArrays.Add(map2);
}
public Queue<Vector2> Waypoints
{
get { return waypoints; }
}
public void AddTexture(Texture2D texture)
{
tileTextures.Add(texture);
}
public int Width
{
get { return map1.GetLength(1); }
}
public int Height
{
get { return map1.GetLength(0); }
}
public void Draw(SpriteBatch batch)
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
int textureIndex = MapsArrays[0][y, x];
if (textureIndex == -1)
continue;
Texture2D texture = tileTextures[textureIndex];
batch.Draw(texture, new Rectangle(
x * 64, y * 64, 64, 64), Color.White);
}
}
}
public int GetIndex(int cellX, int cellY)
{
if (cellX < 0 || cellX > Width - 1 || cellY < 0 || cellY > Height - 1)
return 0;
return map[cellY, cellX];
}
}
}
I have 3 maps but now im using only the first one variable map.
And i have waypoints but they are not fitting to the map so the enemy walk not on the path i created.
The path in my map is marked with numbers 1 and all the rest is 0.
This is the Pathfinder class i added it to this site:
Pathfinder class
This is my complete project maybe it will be more easy to see it in the whole project:
This is the rar file of my project called TowerDefense:
TowerDefense
The problem is with the Pathfinder class on the line number 274:
SearchNode endNode = searchNodes[endPoint.X, endPoint.Y];
I'm getting exception Index was outside the bounds of the array.
What i want to do in the end is to use the Pathfinder class in the right way and also make that the enemy will move over my path the waypoints should be automatic set to the path in my map.
And hard coded like it is now.
EDIT:
I solved the first exception in Game1.cs i changed the line:
List<Vector2> path = pathfinder.FindPath(new Point(0, 0), new Point(9, 9));
To:
List<Vector2> path = pathfinder.FindPath(new Point(0, 0), new Point(7, 7));
I still have two problems now in Pathfinder class in line number 282:
startNode.InOpenList = true;
It throw exception null since startNode is null.
In many items in the List searchNodes also in class Pathfinder some items are null.
The second problem is yet in the MapsLevel.cs class how ot make the waypoint to be automatic fit to the map ( variable map design ) so the enemy iwll move on the path in my map ?