Main Menu

Creation Kit - NPC Teleport in Combat Tutorial

Let's get started right away. Set up your script or open up your favorite Notepad program.

The first thing we need to do is set up some properties (variables) that we need for our script. They are as follows:

Activator Properties: OutVis and InVis - These are the ending and beginning visual effects for the teleportation.

VisualEffect (optional) - In case you'd like to get a little fancier, you can apply visual effects, which are best used under the same functions that spawn the Activators

STATIC OutLocMarker (optional, see the bottom notes) - Used in the case that you would like to predetermine actualization of the ending effect.

Float Properties: X, Y, and ZFloat - In order to track the aftermath of the teleportation sequence, in case it fails.

Boolean: bCasting - In order to ensure that the teleportation function does not overlap a process already in effect

ActorBase: ActorOwner (optional) - In case you'd like to use conditions and properties of your NPC to designate what occurs in the script.

Let's set up our basic functions. These are the spawning of the Activators which are the visual effects. Use VisualEffect via Apply() function here if you'd like.

function BeginTeleport()PlaceAtMe(InVis)endFunction

function EndTeleport()PlaceAtMe(OutVis)endFunction

The function as shown in the source code "TeleportTo" is force sequence based occurrences. If you'd like to teleport the NPC in the case of a scene, special event or such other things, use this instead of "CombatTeleportTo". Because it is basically the same function, we will ignore this derivation of the combat based function.

Let's start to make the body of the script, starting with our fundamental function, CombatTeleportTo. The parameters include an ObjectReference which will be the teleport target in question, and a float which acts as a delay if needed for a smooth procession. We also need store information into our saved "vector" (the collective reference to the three floats we've declared).

This allows us to easily work with radii in a 3 dimensional world. We can acquire both distal and angular information from these two values. We would like to get the distance from a variable point, and find a point r units away from that point. As you can see this is easily accessible when looking at the idea in question from a visual perspective.

The center in our case will be the target ObjectReference, and the point we're interested in is (r,θ). The rX and rY in the functions are the relative offsets based on the coordinate locations of the points in question. If we did not include these, the functions would return values near the origin of the world.

We would also like to ensure that our NPC does not teleport in front of the target. To do this, we need to make sure that the angles of 45 to -45 degrees relative to the initial angle (our target's facing direction) are out of question. That is to say, the NPC will not be able to teleport 45 to -45 degrees in front of our target.

float Function CalculateDesiredAngle(ObjectReference RefAngle)

float T = GetHeadingAngle(RefAngle)

if (T < 45)&&(T > -45) return (T+180)

else return T endIf

endFunction

Now that we have this we can finish our CombatTeleportTo function. We're going to define some private variables.

One thing that may be important to mention is the GetHeadingAngle function. This will return the angle of the target relative to our NPC's location. For instance, suppose A is the target and B is our NPC. GetHeadingAngle would return the value for angle C.

Taking TeleportTarget as a boolean will check if it exists. If it does exist, we execute BeginTeleport(), casting the visual effects, waiting 0.4 seconds with utility.wait(), and finally moving our NPC to the designated location, which is the calculated, processed location of our destination. We also want to use the SetAngle function to turn the NPC toward the target. The only variable really being changed here with respect to this function call is in the 3rd argument. Adding the heading angle to the initial Z angle (Yaw) will turn our NPC towards the target. This concludes the creation of our CombatTeleportTo function. We need something to activate it. This will be the OnHit Event. Every time an NPC is hit, this event is called.

Our conditions are to check the distance by GetDistance(ObjectReference Target). I am using 768 units. Anything more than 768 units will return true. We also want to make sure the target is in the same cell or location as our NPC. We can use a random float, FRand, to specify the tendency of our NPC's teleportation. We must also set bCasting to True temporarily to make sure we do not overlap multiple calls to the teleport function.

An important function that we haven't yet implemented is the boolean function CheckSuccess, which ensures that the NPC made it to the specified location. This is a simple distance check.

The TeleportTo function is not needed for combat, so you can take it out. Actually, you should skim through the code to take out anything you don't want that isn't needed.

The OutLocMarker can be used for placing visuals before the NPC actually teleports. To do this, simply define a private ObjectReference variable, by inserting it into the function PlaceAtMe(). In example: ObjectReference myRef = PlaceAtMe(Object). Now you can access and specify the spatial properties of this object and move it to the designated location prior to teleportation.

The SetLocalAngle can be used if needed to get the local angle instead of the "global" angle.

The DragonRace condition only filters out Dragons, but, for instance, you might want to filter out such things as AlduinRace and other flying races that might not be included if you plan on permitting the NPC to fight such enemies.