Template of a ZScript animated monster made with Decoupled IQM animations
Posted: Sun Oct 20, 2024 6:55 pm
Based on this guide, I created a monster with proper movement logic and animation:
viewtopic.php?t=79003
The first part is the logic of the move.
In Melee 34, it's the last frame of the attack animation.
In Pain 42, it's the last frame of the dying animation.
Regarding porting from Blender:
I used this plugin: https://github.com/lsalzman/iqm
It only worked for me with Blender version 2.93.18.
Details about the porting are in the image:

p.s. Thanks Jay from the official discord vkdoom and of course Jekyll Grim Payne
viewtopic.php?t=79003
Code: Select all
class testmonster: actor
{
default
{
Health 500;
Radius 20;
Height 64;
Mass 600;
Speed 2;
PainChance 200;
Monster;
+FLOORCLIP
+DECOUPLEDANIMATIONS
}
double targetAngle;
const rotSpeedMin = 5.1;
const rotMult = 0.3;
override void PostBeginPlay()
{
targetAngle = angle;
}
override void Tick()
{
Super.Tick();
if(angle != targetAngle)
{
double diff = DeltaAngle(angle, targetAngle);
//cap rotation speed to min speed
double rot = max(abs(diff) * rotMult , rotSpeedMin);
if(rot > abs(diff))
{ // don't overshoot the angle when rotating
angle = targetAngle;
}
else
{
if(diff < 0)
{
A_SetAngle(angle - rot, SPF_INTERPOLATE);
}
else
{
A_SetAngle(angle + rot, SPF_INTERPOLATE);
}
}
}
}
States
{
Spawn:
M000 A 0 {
double oldAngle = invoker.angle;
A_Look();
invoker.targetAngle = invoker.angle;
invoker.angle = oldAngle;
}
M000 A 1 NoDelay SetAnimation('idle', flags:SAF_LOOP|SAF_NOOVERRIDE);
loop;
See:
M000 A 0 {
double oldAngle = invoker.angle;
A_Chase();
invoker.targetAngle = invoker.angle;
invoker.angle = oldAngle;
}
M000 A 1 NoDelay SetAnimation('walking', flags:SAF_LOOP|SAF_NOOVERRIDE);
loop;
Melee:
M000 A 1 {
double oldAngle = invoker.angle;
A_CustomMeleeAttack (1);
invoker.targetAngle = invoker.angle;
invoker.angle = oldAngle;
}
M000 A 34 NoDelay SetAnimation('attack', flags:SAF_LOOP|SAF_NOOVERRIDE);
goto See;
Pain:
M000 A 1 {
double oldAngle = invoker.angle;
A_Pain();
invoker.targetAngle = invoker.angle;
invoker.angle = oldAngle;
}
M000 A 42 NoDelay SetAnimation('pain', flags:SAF_LOOP|SAF_NOOVERRIDE);
goto See;
Death:
M000 A -1 SetAnimation('dying');
stop;
}
}
In Melee 34, it's the last frame of the attack animation.
In Pain 42, it's the last frame of the dying animation.
Regarding porting from Blender:
I used this plugin: https://github.com/lsalzman/iqm
It only worked for me with Blender version 2.93.18.
Details about the porting are in the image:

p.s. Thanks Jay from the official discord vkdoom and of course Jekyll Grim Payne