Jump to content

Actor scripting questions


inawe

Recommended Posts

 

Incorrect. OnLoad is called on all ObjectReferences i.e. basically anything that can have a 3D model in-game.

 

You are right, I went back to look, I was thinking of OnPlayerLoadGame.

 

 

You can access OnPlayerLoadGame from any script using the RegisterForRemoteEvent method :wink:

Edited by steve40
Link to comment
Share on other sites

 

 

 

You can access OnPlayerLoadGame from any script using the RegisterForRemoteEvent method :wink:

 

Where were you back when I needed you lol. You knew that off the back of your hand, and it took me like two weeks to figure out on my own that I could do that when I needed it for a mod. xD

Edited by MadGodSheogorath
Link to comment
Share on other sites

I tried OnInit, but the randomizing version of the script only randomized things once and then applied that to every following spawn. I'm guessing that the script only gets initialized once, not once per instance.

 

OnLoad works. The hairstyles fade in and out a couple of times and sometime stretch out in a long line in front of the character, but they settle down in a few seconds. The hairlines seem to get added correctly too, but I need to test that further. Randomizing the eyes also works.

 

Here is the current version of the script:

ScriptName ChangeMyHeadParts extends Actor Hidden

FormList Property EyeList Auto Const Mandatory
FormList Property HairList Auto Const Mandatory

int RandomEyeIndex
int RandomHairIndex

Event OnLoad()
	RandomEyeIndex = Utility.RandomInt(0, 21)
	Self.ChangeHeadPart((EyeList.GetAt(RandomEyeIndex)) as HeadPart)
	RandomHairIndex = Utility.RandomInt(0, 33)
	Self.ChangeHeadPart((HairList.GetAt(RandomHairIndex)) as HeadPart)
endEvent

Instead of using a variable to keep the script from running more than once on an actor, I'm planning to add a keyword to the actor at the end of the script and check for the presence of the keyword at the beginning.

 

Thanks again everyone for your answers. This post from a while back helped a lot too - https://forums.nexusmods.com/index.php?/topic/4468365-npc-grows-his-own-beard-but-wont-trimshave.

Link to comment
Share on other sites

Each Instance gets their own .. let`s say virtual copy of the script. OnInit works just fine. Maybe there are some reasons why it did not work for you, or maybe I did not understood what exactly you want. OnInit runs when the actor is created and when the actor is reset. Was curious and tried your script on my test npc whom I keep in my mod for experiments . Only hairs, had no time to look for eyes. :D. Worked just fine with OnInit. I can`t say why it did not work for you. Maybe in some cases it does not work, OnInit is used for workshop NPC.

Link to comment
Share on other sites

I tried OnInit, but the randomizing version of the script only randomized things once and then applied that to every following spawn. I'm guessing that the script only gets initialized once, not once per instance.

OnInit should work, as long as the functions you call don't require that the 3D is loaded, and you only want it to run once per actor.

 

Instead of using a variable to keep the script from running more than once on an actor, I'm planning to add a keyword to the actor at the end of the script and check for the presence of the keyword at the beginning.

That would be inefficient and could still allow the script to fire multiple times. Why not use STATES?

 

ScriptName ChangeMyHeadParts extends Actor Hidden

FormList Property EyeList Auto Const Mandatory
FormList Property HairList Auto Const Mandatory

int RandomEyeIndex
int RandomHairIndex

Event OnLoad()
	GoToState("COMPLETED")
	RandomEyeIndex = Utility.RandomInt(0, 21)
	Self.ChangeHeadPart((EyeList.GetAt(RandomEyeIndex)) as HeadPart)
	RandomHairIndex = Utility.RandomInt(0, 33)
	Self.ChangeHeadPart((HairList.GetAt(RandomHairIndex)) as HeadPart)
endEvent

STATE COMPLETED
Event OnLoad()
	; do nothing
EndEvent
ENDSTATE
Link to comment
Share on other sites

OnInit should work, as long as the functions you call don't require that the 3D is loaded, and you only want it to run once per actor.

 

When I thought about it some more, I think my testing on this may have been invalid. I was spawning multiple instances of an NPC directly rather than through a leveled list. I'll try through a leveled list and see if that changes the behavior.

 

OnInit runs when a script first initializes. Does that happen each time the game is loaded, or does it only happen once ever, with the fact that it has been initialized being stored in the save game?

 

