-
Notifications
You must be signed in to change notification settings - Fork 7
Walls
- Read about gameplay objects first.
- Make sure you've read about Heck's object properties to understand what can be changed on walls.
| Raw JSON | ReMapper |
|---|---|
d |
duration |
h |
height |
w |
width |
Walls can be created like any other beatmap object:
rm.wall(map, {
width: 2,
height: 2,
x: 0,
y: 1,
chromaColor: [0,0,0]
})A difficulty has a walls array instead of an obstacles array. If more obstacles end up being a thing, they will have separate arrays too.
Getting a transformation from world space to local space for walls can be quite hairy. It's a complicated mixture of world offsets and local offsets. It's also treated differently depending on whether size or animated scale (scale defined in the animation object) is being used.
Size will scale the object from it's bottom-left-front corner, like so:

Animated scale will scale the object from it's bottom-front edge at the middle, like so:

The goal of the rm.worldToWall function is to provide the necessary transformations required to align a wall to some transform. It assumes the center of the wall is the desired origin of the transform.
For simplicity's sake, either size or animated scale must be default. Depending on which one is being used, the scaleIsAnimated property will be set in the worldToWall function.
Here I'll show you can take some desired transform transform, and apply it to a wall.
If we're using size, this is how the data from worldToWall is to be interpreted:
const transform: rm.Transform = {
position: [0, 0, 0],
rotation: [0, 90, 0],
scale: [2, 2, 2]
}
const wtw = rm.worldToWall(transform, false)
rm.wall(map, {
life: 69420,
lifeStart: 0,
size: wtw.scale,
coordinates: [0, 0], // removes any lane offsets to the wall
animation: {
definitePosition: wtw.position,
localRotation: transform.rotation,
},
})If we're using an animated scale instead, we interpret the result like so:
const transform: rm.Transform = {
position: [0, 0, 0],
rotation: [0, 90, 0],
scale: [2, 2, 2],
}
const wtw = rm.worldToWall(transform, true)
rm.wall(map, {
life: 69420,
lifeStart: 0,
size: [1, 1, 1], // size MUST be 1
coordinates: [0, 0],
animation: {
scale: wtw.scale, // scale is instead used in here
definitePosition: wtw.position,
localRotation: transform.rotation,
},
})If you don't want to interact with worldToWall and just want to set a wall's world transform, you can use the Wall.setWorldTransform function. It can handle animated transforms as well, which automatically use the bake system.
const w = rm.wall(map, {
life: 10,
lifeStart: 0,
})
// Non animated, uses size
w.setWorldTransform({
position: [0, 0, 10],
rotation: [0, 20, 0],
scale: [1, 3, 2],
})
// Animated, bakes
w.setWorldTransform(
{
position: [
[0, 0, 0, 0],
[0, 10, 200, 1, 'easeInOutExpo'],
],
rotation: [
[0, 90, 0, 0],
[0, 0, 90, 1, 'easeInOutExpo'],
],
scale: [
[0, 90, 0, 0],
[0, 0, 20, 1, 'easeInOutExpo'],
],
},
)Internally this uses the rm.setWallWorldTransform function which references the rm.bakeWallWorldTransform function if it needs to bake.
The rm.modelToWall function is designed to represent model objects as walls. It takes in the relevant difficulty and an array of model objects or a string to the path of a .rmmodel file as an input for the model. You are also required to define the start and end of the walls' lifetime.
The model objects are interpreted as unit cubes with the anchor point at their center. The color property is interpreted as Wall.chromaColor, and the group property is ignored.
rm.modelToWall(map, 'my_model', 0, 200)The function returns a promise for an array of walls which have been used to construct the model.
const modelWalls = await rm.modelToWall(map, 'dormant/env', 0, 200)
// Example: make all resulting walls green
modelWalls.forEach((wall) => {
wall.chromaColor = [0, 1, 0]
})The optional distribution parameter controls the total spacing in beats that the walls are spawned. Walls are slightly shifted backwards from 0 to distribution beats in order to combat lag spikes from spawning too many walls at once. By default distribution is 0.3 beats.
Their animations account for this shift (unless they are a string pointing to a point definition in the difficulty) in order to make the distribution seamless. AssignPathAnimation events will also not be able to account for the differing lifetimes of the walls.
rm.modelToWall(map, 'dormant/env', 0, 200, 3) // spread spawning of walls over 3 beats- Info
- Difficulty
- Beatmap Objects
- Gameplay Objects
- Walls
- Basic Notemods
- Note Iterators
- Basic Events
- V3 Events
- Custom Events
- Heck Tracks and Animation
- Easings
- Point Types
- Point Utilities
- Heck Animation Baking
- Heck Animation Settings
Non-Vivify Models
Vivify