Jump to content

Photo

Custom Animation for Standalone follower

custom follower custom animation custom race

  • Please log in to reply
4 replies to this topic

#1
vvalentine73

vvalentine73

    Regular

  • Members
  • PipPip
  • 55 posts

Hey everyone!

 

I've just started modding, I'm at the noobest level so help me out here with some knowledge.

 

So I've created myself a follower but I want it to have custom, unique animations, much like the player has it for itself via PCEA2. I have done the following steps to try and make it work:

 

- Create a custom race

- Edit the defaultmale.hkt file (via PCEA) to set destination to animation folder which has my selected animations
â- Enable the custom race to use that hkt file via CK

 

Now this works partially, I've set Beasty Greatsword animation for 2H power attacks, works fine. Sneaks from Pretty Combat, works fine. Some work, some don't. What am I doing wrong? The Race window in CK has "Behavior Graph", which file should I upload there? Very confusing, please help me out guys!



#2
PeterMartyr

PeterMartyr

    Faithful poster

  • Premium Member
  • 1,085 posts

Very Possible I done it. (Unreleased)

 

Here my script but please be aware it's 25% work, you still have to make independent FEAM

 

Follower Exclusive Animation Mod,

 

Mine has 3 or 4 walks & Idles with 2 sneaks walk & Mt Idles, + Combat, mainly Frostfall Archery & 0ne Handed stuff.

 

It better to apply alternate animation to the Actor, not the Race. Just Sayin

; Written by PeterMartyr for PoupaAA.esp

Scriptname PoupAAnimationScript extends Quest  Conditional

	{Poupa Exclusive Alternate Animation Code}

	;	Requires FNIS 6 or Greater
	;	Is SE compatible [YES]

;=========Custom Follower Alternate Animation_Mk3=============

;/*******************************************

*	FNISS_AA_Base = new Elements[14]
*	FNISS_AA_Base[0] = _sneakmt
*	FNISS_AA_Base[1] = _mt
*	FNISS_AA_Base[2] = _mtidle
*	FNISS_AA_Base[3] = _mtx
*	FNISS_AA_Base[4] = _sprint
*	FNISS_AA_Base[5] = _1hmidle
*	FNISS_AA_Base[6] = _sneakidle
*	FNISS_AA_Base[7] = _jump
*	FNISS_AA_Base[8] = _staffidle
*	FNISS_AA_Base[9] = _bowatk
*	FNISS_AA_Base[10] = _bowidle
*	FNISS_AA_Base[11] = _boweqp
*	FNISS_AA_Base[12] = _bowmt
*	FNISS_AA_Base[13] = _dw

********************************************/; 

Int Property nWalkingStlye = 0 Auto  Conditional Hidden
;	Four FNIS AA Prefixes Sets 0, 1, 2, 3. 
Bool Property bRandom = false Auto Conditional Hidden
String Property sAAprefix = "Pou" AutoReadOnly Hidden
String Property sModName = "PoupaAA" AutoReadOnly Hidden
String[] Property sAnimGroup Auto ;String CK FNIS values matching Integer nAnimBase index values!
Actor Property PoupaACT Auto

Bool bStartUpStatus = false
Int nAAModID
Int nInstalled_CRC
Int[] nAnimBase

Event OnInit()

	utility.Wait(15) ;make sure poupa installed first
	debug.Notification("[PoupAA] Checking Minimum Requirements")
	nAnimBase = new Int[14]
	If(self.CheckRequirements())
		self.SetUp()
	EndIf
EndEvent

Bool Function CheckRequirements()

	Bool bSkyrim = (StringUtil.SubString(Debug.GetVersionNumber(), 0, 3) as Float) >= 1.9 ; Remove this code for SE. SKSE!!!
	Bool bFNIS = (Game.GetModByName("FNIS.esp") < 255)
	Bool bVersionCompare = (FNIS.VersionCompare(6, 0, 0) >= 0)
	Bool bIsGenerated = FNIS.IsGenerated()	
	
	If(!bSkyrim || !bFNIS || !bVersionCompare || !bIsGenerated)
		string Msg = "[PoupAA] You failed requirement check(s): \n"
		If(!bSkyrim)
			Msg += "\n*Skyrim is out dated, upgrade if legal?"  ;for fnis(pity) sake.
		EndIf
		If(!bFNIS)
			Msg += "\n*FNIS.esp is not currently active"   ; ...
		EndIf
		If(!bVersionCompare)
			string sVersion = FNIS.VersionToString()
			Msg += "\n*FNIS Version: " + sVersion + " is too old for Alternate Animation"   ;VERY IMPORTANT
		EndIf
		If(!bIsGenerated)
			Msg += "\n*Your last FNIS generation failed" 
		EndIf
		Msg += "\n\n- Please close the game without saving & fix." ; Be Safe Always ...]
		Debug.Messagebox(Msg)
		return false
	else
		return true
	EndIf