I'm also not sure how instancing works for scripts. If I have an NPC with a script attached and then spawn the NPC multiple times, is it a new instance of the script each time? Does the behavior of this change if part of the NPC's data comes through a leveled list?

 

That would be inefficient and could still allow the script to fire multiple times. Why not use STATES?

 

Because I'm a scripting newbie and don't know how states work? ;-) I'll have to read through the information on them on the CK wiki. By inefficient, do you mean that it takes the game longer add a keyword and check for it periodically than to set a state and check it periodically?

 

I see that you put the GoToState at the beginning of the Event script. Wouldn't that cause it to jump there without processing the rest of the script?

 

Once a script is in a state, does it stay there until something tells it to leave? Is the state stored in the save game so that when the game is reloaded, the script is still in that state?

 

Thanks.

Edited by inawe
Link to comment
Share on other sites

Each Instance gets their own .. let`s say virtual copy of the script. OnInit works just fine. Maybe there are some reasons why it did not work for you, or maybe I did not understood what exactly you want. OnInit runs when the actor is created and when the actor is reset. Was curious and tried your script on my test npc whom I keep in my mod for experiments . Only hairs, had no time to look for eyes. :D. Worked just fine with OnInit. I can`t say why it did not work for you. Maybe in some cases it does not work, OnInit is used for workshop NPC.

Whoops, didn't see that you had already answered a couple of the things that I asked steve40.

 

When is an actor reset? Is that the same as respawning?

 

For the behavior I was seeing, I was spawning multiple instances of an NPC at the same time to test out the randomization (player.placeatme <NPC's form ID> 15). The first instance got a random hair and eyes. The following instances all got those same hair and eyes. With OnLoad, the hair and eyes was random for each instance. I'm going to retest this by spawning the NPC through a leveled list to see if the behavior changes. It would be nice for the hair and eyes to be set before 3D loads so that they don't do the weird transitioning for a few seconds.

Link to comment
Share on other sites

steve40,

 

You can ignore my question about putting the GoToState at the beginning of the Event. The CK wiki answered that. I understand now that GoToState is not the same as the old programming GoTo that I am thinking of. Setting a state simply filters which part of a script sees/pays attention to further events that the script receives. My only remaining question on states is whether or not they are stored in the save game so that they are maintained across reloads.

Link to comment
Share on other sites

 

Each Instance gets their own .. let`s say virtual copy of the script. OnInit works just fine. Maybe there are some reasons why it did not work for you, or maybe I did not understood what exactly you want. OnInit runs when the actor is created and when the actor is reset. Was curious and tried your script on my test npc whom I keep in my mod for experiments . Only hairs, had no time to look for eyes. :D. Worked just fine with OnInit. I can`t say why it did not work for you. Maybe in some cases it does not work, OnInit is used for workshop NPC.

Whoops, didn't see that you had already answered a couple of the things that I asked steve40.

 

When is an actor reset? Is that the same as respawning?

 

For the behavior I was seeing, I was spawning multiple insta nces of an NPC at the same time to test out the randomization (player.placeatme <NPC's form ID> 15). The first instance got a random hair and eyes. The following instances all got those same hair and eyes. With OnLoad, the hair and eyes was random for each instance. I'm going to retest this by spawning the NPC through a leveled list to see if the behavior changes. It would be nice for the hair and eyes to be set before 3D loads so that they don't do the weird transitioning for a few seconds.

They reset when the the cell resets. Spawning multiple instances at once can be the reason. Can`t tell you why, maybe RandomInt works this way when called in the exactly same moment(chooses the same RandomInt). If you spawned they one by one, they`d get different hair.

Adding a short pause fixes it somehow. Don`t ask me why , I don`t know, it just works. :smile:

Event OnInit()
    Utility.Wait(Utility.RandomFloat(0.0,2.0))
    Int RandomHairIndex = Utility.RandomInt(0, 21)
    Self.ChangeHeadPart((HairList.GetAt(RandomHairIndex)) as HeadPart)
endEvent

You know, I`ve found problem with changing headparts. It seems that the game does not save this changes. Each time after quiting and loading a save , npc get their default headparts( from the CK). They also get the same headparts after leaving and returning to the area. I don`t know if this happenes with all npc, or only non persistent. And to avoid this you probably would need to use OnInit,OnLoad and OnPlayerLoadGame . Creating a randomInt on Inint and then using this variable for other events.

Edited by kitcat81
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...