Scriptable Objects - Integrating Coroutine Style Logic Without MonoBehaviours

I’m using a set of scripts called UnitySteer that are derivative of the C++ OpenSteer project. These scripts work very well and provide a lot of versatility for managing NPCs. However, these scripts are not monobehaviours and as such, I can’t figure out how to integrate coroutine style logic. Advice?

Link to scripts: GitHub - ricardojmendez/UnitySteer: Steering, obstacle avoidance and path following behaviors for the Unity Game Engine

There’s an abstract class called Steering that is a MonoBehaviour and all other behaviors derive from it. It should create menu options to add those components to your GameObjects judging by the source code. There’s also tutorials linked in the readme.

1 Like

Thank you! I did not see that the abstract class being referenced was actually a MonoBehaviour.

Ok so this is obvious to more experienced programmers unlike myself, but after speaking to a couple people I learned that I don’t actually need to modify the code within the abstract class to manage coroutine style behaviours. I can directly access the components on the game object simply by referencing them within a separate MonoBehaviour and attaching it to the GameObject. This should allow me to create very intricate “wandering” behaviours for NPC’s with these scripts. :slight_smile:

using UnityEngine;
using System.Collections;
using UnitySteer.Behaviors; //this is the reference to the abstract class


public class HoldPosition: MonoBehaviour
{
    public int frame = 0;
    public GameObject gameObject;

    void Start(){
        StartCoroutine(Waiting());
    }

    IEnumerator Waiting(){
        yield return new WaitForSeconds (5);
        if (frame >= 1){
            gameObject.GetComponent<SteerForWander> ().enabled = false;
        }
        yield return new WaitForSeconds (8);
        frame--;
    }

    void Update(){
        if (frame <= 0) {
            gameObject.GetComponent<SteerForWander> ().enabled = true;
            frame++;
            StartCoroutine (Waiting ());
        }
    }
}

This is just a base level routine using WaitForSeconds. I will be expanding on this code over time to integrate random ranges and other instructions. Maybe this will help another novice like myself if they are stuck in a similar situation.

That could be simplified a fair amount. Remember - Start can be a coroutine in and of itself and I don’t really understand what the frame thing is doing.

[SerializeField]
SteerForWander wander; // assign via inspector

IEnumerator Start()
{
    while (true)
    {
        yield return new WaitForSeconds(5);
        wander.enabled = false;
        yield return new WaitForSeconds(8);
        wander.enabled = true;
    }
}

Wow dude! Thank you for that! The frame integer in my code above was being used as a switch. It was reading and writing values set by the script and acting on those updated values, essentially emulating the behaviour of your true false statements above. I had not learned Start in and of itself can function as a coroutine. This is immensely valuable information. My main question about that block above is about while (true). Nothing is defined initially. (while WHAT is true) How does unity know what to read at the start of the coroutine without a reference? Does it look ahead to find it’s object reference or something else?

while (true) basically means “loop forever”. It’s evaluating the literal boolean value of true. So it’s while true is true.

Ok cool! Thanks for your help with these concepts Kelso!