EndFunction

Function PlayerLoad()
	
	If(bStartUpStatus)
		Int nCRC_New = FNIS_aa.GetInstallationCRC()	 
		If(nCRC_New != nInstalled_CRC)
			nInstalled_CRC = nCRC_New
			debug.Notification("[PoupAA] New FNIS installation detected. Reinstalling.")
			self.SetUp()
		EndIf
	EndIf
EndFunction

Int Function GetAAgroupID(Int nIndex)

	Int[] nAAgroup = new Int[14]
	nAAgroup[0] = FNIS_aa._sneakmt()
	nAAgroup[1] = FNIS_aa._mt()
	nAAgroup[2] = FNIS_aa._mtidle()
	nAAgroup[3] = FNIS_aa._mtx()
	nAAgroup[4] = FNIS_aa._sprint()
	nAAgroup[5] = FNIS_aa._1hmidle()
	nAAgroup[6] = FNIS_aa._sneakidle()
	nAAgroup[7] = FNIS_aa._jump()
	nAAgroup[8] = FNIS_aa._staffidle()
	nAAgroup[9] = FNIS_aa._bowatk()
	nAAgroup[10] = FNIS_aa._bowidle()
	nAAgroup[11] = FNIS_aa._boweqp()
	nAAgroup[12] = FNIS_aa._bowmt()
	nAAgroup[13] = FNIS_aa._dw()

	return nAAgroup[nIndex]
EndFunction

Int Function GetGroupBaseValueID(int nAAgroup)

	return FNIS_aa.GetGroupBaseValue(nAAModID, nAAgroup, sModName)
EndFunction

Function SetUp()  ;Register & Store my AA values

	If(!bStartUpStatus)
		bStartUpStatus = true
		debug.Notification("[PoupAA]: Passed...  Installing.")
	else
		debug.Notification("[PoupAA]: Reacquiring FNIS_AA Base Values")
	EndIf
	nInstalled_CRC = FNIS_aa.GetInstallationCRC()	 
	nAAModID = FNIS_aa.GetAAModID(sAAprefix, sModName)
	Int nIndex = 14
	While(nIndex > 0)
		nIndex -= 1
		nAnimBase[nIndex] = GetGroupBaseValueID(GetAAgroupID(nIndex))
	EndWhile
	If((PoupaACT as ObjectReference).Is3DLoaded())
		self.RegisterForSingleUpdate(0.1)
	EndIf
	debug.Notification("[PoupAA]: Setup complete")
EndFunction

Bool Function ApplyAAGroupValue(string animGroup, int base , int number = 0)

	return FNIS_aa.SetAnimGroup(PoupaACT, animGroup, base, number, sModName) 
EndFunction

Int Function GetIntValue_Ex()

	If(nWalkingStlye  < 3)
		return 0
	else
		return nWalkingStlye
	EndIf
EndFunction

Event OnUpdate()

	If(bStartUpStatus)
		If(bRandom)
			nWalkingStlye = utility.RandomInt(0, 3)
			RegisterForSingleUpdateGameTime(12)
		EndIf
		Int nIndex = 14
		Bool bOkay = true ; since default is false 
		While(nIndex > 0 && bOkay)
			nIndex -= 1
			If(nIndex > 4)
				bOkay = ApplyAAGroupValue(sAnimGroup[nIndex], nAnimBase[nIndex])	
			ElseIf(nIndex > 0)
				bOkay = ApplyAAGroupValue(sAnimGroup[nIndex], nAnimBase[nIndex], nWalkingStlye)
			else
				bOkay = ApplyAAGroupValue(sAnimGroup[nIndex], nAnimBase[nIndex], GetIntValue_Ex())
			EndIf
		EndWhile
		If(!bOkay)
			String Msg = "[PoupAA] ERROR at applying Alternate Animation. \n\nFailed at Style: " + nWalkingStlye + " at the Index of " + nIndex + ", with " + sAnimGroup[nIndex] + " Animation Group Base."
			debug.TraceAndBox(Msg)
			; [Notation] I never seen this message. Remove or change to Trace only for mod release.
		EndIf
	EndIf
