Hello Guys
im trying actually to create a AI system based on the Knowledge of another AI Script which using NavMesh. In This System i work with States. My main Problem is that i not sure if i can use NavMesh for my Game because its in the Space and there are Planets Asteroids etc. as Objects but no Ground. I remember that i read about that this not working and everything i tried the Objects only moving on one Height and not go Up or Down. So i try to go a other way to create my AI.
Actually my Ai has 3 Scripts about the Interfaces and 1 Action Script. As example i need the Rotation Action of the NPC in many Scripts so my idea was that i write the Rotate Script in own .cs and then access it from my State Scripts. But if i try to Access the Rotate Script he tells me:
Im not sure if i can make this how i want, perhaps someone can tell me something about why its not working or if theres a different way to handle this.
NPC_State_Interface:
Here is my Interface which Update the State and Contains all possible States (actually only Patrol)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace enemy
{
public interface NPC_State_Interface
{
void UpdateState();
void ToPatrolState();
}
}
NPC_State_Machine, this Script is attached to the NPC from here i want to controll every State every Move every Data from the NPC (later also Health and Shield as example) We initialize every State set the Variables, check the actual State and initialize the Start State which is the Patrol State for now.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace enemy
{
public class NPC_State_Machine : MonoBehaviour
{
//Check State
private float checkRate = 0.1f;
private float nextCheck;
//NPC Controlloptions
public float sightRange = 40f;
public float moveSpeed = 50f;
public float RayCastOffset = 5f;
public float speedRotation = 2f;
//Waypoint
public GameObject[] waypoints;
//NPC Options
public MeshRenderer meshRendererFlag;
//NPC States
public NPC_State_Interface currentState;
public NPC_State_Patrol patrolState;
void Awake()
{
SetupUpStateReferences(); //Setup the State References
Debug.Log("Awake References");
}
void Start()
{
SetInitialReferences();
}
void Update()
{
CarryOutUpdateState();
}
void SetupUpStateReferences() //Setup the State References
{
//Here we need a Reference to every State we wanna use
patrolState = new NPC_State_Patrol(this);
Debug.Log("Setup References");
}
void SetInitialReferences()
{
//The First State every Enemy get actually it is the Patrol State
ActivatePatrolState();
Debug.Log("Initial State Reference");
}
void CarryOutUpdateState()
{
if (Time.time > nextCheck)
{
nextCheck = Time.time + checkRate;
currentState.UpdateState();
Debug.Log("Update State");
}
}
void ActivatePatrolState() //To Activate the Patrol State at Beginning
{
currentState = patrolState;
Debug.Log("Activate Patrol State");
}
}
}
NPC_State_Patrol, in this Script i tell what to do in the Patrol State, i comment out the Code of the Rotation because i want that he use the Rotation from another Script NPC_Rotate
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace enemy
{
public class NPC_State_Patrol : NPC_State_Interface
{
private readonly NPC_State_Machine npc;
private int nextWayPoint = 0;
public NPC_Rotate rotate;
public NPC_State_Patrol(NPC_State_Machine npcStateMachine)
{
npc = npcStateMachine;
}
public void UpdateState()
{
Patrol();
Debug.Log("Patrol");
}
public void ToPatrolState() { }
//Explanation about
//Here we can write down explicite what the NPC actually have
//to do in the Patrol State Simple for every NPC he have to Look
//somewhere and have to Check if theres a Enemy to go in other State
//i also want to Setup a new Script for an Action and call it. From here
void Patrol()
{
Debug.Log("Patrol on Waypoint");
npc.meshRendererFlag.material.color = Color.blue;
//here i try to Access the NPC_Rotate Script but he give me the NullReferenceExceptionError
rotate.RotateTo(npc.waypoints[nextWayPoint].transform.position);
MoveForwards();
if (HaveIReachedDestination())
{
nextWayPoint = (nextWayPoint + 1) % npc.waypoints.Length;
}
}
bool HaveIReachedDestination()
{
Vector3 delta = npc.waypoints[nextWayPoint].transform.position - npc.transform.position;
if (delta.magnitude < npc.RayCastOffset)
{
return true;
Debug.Log("Reached Destination");
}
Debug.Log("Actual Distance:" + delta);
return false;
}
//If i access the Rotation in this Script its no problem and he rotate to the target position but this is not what i want xD
/*public void RotateTo(Vector3 targetPosition)
{
Quaternion destRotation;
Vector3 relativePos;
Debug.Log("Rotate");
relativePos = targetPosition - npc.transform.position;
destRotation = Quaternion.LookRotation(relativePos);
npc.transform.rotation = Quaternion.Slerp(npc.transform.rotation, destRotation, npc.speedRotation * Time.deltaTime);
}*/
public void MoveForwards()
{
//Simple Move Forward and comment out the RotateTo function in this method
npc.transform.position += npc.transform.forward * Time.deltaTime * npc.moveSpeed;
//RotateTo(npc.waypoints[nextWayPoint].transform.position);
}
}
}
NPC_Rotate just a simple rotation for the NPC which i want call from different States
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace enemy
{
public class NPC_Rotate : MonoBehaviour
{
public NPC_State_Machine npc;
public void RotateTo(Vector3 targetPosition)
{
Quaternion destRotation;
Vector3 relativePos;
relativePos = targetPosition - npc.transform.position;
destRotation = Quaternion.LookRotation(relativePos);
npc.transform.rotation = Quaternion.Slerp(npc.transform.rotation, destRotation, npc.speedRotation * Time.deltaTime);
Debug.Log("Rotate");
}
}
}
Uh long now, i hope u guys can understand what i want and help me out a little bit with ideas ore solving my problem. Thanks everyone and feel free to ask for more Information if need.