• Advertisement

Recommended Posts

Posted (edited)

Hi!

I'm trying to create a daily routine for an NPC in Unity.

It should start at 9 am to move to a certain point, stay there for a while, move back and - ideally - despawn.

 

I'm using the "simple waypoint system"

I tried several approaches but ran into problems every time:

 

1 - NPCs stop moving when deactivated and reactivated.

2 - Same goes for instantiating and destroying.

3 - The Waypoint systems "stop" function stops everything. The NPC is incapable of moving afterwards. The pause function would require to put in a float value, which would be nastiest kind of hardcoding, since it doesn't correlate to the time of day. I don't like to discard it, it's actually a good system.

And lastly: For some weird reason the OnTriggerEnter function doesn't recognize my tags (except Player).

This should be easy, right? I spent an entire day failing at every attempt. I'd be glad if someone could helß (:

Edited by Felis Nigripes

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)
11 hours ago, Felis Nigripes said:

This should be easy, right?

Programmers first rule: Nothing is ever easy.

What have you actually tried? Do you have some data that describes what your NPCs should be doing at what times?

  • Entity ID: 1 should move from <location> to <location> leaving at 13:30 and on arrive:<roam\shop\stand\gather\fight>

This way you could determine what the day\time currently is and see if they should be moving to a point, or already be at a point in some state when the player gets near(Which would respawn the NPC). If they are between points you just get the percentage of time they are within (Just a line that goes as the crow flies would work fine with the entities speed) then you can lerp along it based on that, maybe add data when they should be arriving as well.

Regarding your OnTriggerEnter problem, what do you mean tags? Can you ensure everything is setup correctly as shown in the Unity documentation?

https://docs.unity3d.com/Manual/CollidersOverview.html (Scroll down to the bottom)

https://docs.unity3d.com/Manual/LayerBasedCollision.html

 

Edited by nhold

Share this post


Link to post
Share on other sites
Posted (edited)
Just now, nhold said:

Regarding your OnTriggerEnter problem, what do you mean tags? Can you ensure everything is setup correctly as shown in the Unity documentation?

https://docs.unity3d.com/Manual/CollidersOverview.html (Scroll down to the bottom)

https://docs.unity3d.com/Manual/LayerBasedCollision.html

I checked the table and it turns out the NPC needed a rigidbody. Works fine now. Thanks for that (:

After another day of testing I figured it out, sort of. I tried it with triggers for a while, but the problem seemed to be in the way the waypoint system works. It stops every movement when the NPC gets deactivated/destroyed/stopped.

There's a function buried deep in one of the scripts called StartMovement. It gets the NPC going again.

 

Follow-up question: I Is there a discernable reason why I can't assign public gameobjects to a prefab? This seems like an unnecassary restriction to me. Is there a workaround for this? Generally, I'm suspicious towards leaving objects in the scene all the time and I'd prefer instantiate/destroy.

Edited by Felis Nigripes

Share this post


Link to post
Share on other sites
15 hours ago, Felis Nigripes said:

Follow-up question: I Is there a discernable reason why I can't assign public gameobjects to a prefab?

I don't understand your question, do you have code: 

public GameObject someObject;

Because you should be able to put a prefab on that if it's in MonoBehaviour class (Or Serialized class that is in a MonoBehaviour).

15 hours ago, Felis Nigripes said:

Generally, I'm suspicious towards leaving objects in the scene all the time and I'd prefer instantiate/destroy.

Is this related to your above question? It's usually best case to pool your GameObjects. Instantiating and destroying is pretty costly at the moment.

Share this post


Link to post
Share on other sites
Posted (edited)
Just now, nhold said:

I don't understand your question, do you have code: 


public GameObject someObject;

Because you should be able to put a prefab on that if it's in MonoBehaviour class (Or Serialized class that is in a MonoBehaviour).

Is this related to your above question? It's usually best case to pool your GameObjects. Instantiating and destroying is pretty costly at the moment.

Sorry, I should put it more precisely.

It's the other way round. I have a prefab in the inspector. The prefab has a script attached to it. But I can't assign gameobjects from the hierarchy to the script in the inspector. I wanted to spawn the prefab with the variables assigned.

I've heard several times that instantiating and destroying is pretty bad performance-wise. It's just very practical sometimes, but I will take your advice and largely stick to activate/deactivate.

Edited by Felis Nigripes

Share this post


Link to post
Share on other sites
6 hours ago, Felis Nigripes said:

. I have a prefab in the inspector. The prefab has a script attached to it. But I can't assign gameobjects from the hierarchy to the script in the inspector. I wanted to spawn the prefab with the variables assigned.

Now you encounter the common problem people have with engines. The engine already has a build in system for what you want, but because you are ignoring it you get problems.

First, the editor doesn't exist when the game is running on it's own, so it can't find prefabs in the editor. Unity has a resource folder for this: https://docs.unity3d.com/ScriptReference/Resources.Load.html

Make a folder name it "Resources". The code to load looks like this:

AI = Resources.Load("AIName");

Second Unity prefers if you use it's level streaming and layering for dynamically loading and unloading. But this is not a good choice for what you are doing. You would need a scene for every AI and that is just insane.

 

6 hours ago, Felis Nigripes said:

I've heard several times that instantiating and destroying is pretty bad performance-wise. It's just very practical sometimes, but I will take your advice and largely stick to activate/deactivate.

Loading at realtime is costly. Once you start using the resources folder you will quickly see why games avoid this. Instead you should make "zones" these zones consist of a Unity scene that can be loaded and unloaded. When a AI isn't needed you set it to inactive, this will reduce it's cost but keep it in memory.

Once the player is very far from that zone you unload the scene. Freeing all the resources used.

 

Unity isn't the best engine for things like this. If setting the AI to Inactive doesn't work anymore you should consider moving to a openworld engine like Unreal. Unreal has a lot less problems when loading resources at runtime.

Share this post


Link to post
Share on other sites
Quote

Unity isn't the best engine for things like this. If setting the AI to Inactive doesn't work anymore you should consider moving to a openworld engine like Unreal. Unreal has a lot less problems when loading resources at runtime.

I've considered it. Transitioning when the work is still in progress is, I think, a bad idea, but when I finished this I will definitely take a look at unreal.

 

Thanks for the feedback. I've made it work as good as I can. The NPCs appear, do their thing and disappear as expected now. There aren't enough to affect the performance just yet. I shall see how that plays out.

Share this post


Link to post
Share on other sites
On 4/13/2018 at 9:35 PM, Felis Nigripes said:

It's the other way round. I have a prefab in the inspector. The prefab has a script attached to it. But I can't assign gameobjects from the hierarchy to the script in the inspector. I wanted to spawn the prefab with the variables assigned.

No, you can't do that as the GameObjects in scene (Hierarchy) doesn't exist in the same scope as the prefab, what would it reference if you unloaded the scene?

On 4/14/2018 at 4:29 AM, Scouting Ninja said:

Unity has a resource folder for this:

There is an accepted Unity pattern of having your own run time prefab library that access prefabs by some ID\Name.

Edited by nhold

Share this post


Link to post
Share on other sites
1 hour ago, nhold said:

There is an accepted Unity pattern of having your own run time prefab library that access prefabs by some ID\Name.

Reminds me of how Unity users used to hold shared values before Unity added the Scriptable Objects.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement