Post Details Page

Implementing Vehicle gameplay in Miliastra Wonderland

Vehicle Gameplay

Who this guide is for?

Anyone looking to implement a land-based vehicle gameplay, or get ideas on how to move faster. I showcase two different kinds of vehicle gameplay you can implement. They aren't the only ways one can implement vehicle gameplay, but should give you a good idea from a basic simple version to a more complex one.


Important to note that the official documentation does say that "Vehicle" is going to be added in Miliastra Wonderland, so part of this may become irrelevant in the future depending on how it's implemented, but some of it should still be relevant. It's possible that the official "Vehicle" that will be in Miliastra Wonderland will be similar to the boat controls that we have currently in Genshin Impact.


Note: This guide is written during version Luna V.

The Tutorial

Basic Version


Starting off, we'll first create the necessary prefabs.


Creating VehicleMotion Prefab


The first prefab we'll create will be responsible for pulling the player's character, which we will name VehicleMotion. It will be following the player's character by the means of a Follow Motion Device component with an offset. And it will pull the player with a Force Field that is oriented to pull players towards the center of the entity.


  1. In the Prefab Tab, create a Prefab with an Empty Model (you can find it under Dynamic Units, Others)
  2. Name it "VehicleMotion"
  3. Turn off it's Native Collision

(Optional, this is to give the entity a visual appearance so you see where it is in development. You'll most likely remove or turn this off for an actual game)

  1. Go to the Decoration List and add in a Model, for this example we'll use a Wooden Signpost
  2. Turn off the decoration's Native Collision


  1. Go to the components tab, and add a Follow Motion Device component


We don't need to edit anything for the Follow Motion Device component here, as we will setting in a node graph. Just need to make sure the entity has a Follow Motion Device component in order for us to configure it in node graphs.


  1. And then also add in a Character Disruptor Device component
  2. Go to Advanced Editing for the Character Disruptor Device component
  3. Change the Device type to Force Field
  4. Set both the Inner and Outer Sphere Radius both to 2.00
  5. Set the Disturbance Direction to "Line Connecting Sphere Center and the Trigger Area"
  6. Set both Inner Diameter Orientation and Orientated Outward from the Outer Diameter to "Towards Sphere Center"
  7. Set both the Inner and Outer Diameter Velocity to 5.00

This allows the Force Field to pull the Character towards the sphere center.



  1. Go to the Trigger Area tab
  2. Set the Trigger Area Shape to Sphere
  3. Set the Radius to 2.00

This just makes it so the Trigger Area is the same as the Force Field Sphere's 2m radius.



Make sure you save the Prefab.


Creating VehicleModel Prefab


Next we'll need to create a Prefab that gives the visual appearance of the vehicle. It will allow the player to know which way the Vehicle is going, additionally we will be turning it to create a "Car Drifting" effect in a later section of this guide.


  1. In the Prefab Tab, create a Prefab with a Toy Cart Model (Type in "Toy Cart" in the search bar, while in "Gameplay Mechanism")
  2. Name it "VehicleModel"
  3. Set the Zoom to, (0.3, 0.3, 0.3)
  4. Turn off it's Native Collision

For the purpose of this guide, we will just be using this simple model. You can create your own model with all sorts of decorations if you desire, just make sure to turn off it's Native Collision.


  1. Go to the Components Tab, and add a Follow Motion Device component

Same thing with the VehicleMotion prefab, we'll be setting the Follow Motion Device details in a node graph, so we won't have to do anything extra here.


Make sure you save the Prefab.


Creating entities based on the prefabs in node graph


Next we'll be utilizing a node graph to create the entities correlated to the VehicleMotion and VehicleModel prefabs.


  1. In Miliastra Sandbox window, go to your Server Node Graph, Entity Node Graph, open up the default tab, and create a node graph.
  2. Name it CharacterOnCreate

We'll be putting this on the Character. It will be responsible for creating the vehicle related entities and having them follow the Character.


  1. Open up the node graph, CharacterOnCreate
  2. Add in the node "When Entity is Created"
  3. Add in the node "Create Prefab"
  4. Set it as follows
  5. Prefab ID: Copy the prefab ID from your VehicleModel's Prefab ID (You can find the Prefab ID on the top right of the screen when the prefab is selected, under the Prefab's name)
  6. Location: 0, 0, 0
  7. Rotate: 0, 0, 0
  8. Owner Entity: Get Self Entity
  9. Overwrite Level: No
  10. Level: 1
  11. Unit Tag Index List: ignore it, just leave it as is.
  12. Plug in the execution flow from "When Entity is Created" node to the "Create Prefab" node.

