How to feed event manager Data into State Machine

Greetings fellas.

I’m currently learning State Machine specially from the tutorial Unity has for us. Its gonna be a big question.

I have an custom Event Manager I made for registering click inputs. The manager broadcasts messages based on Raycasting. I also have a state machine to handle different states my characters will have. It is an RTS game. I pretty much made both the State Machine and EventManager. But Im having trouble feeding data into the State Machine.

I want the terrain to receive the click event when clicked on terrain and check if the current state of selected units is Patrol State. If it is Patrol State, the terrain will feed the Transforms of those click to State Pattern which handles the state machine until another event is triggered (right click in this case). The way the state machine is set up, The StatePatternEnemy.cs script calls a custom UpdateState() function available in all State scripts, from its own Update() function derived from monobehavior. But how can I feed the Transform values into Patrol State if the StatePatternEnemy.cs is using Update() to access states?

i thought about making a public Patrol() function in the Patrol State script that the StatePatternEnemy.cs can call on and feed Transforms into. But wouldn’t that conflict with the whole thing if I’m accessing 1 particular function in a particular state?

P.S: I may have used an Array but I prefer generic lists as they are easier to work with and can be more dynamic.

I left the codes below.

using UnityEngine;
using System.Collections;

public class StatePatternEnemy : MonoBehaviour
{
	public float searchingDuration = 4f;
	public float sightRange = 4f;
	public Transform[] wayPoints;
	public Transform eyes;
	public Vector3 offset = new Vector3 (0, 0.5f, 0);

	[HideInInspector] public Transform chaseTarget;
	[HideInInspector] public IEnemyState currentState;
	[HideInInspector] public PatrolState _patrolstate;
	[HideInInspector] public AlertState _alertState;
	[HideInInspector] public NavMeshAgent _navmeshagent;

	void Awake() {
		_patrolstate = new PatrolState (this);
		_alertState = new AlertState (this);
		_navmeshagent = GetComponent<NavMeshAgent> ();
	}

	void Start() {
		currentState = _patrolstate;
	}

	void Update() {
		currentState.UpdateState ();
	}

	private void OnTriggerEnter (Collider other) {
		currentState.OnTriggerEnter (other);
	}
}

and the PatrolState:

using UnityEngine;
using System.Collections;

public class PatrolState : IEnemyState
{
	private readonly StatePatternEnemy enemy;

	public PatrolState(StatePatternEnemy statePatternEnemy) {
		enemy = statePatternEnemy;
	}

	public void UpdateState () {
		Patrol();
	}
	public void OnTriggerEnter (Collider other) {
		if (other.gameObject.CompareTag ("Player"))
			ToAlertState ();
	}
	public void ToPatrolState () {
		return;
	}
	public void ToAlertState () {
		enemy.currentState = enemy._patrolstate;
	}
	public void ToCombatState () {
		enemy.currentState = enemy._combatstate;
	}
	
	public void Patrol() {
		
	}
}

1 Answer

1

To return a transform you need to either call the raycast function and ask for a return or, probably more likely in this case, call the WayPoint (I’m assuming you want a WayPoint for patrolling) function and pass it the transfrom you just clicked.

So your raycast provides a transform to go to, not sure what your variable name is for the raycast out but hit is fairly common.

So where you’re recording the WayPoints have a public function that accepts a transform.

public WayPointRecorder(Transform t)

Have that transform added to the array for WayPoints. You’ll also need a way of telling it to Start/Stop recording WayPoints so you don;t just end up with a massive list! Just have bool for RecordWP.

You’re raycast can check if RecordWP is true and pass back the hit.transform to WayPointRecoprder by referencing the script. Let’s say it’s in PatrolState, at the top of your script with the RayCast have…

public PatrolState PSScript;

Then when you’re raycast hits check the RecordWP bool in PatrolState then call the WayPointRecorder passing back the transform hit from your raycast.

if(PSScript.RecordWP)
     PSScript.WayPointRecorder(hit.transform);

Hope that makes sense!

Thats the thing. Im not getting how the flow will work. The terrain has RaycastHit hitinfo and Im guessing hitinfo.point is the transform Im looking for. I push hitinfo.point into StatePatternEnemy. Do I make the function to store all the transform in the StatePatternEnemy or just use that to push the Transform into Patrol State script where I create the function to store the transforms?

And the raycast is not registering in any of the given scripts. Its being registered in a terrain script which is part of the event manager. It reads the event incase of a click and registers the raycastHit variable