EndEvent

Event OnUpdateGameTime()

	self.RegisterForSingleUpdate(0.1)
EndEvent

Function WalkingStlye(Int nStlye )

	nWalkingStlye = nStlye
	Self.RegisterForSingleUpdate(2.0)
EndFunction

Function RandomWalk(Bool bChoice)

	bRandom = bChoice
	Self.RegisterForSingleUpdate(2.0)
EndFunction

The above code works 100% via Dialogue options. Take look & compare it to yours.

 

Obviously the Follower doesn't use the Game Skeleton, but has their own. 

 

I hope my use of arrays doesn't confuse you. 

 

There is also Player Alias for Player Load Game  Maintenance, and Follower Alias which OnLoad, (cause when a NPC OffLoad, they lose their Alternate Animation),  which reapply it to the actor.

 

When I made it I had no idea, but I think my advantage was I could code, so it worked 1st pop has intended.

 

My Fnis List

Version V6.2

AnimVar PoupAAVar INT32 5555

AAprefix pou 

'Pou0_<>.HKX

AAset	_mtidle 4

AAset	_mt 4

AAset	_1hmidle 1

AAset	_mtx 4

AAset	_sneakidle 1

AAset	_sneakmt 2

AAset	_sprint 4

AAset	_jump 1

AAset	_staffidle 1

AAset	_dageqp 1

AAset	_bowatk 1

AAset	_bowidle 1

AAset	_boweqp 1

AAset	_bowmt 1

AAset	_dw 1

It really not hard. Just make sure to read & re-read all the Documentation by Fore, it's all explain there, he is very helpful. So there no need for me to repeat it.

 

Remember, you haven't failed, it just take baby steps keep trying.

 

And it trust me it work in SSE. I tested it on the day Fore released FNIS 7 & told him so.

 

Oh take look at Fore's Example of the Katana Script, it's in FNIS 6 User Package

 

WTF I'll post it for ya, it's a public example anyway for Modders to help them, I sure Fore won't mind.(I hope) It doesn't use Arrays.

ScriptName FNISACweaponScript extends ObjectReference

;	This is an example script/mod which demonstrates how FNIS Alternate Animations can be used for a specific weapon only
;	It was made for a katana to be used with 
;	Oriental Swordsmanship animation of East Asia by cyh0405 - http://www.nexusmods.com/skyrim/mods/70108
;	Whenever the katana is equipped, the Swordsmanship animations are loaded for the player, and unloaded on unequip.
;	The script requires an animation sub folder with the animations, and a file list FNIS_<mod>_List.txt with the following lines:
;	AAprefix fac
;	AAset _2hmmt 1
;	AAset _2hmatk 1
;	AAset _2hmatkpow 1


actor player
int FNISaa_crc
int FNISaa_ModID
int FNISBase_2hmmt
int FNISBase_2hmatk
int FNISBase_2hmatkpow
int FNISValueOld_2hmmt
int FNISValueOld_2hmatk
int FNISValueOld_2hmatkpow

Event OnInit()
	player = Game.GetPlayer()
EndEvent

Event OnEquipped(Actor akActor)
	if ( akActor == player )
		;Menumode and 1st person: wait til menumode is left
		if Utility.IsInMenuMode()
			if ( player.GetAnimationVariableInt("FNISaa_crc") == 0 )
				Utility.wait(0.01)
			endif
		endif
		Game.ForceThirdPerson()
		
		;can't do anything if FNIS crc == 0 (FNIS generator has failed)
		int FNISaa_crcNew = FNIS_aa.GetInstallationCRC()
		if ( FNISaa_crcNew == 0 )
			return
		endif
		
		;crc has changed: mod ID and base values need to be re-read
		if ( FNISaa_crcNew != FNISaa_crc )
			FNISaa_crc = FNISaa_crcNew
			FNISaa_ModID = FNIS_aa.GetAAmodID("fac", "FNISAlternateCombat", true)
			FNISBase_2hmmt = FNIS_aa.GetGroupBaseValue( FNISaa_ModID, FNIS_aa._2hmmt(), "FNISAlternateCombat", true)
			FNISBase_2hmatk = FNIS_aa.GetGroupBaseValue( FNISaa_ModID, FNIS_aa._2hmatk(), "FNISAlternateCombat", true)
			FNISBase_2hmatkpow = FNIS_aa.GetGroupBaseValue( FNISaa_ModID, FNIS_aa._2hmatkpow(), "FNISAlternateCombat", true)
		endif
		
		;store the current AnimVar values
		FNISValueOld_2hmmt = player.GetAnimationVariableInt("FNISaa_2hmmt")
		FNISValueOld_2hmatk = player.GetAnimationVariableInt("FNISaa_2hmatk")
		FNISValueOld_2hmatkpow = player.GetAnimationVariableInt("FNISaa_2hmatkpow")
		
		;set katana specific AnimVar values
		bool result = FNIS_aa.SetAnimGroup(player, "_2hmmt", FNISBase_2hmmt, 0, "FNISAlternateCombat", true)
		result = result && FNIS_aa.SetAnimGroup(player, "_2hmatk", FNISBase_2hmatk, 0, "FNISAlternateCombat", true)
		result = result && FNIS_aa.SetAnimGroup(player, "_2hmatkpow", FNISBase_2hmatkpow, 0, "FNISAlternateCombat", true)

		if !result
			Debug.MessageBox("FNIS AA could not be activated for katana")
		endif
		Debug.Notification("Katana Animvars set")
	endif
EndEvent

Event OnUnEquipped(Actor akActor)
	if ( akActor == player )
		; reset only when setting has been successful
		if ( FNISaa_crc != 0 )
			;Menumode and 1st person: wait til menumode is left
			if Utility.IsInMenuMode()
				if ( player.GetAnimationVariableInt("FNISaa_crc") == 0 )
					Utility.wait(0.01)
				endif
			endif
			Game.ForceThirdPerson()
			
			;if crc has changed (different installation) the old values are invalid. Reset to vanilla
			if ( FNIS_aa.GetInstallationCRC() != FNISaa_crc )
				FNISValueOld_2hmmt = 0
				FNISValueOld_2hmatk = 0
				FNISValueOld_2hmatkpow = 0
			endif
			
			;re-set the AnimVars (value before equip, or vanilla)
			player.SetAnimationVariableInt("FNISaa_2hmmt", FNISValueOld_2hmmt)
			player.SetAnimationVariableInt("FNISaa_2hmatk", FNISValueOld_2hmatk)
			player.SetAnimationVariableInt("FNISaa_2hmatkpow", FNISValueOld_2hmatkpow)
			Debug.Notification("Katana Animvars reset")
		endif
	endif
EndEvent

Now you have Two Examples. One applied to Sword, and one to an NPC Actor. Now do your Research correctly by reading FNIS_6.2_AlternateAnimations.txt or newer, found in the User FNIS Package & it will come together so fast your head will spin. Your Problems are from Poor Research, you don't understand the GIST of it correctly. Back to basic, learn how it works first, then ask for help. I am not here to teach you, but help you.

 

Good Luck Noobie. I wish you the best.

 

 

Attached File  FNIS.PNG   55KB   2 downloads

 

Remember an Actor is simply extending the ObjectReference Script.

 

Yes I am still using 6.2 Deal...  the script years old too.

 

Feel free to any body to use "my code & publish," I really don't care.... there not a lot of examples of this stuff anyway, so glad I am showing it, & I hope it help those who need it.

 

Fore Code belongs to Fore. I am just pushing it  along.



#3
vvalentine73

vvalentine73

    Regular

  • Members
  • PipPip
  • 55 posts

This is good stuff! Thanks man i'll definiteyl look into it. I tried the old PCEA way :3



#4
PeterMartyr

PeterMartyr

    Faithful poster

  • Premium Member
  • 1,085 posts

I know. But there better ways now, instead of hacking into that. Use FNIS Alternate Animation capabilities. & once again Good Luck mate.



#5
HanzSteiger

HanzSteiger

    Enthusiast

  • Supporter
  • PipPip
  • 214 posts
Hi, I want to understand easy way about animation group.
I'm not expert in scripting so I wish there's any simpler language
The challenge is I want to create without using FNIS and SKSE.

Recently I'm created new custom Animation for my pistol Mod.
The Animation works, but cannot move...so this maybe the walk/run not set as Animation group.

So I hope anyone can answer for my problems.

Thx.





Also tagged with one or more of these keywords: custom follower, custom animation, custom race

Page loaded in: 1.135 seconds