This creates a VehicleModel entity at Location 0,0,0


  1. Add in the node "Switch Follow Motion Device Target by Entity
  2. Set it as follows
  3. Target Entity: Created Entity output from the "Create Prefab" node
  4. Follow Target Entity: Get Self Entity
  5. Follow Target Entity Parameter: "GI_AvatarRoot"
  6. Location Offset: 0, 0, 0
  7. Rotation Offset: 0, 0, 0
  8. Set Follow Coordinate System: "Local Coordinate System"
  9. Set Follow Type: "Completely Follow"
  10. Plug in the execution flow from "Create Prefab" node to the "Switch Follow Motion Device Target by Entity" node.

This makes the VehicleModel follow Self Entity, in this case it will be the Character, as we will mount this node graph onto the Character. Note that because we have Follow Type as "Completely Follow" when the Character rotates, the VehicleModel will rotate along with it.


  1. Add in the node "Set Custom Variable"
  2. Set as follows:
  3. Target Entity: Get Self Entity
  4. Variable Name: "VehicleModel"
  5. Variable Value: Plug in the Created Entity output from the previous "Create Prefab" node.
  6. Trigger Event: No
  7. Plug in the execution flow from "Switch Follow Motion Device Target by Entity" node to "Set Custom Variable" node.

This allows us to reference the VehicleModel entity in the node graph for future uses.



Next we'll be doing a similar thing but for the VehicleMotion prefab, but with a key difference in the Follow Motion Device's location offset.


  1. Add in the node "Create Prefab"
  2. Set as follows:
  3. Prefab ID: Copy the prefab ID from your VehicleMotion's Prefab ID (You can find the Prefab ID on the top right of the screen when the prefab is selected in the Prefab Library module, under the Prefab's name)
  4. Location: 0, 0, 0
  5. Rotate: 0, 0, 0
  6. Owner Entity: Get Self Entity
  7. Overwrite Level: No
  8. Level: 1
  9. Unit Tag Index List: ignore it, just leave it as is.
  10. Plug in the execution flow from "Set Custom Variable" node to the "Create Prefab" node.

(You could also just plug the execution flow from the "When Entity is Created" to the "Create Prefab" node that creates the VehicleMotion entity, the two Create Prefabs do not need to be executed in sequential order.)


  1. Add in the node "Switch Follow Motion Device Target by Entity
  2. Set it as follows:
  3. Target Entity: Created Entity output from the "Create Prefab" node corresponding to VehicleMotion prefab.
  4. Follow Target Entity: Get Self Entity
  5. Follow Target Attachment Point Name: "GI_AvatarRoot"
  6. Location Offset: 0, 0, 1
  7. Rotation Offset: 0, 0, 0
  8. Follow Coordinate System: Local Coordinate System
  9. Follow Type: Completely Follow
  10. Plug in the execution flow from "Create Prefab" node to the "Switch Follow Motion Device Target by Entity" node.

Note the important difference in this, the Location Offset needs to be at 0,0,1. With Z being greater than 0. Because the Follow Type is "Completely Follow" when the Character rotates, the VehicleMotion rotates with this offset, resulting in the VehicleMotion entity being in front of the Character at all times. Allowing it to pull the Character to wherever it's facing.


We also aren't setting a custom variable for the VehicleMotion at this portion of the guide, but will be in the later parts. Which we will do so when we need to.


Make sure to save the node graph.


Mount the node graph


Next we just need to mount the node graph.


  1. Go to the Combat Preset Module in the Genshin Impact window
  2. Select Edit Character
  3. Go to the Node Graph section, and add in the "CharacterOnCreate" node.


Time to test it!


If all goes well, your Character should naturally move towards wherever they face. A way for it to have it act like a vehicle is holding W key and rotating the camera. For this demonstration we didn't hide the Character model, so that you can see what is actually happening. In a later section we'll cover how to hide the Character model.


Basic Version with Drifting Visuals


Now in this part, we'll be adding a bit more flair to this version, and that is making it look like the vehicle is doing a car drift.


In order to do so, we'll be utilizing a looping timer, that checks the current direction from the direction last recorded. If that difference in direction is greater or less than a certain amount, we'll add a rotation offset to the Follow Motion Device of the VehicleModel, clockwise or anticlockwise depending on the difference.


Creating Timer for Polling Loop


  1. In Miliastra Sandbox window, open up the "CharacterOnCreate" node graph in the Server Node Graph, Entity Node Graph.
  2. Add a node "Start Timer"
  3. Set it as follows
  4. Target Entity: Get Self Entity
  5. Timer Name: "PollDirection"
  6. Loop: Yes
  7. Timer Sequence: Assembly List with 0th index as 0.5
  8. Plug in the execution flow from "When Entity is Created" node to "Start Timer" node.

This creates a looping timer, that will run every 0.5 seconds, named "PollDirection" that can be listened to by "Self Entity" in this case, any node graphs mounted on the Character.

The execution flow order doesn't matter so plugging it in direction from "When Entity is Created" should be fine. You can plug it in from the end of the last node that we've made earlier if you like to see everything happen in sequence.


Node graph to check for drift conditions


Now we need to handle what happens when the timer is fired.

  1. Under Server Node Graph, Entity Node Graph, create a new node graph, name it "PollForDirection"



This is going to get very wordy if I start listing out every detail, so please refer to the images provided if it gets confusing.


First we'll need to compare the current direction of the character, to the previous direction. In order to do so, we'll need to store the previous direction somewhere. (Note: in this section, what I refer as "direction" might be more accurately interpreted as "rotation" instead, keep in mind that it's a rotational value, and not a directional vector)


  1. Open up "PollForDirection" node graph.
  2. Open up the "Node Graph Variable" sub window thing.
  3. Add in a new 3D Vector
  4. Name it "LastDirection"



Next we'll be comparing current direction of the Character to this "LastDirection", and utilizing the Y component. This is the only rotational value we care about.


Accounting for 360 degree issue


Because the rotational values goes from 0 to 359.99999, we need to account for the sort of "jump" in value when comparing the values. For example, if current rotation is 90 degrees is to the east, when compared it a previous rotation of 358 which is slightly left of north. It becomes 90 - 358 resulting in -268, meaning it thinks it has turned anti-clockwise 268 degrees. When in reality it is more likely to be 92 degrees clockwise.


To compensate for that, any value that is greater than 180 or lower than -180, needs to be subtracted by 360, or added by 360 respectively. (-268 from the previous example becomes 92)


Thus we will be checking for three possibilities.

  • Y-component being greater than 180
  • Y-component being less than -180
  • Neither

We will then subtract, or add to it, or do nothing to it, and store it as a Local Variable.


Checking for drift conditions


Next we take that Local Variable value, and we'll be checking for another three possibilities.

  • Is the rotational difference(the value) greater than 15
  • Is the rotational difference(the value) less than -15
  • Neither

15 is just a degree threshold I decided on whether or not the "drift" effect should take place. Feel free to increase or decrease it as you see fit, just make sure its in reasonable range.


Make sure the "Get Local Variable" node is set as a Floating Point Number

Creating the drift effect


Now with these three possibilities, we all do the same thing just with different values.

  • Rotation offset of Y 30
  • Rotation offset of Y -30
  • Rotation offset of Y 0

The 30 degrees is also another number I decided on how much visual "Drift" should occur. Feel free to change it as you like within reasonable means.


Update for next loop, mounting node graph, and test run


Finally we need to update the "LastDirection" for the next timer run.


Save the node graph.


Now we need to mount this node graph onto the Character.


  1. Open up Creation Preset on Genshin Impact
  2. Edit Character
  3. Go to the node graph section, and add in the "PollForDirection" node graph we just created.


Time to test it!


Turning Vehicle Off (Optional)


I'll also briefly demonstrate how you can turn the vehicle's motion off. The same principles is used for speeding it up, or decreasing it. By changing the Character Disruptor Device setting on the VehicleMotion entity, we can change the behavior.


Creating Tab Component


  1. Go to the Prefab Library, and select your VehicleMotion prefab.
  2. Under components, add in a new Tab component.
  3. Go to Advanced Editing under the Tab component.
  4. Change the tab prompt text to "Toggle" (Note: You need to be at least Craftsmen Level 2 to see the actual text in game)
  5. In Trigger Option Area, change it to Trigger Area Shape of "Sphere" and a Radius of "2.00"
  6. Remember to overwrite and save the prefab

This creates a Tab option around the VehicleMotion, that the Character can press for us to interact with it.


Creating Node Graph for Toggle


  1. Now in Miliastra Sandbox window, under Server Node Graph, Entity Node Graph, create a new node graph.
  2. Name it "ToggleMotion"
  3. Open up the "ToggleMotion" node graph.


Storing Toggle State


We'll be making a toggle that turns the vehicle's motion on and off. To do so, we'll need a variable to remember the state of the motion, as we cannot retrieve what Device ID the Character Disruptor Device is set to.


  1. Open up the Node Graph Variable subwindow thing.
  2. Add in a boolean, name it "On".
  3. Set its default value to "Yes"

Toggling Force Field


Now we just need to change the Character Disruptor Device's Device ID from either 0 (which is nothing) or 1 (the one force field we put into the component)


  1. Add in the node "When Tab is Selected"
  2. Add in the node "Set Node Graph Variable"
  3. Set it as follows
  4. Variable Name: Select the variable, "On"
  5. Variable Value: Get Node Graph Variable (On) -> Logical NOT Operation Node
  6. Trigger Event: No
  7. Connect execution flow from "When Tab is Selected" to "Set Node Graph Variable"
  8. Add in the node "Set Character Disruptor Device"
  9. Set it as follows
  10. Target Entity: Get Self Entity
  11. Device ID: Get Node Graph Variable (On) -> Data Type Conversion
  12. Plug the output of that into "Device ID" of "Set Character Disruptor Device"

If you have more device's under your VehicleMotion's Character Disruptor Device component, you will need to do the appropriate handling, but the principle is the same in using the same "Set Character Disruptor Device" node to change it.


Make sure to save the node graph.


Mount node graph and test run


Now we just need to mount it.

  1. In Genshin Impact, go to the Prefab Library.
  2. Select your VehicleMotion prefab.
  3. Under the node graph section, add in the node graph "ToggleMotion"
  4. Remember to overwrite and save the prefab


Now we can go and test run.


For your own future purposes, you can even choose to have multiple VehicleMotion entities following the Character. Because multiple Force Field's can apply their influence to the Character at the same time. Allowing you to speed up or slow down in difference increments. Keep in mind there is a speed limit that still cannot be bypassed with multiple Force Fields. Refer to my previous guide for said speed limit and more details.

Hiding Character Model (Optional)


If you want to hide your Character Model, so that it's only the vehicle showing. You can do so by creating a unit status, set its Infinite Duration to on. And add in the Effect "Character Hidden".


Note that the boolean local filter when returning an output of false, results in the character being fully hidden. And on the output of true, results in the character being partially hidden.

Left is the boolean filter returning "True". Right is the boolean filter returning "False"


Make sure to add the status under "Edit Character", "Unit Status -> Advanced Editing". Or apply the status in a node graph.

Turning Controls Version


So the basic version of in this Vehicle guide, has some downsides. For starters, you can turn 180 degrees instantly and the "Vehicle" does a 180 degree turn. Hardly realistic of a locomotion vehicle. In this "Turning Controls" version, we will be utilizing the "Allow Input Steering" in a skill's status track. Particularly of a Hold Skill. This will allow the player to hold a skill down, and turn.


The "Allow Input Steering" essentially makes it so instead of instantly turning whenever the player presses a directional input, it gradually turns towards that direction. The speed in which it turns is configurable in the skill's Animation Editor.


Let's begin.


Vehicle Prefab


First of we'll be creating a new Prefab, named "Vehicle" as more complex logic is added, it may become handy and more organized to have an entity that handles all the turning logic related to a vehicle gameplay. It's also necessary in so that the VehicleModel has something to follow that has a fixed rotation.


  1. In Genshin Impact, in the Prefab Library, create a new empty Prefab, name it "Vehicle"
  2. Set its Native Collision to Off

  1. Under the components tab, go to "Advanced Editing" under "Custom Variable"
  2. Add in a 3D vector.
  3. Name it "CurrentDirection".
  4. Set the default values to 0,0,1.

We set it here instead of a node graph, so that we can have customizable starting value that faces north. This will be handy as our vehicle spawns facing north in this guide, and thus the force field is pulling them north.


In your own game, you may need to customize this variable's starting value as something else, depending on your needs, either in the prefab library or in a node graph.


Next we need to make the "Vehicle" follow the Character.

  1. Under the components tab, add in a "Follow Motion Device" component.

Same thing as before, we customize this in a node graph.


Make sure to save the prefab.


Adding Vehicle as a Variable

So normally, this step wouldn't be necessary, and its a bit weird. But without it things might not work. In particular we need to add in a custom variable in the Character named "Vehicle" of type Entity. You might say, [we don't even have a default value for it, why don't we just set it in the node graph?] I'm suspecting that because we will be needing to call this variable in a Client Node Graph, and because we only set it in a Server Node Graph (CharacterOnCreate), the client side node graph never realizes this variable exists. Thus setting it in the Genshin Impact editor under the Character's Custom Variable fixes an issue where the client side node graph can't find the variable.


  1. In the Combat Preset, Click Player on the top left.
  2. Select Edit Character (assuming you just have one default player template)
  3. Under the components tab, go to Advanced Editing for Custom Variable
  4. Add in a variable of type "Entity"
  5. Name it "Vehicle".


Refactoring CharacterOnCreate for the new changes


We'll be changing a couple of things about how things are handle in "CharacterOnCreate" , these are the notable things we'll be doing.

  • The first being that since we're having a "Vehicle" entity handle things, we will be moving references to the "VehicleModel" to be stored in the "Vehicle".
  • We will also remove the timer, as the way we turn makes it not the best option to create a "Drift" effect that way. We'll be using a difference technique for the "Drift" effect in this version.
  • We need to have the VehicleModel and VehicleMotion follow the Vehicle instead of the Character.
  • The last and most notable part, is that the Vehicle has a follow type of "Follow Location" making it not turn regardless of where the character faces.


  1. In Miliastra Sandbox window, open up your "CharacterOnCreate" node graph.
  2. Let's first delete the "Start Timer Node" and its related inputs.
  3. Next, unhook the execution flow from the "When Entity is Created" node to the "Create Prefab" node

We'll be creating the Entity from the Vehicle Prefab, and set the Follow Motion Device for it, similar stuff as before.

  1. Add a "Create Prefab" node
  2. Set it as follows:
  3. Prefab ID: copy the Prefab ID of the Vehicle Prefab
  4. Location: 0, 0, 0
  5. Rotate: 0, 0, 0
  6. Owner Entity: Get Self Entity
  7. Overwrite Level: No
  8. Level: 1
  9. Unit Tag Index list: ignore it, don't need to set it.
  10. Connect the execution Flow from "When Entity is Created" node to this "Create Prefab" node.
  11. Add a "Switch Follow Motion Device Target by Entity"
  12. Set it as follows:
  13. Target Entity: Created Entity from the Create Prefab node corresponding the Vehicle prefab we just made.
  14. Follow Target Entity: Get Self Entity
  15. Follow Target Attachment Point Name: "GI_AvatarRoot"
  16. Location Offset: 0, 0, 0
  17. Rotation Offset: 0, 0, 0
  18. Follow Coordinate System: Local Coordinate System
  19. Follow Type: Follow Location (this is critical, and different from the others we've done)
  20. Connect the execution flow from "Create Prefab" node to "Switch Follow Motion Device Target by Entity"


Next we need to store a reference to the Vehicle.

  1. Add Set Custom Variable node
  2. Set it as follows:
  3. Target Entity: Get Self Entity
  4. Variable Name: "Vehicle"
  5. Variable Value: Created Entity from the Create Prefab node corresponding to the Vehicle prefab.
  6. Trigger Event: No
  7. Connect the execution flow from "Switch Follow Motion Device Target by Entity" to this "Set Custom Variable" node.


Connect these nodes to the existing nodes.

  1. Connect the Switch Follow Motion Device by Entity pertaining to the Vehicle, to the Create Prefab node pertaining "VehicleModel".


Next we need to change both VehicleModel and VehicleMotion entities to follow the Vehicle instead of the Character.

  1. Unplug the "Follow Target Entity" for the "Switch Follow Motion Device Target by Entity" pertaining to BOTH "VehicleModel" and "VehicleMotion" entities.
  2. Plug in the Created Entity for the "Vehicle" into the "Follow Target Entity" you just unplugged.
  3. Change both of the "Switch Follow Motion Device Target by Entity" node's "Follow Target Attachment Point Name" to "GI_RootNode"


Now we just need to change where the VehicleModel reference is stored.

  1. Unplug the Target Entity for "Set Custom Variable" pertaining to the Variable Name "VehicleModel"
  2. Plug in the Created Entity for the "Vehicle" into the Target Entity for that "Set Custom Variable" node.


Next we need to also store a reference to the VehicleMotion, which we previously did not need to do.

  1. Add a Set Custom Variable Node
  2. Set it as follows:
  3. Target Entity: "Created Entity" from "Create Prefab" pertaining the "Vehicle"
  4. Variable Name: "ForwardForceField"
  5. Variable Value: "Created Entity" from "Create Prefab" pertaining the "VehicleMotion"
  6. Trigger Event: No
  7. Connect the execution flow from "Switch Follow Motion Device Target by Entity" pertaining to "VehicleMotion" to this "Set Custom Variable"


And we are done updating this node graph. Make sure to save the node graph.


There's only some order of execution sequence that must be followed.

  • The Vehicle Prefab must be created before the other two prefabs.
  • Each of the "Switch Follow Motion Device Target by Entity" must be called after the corresponding prefabs are created.
  • Each of the "Set Custom Variable" must be called after the corresponding prefabs are created.


Creating Client Node Graphs for Turn Skill


In order for us to do stuff with a Hold Skill, we need client side node graphs, we'll first be making two client side node graphs, one for when the player starts pressing the skill, and one when they release the skill.


  1. In Miliastra Sandbox window, press the window tab on the top left.
  2. Select Client Node Graph Resource Explorer.
  3. In Character Skill Node Graph's default tab, create two skill node graphs.
  4. Name them, "TurnStart" and "TurnEnd"


Creating Turn Skill


Now we go back to the Genshin Impact window and configure the skill.


  1. In Genshin Impact, go to the Combat Preset module.
  2. And go to the Skill section on the left.
  3. Add a New Skill
  4. Name it "Turn"
  5. Choose a skill icon of your choosing
  6. Change the Skill type on the top right, from "Normal Skill" to "Hold Skill"


Configuring Turn Skill's Visuals


Next, we'll need to configure the skill.


  1. Open up the Animation Editor
  2. Select "General Quick Chant_01" for the start of the animation.
  3. Select "General Chant in Place _01_Loop Animation" for the loop part of the animation
  4. Configure the loop part of the animation to be 6.00s (Optional, up to your preference)
  5. In the Default Branch, Select "General Chant in Place_01_Post-Cast".
  6. Configure the Default Branch animation time to 0.5 sec (Optional, up to your preference)
  7. Click the Response_1 in the Branch Track, and configure the "Response_1 Transition to Branch" to "Default Branch"

Step 7 is important, as it allows it to transition into the Post Cast part of the animation timeline.


Configure Turn Skill's node graph execution


Next we'll add in where the node graph occurs.


  1. In the First (+) area for the Start Event Track, click it and select the "TurnStart" node graph you created.
  2. In the (+) area right after the Default Branch ends, for the Start Event Track, click it and select the "TurnEnd" node graph you created.


Configure Turn Skill to "Allow Input Steering"


Finally we need to add in the "Allow Input Steering" status.

  1. Right click the timeline to the right of "Status Track", select "Add Event" and select "Allow Input Steering" (If for some reason you don't see the "Status Track" you may need to scroll down, if it's still not there, right click the left side of the timeline, and add a New Track -> New Status Track)
  2. Click the "Allow Input Steering" block in the timeline, and change the "Turning Angular Velocity" to 90.00 (Value is up to your preference, just don't set it as 0)

The Turning Angular Velocity is what determines the rotational speed in which the player can turn towards the directional input.

You can now exit the Animation Editor, and remember to save the skill.


Adding Turn Skill to Class


Now with the Turn Skill created, we need to have it be added to the Class that the Player belongs to.


  1. In the Combat Preset module, go to the Player Tab on the top left.
  2. Select Class, and Custom Class (in my case, I only have the default class, choose your corresponding class if you have more)
  3. Switch to the middle skill tab on the right side of the screen.
  4. Click + under Normal Attack and select "Turn" skill that you created.
  5. (Optionally) You could also change the Active Skill Quantity to more than 0, and set the skill there, or utilize the custom button skills.

I found it easier to WASD to turn and just hold the left mouse button to initiate the turn.


Configuring Turn Skill Node Graphs


Now we need to configure the TurnStart and TurnEnd skill node graphs. We need the player to face the direction of the Vehicle to prevent it from getting to go wherever it wants when the Turn Skill starts.


First we need to make the player face the direction of where the vehicle is going.

  1. In Miliastra Sandbox window, go to Client node Graph Resource Explorer (If you can't find it, click the Window on the top left)
  2. Open up the TurnStart node graph you created earlier under Character Skill Node Graph
  3. Add in a "Player Turns to Face Set Direction" node.
  4. Add in the following
  5. Get Self Entity
  6. Get Custom Variable with Variable Name "Vehicle"
  7. Get Custom Variable with Variable Name "Current Direction"
  8. Then plug the resulting variable into the Orientation input of "Player Turns to Face Set Direction"
  9. Connect the execution flow from "Node Graph Starts" to "Player Turns to Face Set Direction"


Next we need to let the server side know that the player has pressed the Turn skill. We'll utilize signals.

  1. At the bottom of the node graph, select the Server Signal Explorer button.
  2. Add a new Signal
  3. Name it "TurnStarted"
  4. Apply Changes

  1. Next in the node graph, add in the "Send Signal to Server Node Graph"
  2. Press the magnifying glass in "Signal Name" and select "TurnStarted"
  3. Connect the execution flow from "Player Turns to Face Set Direction" to "Send Signal to Server Node Graph"

Remember to save the node graph.


Next we'll need to configure the TurnEnd node graph.

  1. Open up the TurnEnd node graph you created earlier under Character Skill Node Graph.
  2. At the bottom of the node graph, select the Server Signal Explorer button.
  3. Add a new Signal
  4. Name it "TurnEnded"
  5. Give it two parameters of type "3D Vector"
  6. Name one, "ForceFieldOffsetVector" the other "VehicleRotation"
  7. Apply Changes.


  1. Next in the node graph, add in the "Send Signal to Server Node Graph"
  2. Press the magnifying glass in "Signal Name" and select "TurnEnded"
  3. Plop in a "Get Self Entity"
  4. Connect that to a "Get Entity Rotation"
  5. Plug in the "Rotate" output value into "VehicleRotation" for the "Send Signal to Server Node Graph"
  6. Put down a "3D Vector Rotation" node
  7. And put in 0, 0, 1 for the Rotated 3D Vector
  8. Plug in the "Rotate" output value into the "Rotate" input of "3D Vector Rotation" node.
  9. Plug in the "Result" from the "3D Vector Rotation" node into the "ForceFieldOffsetVector" for the "Send Signal to Server Node Graph"
  10. Finally, connect the execution flow from "Node Graph Starts" to "Send Signal to Server Node Graph".

Remember to save the node graph.


Handling Turning on Server Side


Now that we have those setup, we need to handle the server side of when these signals are fired.


To keep things organized, we'll be utilizing a separate node graph to handle everything that correlates to turning.


  1. In Miliastra Sandbox window, go to Server Node Graph Resource Explorer
  2. Under Server Node Graph, Entity Node Graph, create a new node graph.
  3. Name it "HandleTurn" and open it.


First, to handle when turn starts. Remember that we would have turned the Character to face the Vehicle's direction, thus we can now change the VehicleModel and VehicleMotion to follow the Character.


  1. Add the node "Monitor Signal" and select "TurnStarted" under the signal name.
  2. Add in two "Switch Follow Motion Device Target by Entity" nodes, and connect them in sequence to the "Monitor Signal node."
  3. For the first one the inputs should be the following
  4. Target Entity: Get Self Entity -> Get Custom Variable (VehicleModel)
  5. Follow Target Entity: Get Self Entity -> Get Owner Entity
  6. Follow Target Attachemnt Point Name: "GI_AvatarRoot"
  7. Location and Rotation Offset: 0, 0, 0
  8. Follow Coordinate System: Local Coordinate System
  9. Follow Type: Completely Follow
  10. For the second one the inputs should be the following
  11. Target Entity: Get Self Entity -> Get Custom Variable (ForwardForceField)
  12. Follow Target Entity: Get Self Entity -> Get Owner Entity
  13. Follow Target Attachemnt Point Name: "GI_AvatarRoot"
  14. Location Offset: 0, 0, 1
  15. Rotation Offset, 0, 0, 0
  16. Follow Coordinate System: Local Coordinate System
  17. Follow Type: Completely Follow


Now when the player presses the skill, everything changes to the basic version, except they are stuck in "Input Steering Mode" when they are holding on to it. We now need to configure the following when they release the skill which is when "TurnEnded" is called.

  • We need to update the direction of the vehicle, because the Character may have turned
  • And the "VehicleModel" and "VehicleMotion" needs to revert back to following the "Vehicle"


  1. Add the node "Monitor Signal" and select "TurnEnded" under the signal name.
  2. Add in the node "Set Custom Variable" and configure as follows
  3. Target Entity: Get Self Entity
  4. Variable Name: "CurrentDirection"
  5. Variable Value: Plug in the output from the Monitor Signal node named "ForceFieldOffsetVector"
  6. Trigger Event: No
  7. Connect the execution flow from Monitor Signal node to the Set Custom Variable node.
  8. Add two nodes of "Switch Follow Motion Device Target by Entity" and connect the execution flow in sequence to the "Set Custom Variable" node.
  9. Set the first one as follows
  10. Target Entity: Get Self Entity -> Get Custom Variable (VehicleModel)
  11. Follow Target Entity: Get Self Entity
  12. Follow Target Attachment Point Name: "GI_RootNode"
  13. Location Offset: 0, 0, 0
  14. Rotation Offset: Plug in the output from the Monitor Signal node named "VehicleRotation"
  15. Follow Coordinate System: Local Coordinate System
  16. Follow Type: Completely Follow
  17. For the second one, set it as so
  18. Target Entity: Get Self Entity -> Get Custom Variable (ForwardForceField)
  19. Follow Target Entity: Get Self Entity
  20. Follow Target Attachment Point Name: "GI_RootNode"
  21. Location Offset: Plug in the output from the Monitor Signal node named "ForceFieldOffsetVector"
  22. Rotation Offset: 0, 0, 0
  23. Follow Coordinate System: Local Coordinate System
  24. Follow Type: Completely Follow

And that's it for handling TurnEnded.


Notice that when reverting back to having "VehicleModel" and "VehicleMotion" we configure the rotation offset and location offset respectively differently? Recall that the "Vehicle" never rotates, it is always facing the same direction. Thus we need to have the "VehicleModel" and "VehicleMotion" be rotated on the offset, with one needing to turn by rotation, the other is positioned at a different offset so it matches the rotation.


Finally mount the HandleTurn node graph to the Character.

  1. In Genshin Impact, go to the Prefab Library
  2. Select the Vehicle Prefab, and go to the node graph Tab
  3. Add HandleTurn node graph

Remember to overwrite and save the prefab.


You can now test play it.


Turning Controls with Drifting Visuals


Now I personally prefer this turning controls version, and we definitely need to get in those "Drift" effect back in. In this section we'll do just that.


Instead of a timer, we'll be adding multiple client side node graph calls to the Turn skill's animation timeline, from the moment it presses hold, till right before it releases. This way we can create the same effect as a timer. We'll then handle the same logic in a client side node graph, instead of the server side node graph with the timer.


Let's begin.


First we need to create the client side node graph that we call when we are turning.

  1. Go to Miliastra Sandbox, Client Node Graph Resource Explorer
  2. Create a Character Skill Node Graph, and name it "TurnHold"


Next we'll need to set it so that it's triggered in the Skill Animation Editor.

  1. In Genshin Impact, go to Combat Preset module, Skills.
  2. Open up the Animation Editor for the Turn Skill you created.
  3. In the Node Graph Event Track, select the point at 0.5 seconds,
  4. Right click the track, and select "Add Event", select "TurnHold"
  5. Do the same thing for every 0.5 seconds for the duration of the Loop Animation. (So before "TurnEnd" occurs)

Close the Animation Editor and remember to save the updated Skill.


Next we go back to the Miliastra Sandbox to configure the TurnHold node graph.The logic is identical, except we are using client side nodes, so some differences may occur in what nodes we use. You cannot just copy and paste, since server nodes are not client nodes.


Instead of going through every step again, I'll list out the differences, and you can just compare with the images provided.


  • At the start, we need to convert the "CurrentDirection" variable we are storing in the Vehicle, to a rotational variable, because it is a Directional Vector.
  • Setting and Getting Local Variable is different in Client Side. We actually get to name the variable name, so you can just name it "turn_angle".
  • The three possiblities, Drift clockwise, drift anti-clockwise, no drift. We will let a server node graph handle, by sending a signal.
  • We also let a server node graph handle updating the direction.
  • Thus we'll be creating two new signals, "Update Direction" and "TurnDrift" see the images for the parameters necessary for them.

UpdateDirection signal with its parameter

TurnDrift signal with its parameter


Make sure the Get Local Variable is set to Float type and not Integer

Now with that set, we need to do the server side handling.


  1. In Miliastra Sandbox, Server Node Graph Resource Explorer, Entity Node Graph, open up the HandleTurn node graph.
  2. Add in a Monitor Signal Node, set the signal to "Update Direction"
  3. Add in a "Set Custom Variable" node
  4. Set it as the following:
  5. Target Entity: Get Self Entity
  6. Variable Name: "CurrentDirection"
  7. Variable Value: Plug in the "UpdatedDirection" output from Monitor Signal node.
  8. Trigger Event: No
  9. Next add in a Monitor Signal Node, set the signal to "TurnDrift"
  10. Add in a "Switch Follow Motion Device Target by Entity" node
  11. Set it as the following:
  12. Target Entity: Get Self Entity -> Get Custom Variable (VehicleModel)
  13. Follow Target Entity: Get Self Entity -> Get Owner Entity
  14. Follow Target Attachment Point Name: "GI_AvatarRoot"
  15. Location Offset: 0, 0, 0
  16. Rotation Offset: Plug in "DriftAmount" output from Monitor Signal node to "Create 3D Vector" node's Y-Component, plug the 3D Vector into Rotation Offset.
  17. Follow Coordinate System: Local Coordinate System
  18. Follow Type: Completely Follow


And that's it! Make sure to save the node graph, and go and test run it.


Turning Controls with Restricting player movement


Now this version so far is decent, the vehicle cannot do an instant 180, but the player can still move around. A quick trick to restrict the player movement we can do is to give the player essentially a no gravity status. Float them in the air, enable "Allow Cast in Mid AIr" for the Turn Skill. And finally moving the vehicle model's offset everywhere to compensate for the fact that we are floating the player.


First to give the player a "no gravity" status.

  1. In Genshin Impact, go to the Combat Preset module, select the Status tab on the most left.
  2. Create a new status. We'll name it "No_Gravity"
  3. Set the Infinite Duration to On
  4. Go to the Effect Details
  5. Add Effect, and add in the effect named "Fall Efficiency Change Value"
  6. Set the Change Value (%) to -200


Next we need to apply it to the Character

  1. Go to the Player Template, and Edit Character
  2. Select the Components Tab on the right side of the screen.
  3. Click "Advanced Editing" under Unit Status. (If you don't see Unit Status, you can add it as a component)
  4. Add Status, and select the "No_Gravity" status


Next we need to float the player, we'll do it by simply raising the spawn point up.

  1. Go to the Entity Placement Module
  2. Select the Create Preset Point that determines where the player spawns
  3. Change it's Y location to 1.00


Finally we need to change the Location Offset's Y value for VehicleModel everywhere to compensate for that.

You'll find those in the following places, set the Location Offset to 0, -1, 0 for all of them.

  1. in the CharacterOnCreate node graph.
  2. in the HandleTurn node graph.
  3. For TurnStarted signal
  4. For TurnEnded signal
  5. For TurnDrift signal


Remember to change the Turn Skill to "Allow Cast in Mid Air"


Now you can test play, it should look like this.


Final notes

If you are planning to make your game support multiplayer, you will need to configure Filter Node Graphs for your Force Fields to only work on the corresponding player.


Afterword


This guide took more time than I expected. But it's not the only ways to do vehicle, I'm still experimenting with other ways, but these are the more straight forward ways I've found. There's a lot of interesting things you can do, such as adding an entity

much like "VehicleMotion" but it has an Ejector, which allows you to have a temporary speed boost mechanic. I didn't cover any of that, because this guide definitely took a long of time to cover already. But I may cover more additional things one can do in a future guide.


I hope the guide has been beneficial for you to understand how different ways of vehicle can be implemented. That is until they straight up add a native Vehicle mode to Miliastra Wonderland. (I swear... if it somehow is in Luna VI or something...) But until that time comes, these are a few ways you can implement a vehicle gameplay in your games.


Feel free to leave any questions you like.


Genshin Impact • Guides & Analyses
Repost allowed
Miliastra Wonderland
3
1
2
3
0
All comments 1

Loading...

All Tools

Recommended Users