Hi. I want to create a tower defense like game but I’m currently stuck on creating smooth tower placement.
I’m spawning a placeholder tower to indicate the spawning position before actually placing the tower, but the movement of the placeholder tower is really snappy and not smooth at all.
I’ve tried several methods such as linear interpolation and control rigs, but I can’t seem to get the hang of control rigs (and how to access them in verse) and I’m not even sure if they’re suited for my use case for spawning props.
This is my best try right now using linear interpolation and tweaking the TimeToMove
and alpha
, but its still very snappy:
@editable
InputTrigger:input_trigger_device = input_trigger_device{}
@editable
PlaceholderAsset:creative_prop_asset = DefaultCreativePropAsset
var SpawnedPlaceholder:logic = false
OnBegin<override>()<suspends>:void =
InputTrigger.PressedEvent.Subscribe(OnInputPressed)
OnInputPressed(Agent:agent):void =
spawn{SpawnAndMovePlaceholderTower(Agent)}
DrawDebugLine(Agent:agent):transform =
var PlaceLocation:vector3 = vector3{}
var PlaceRotation:rotation = rotation{}
if (FortChar := Agent.GetFortCharacter[]):
# Get the start of the line
LineStart := FortChar.GetViewLocation()
# Get the end of the line
ViewRotation := FortChar.GetViewRotation()
ForwardVector := ViewRotation.GetLocalForward()
LineEnd := ForwardVector * 500.0 + LineStart # Make the unit vector longer and make it start at the linestart instead of the root
# Get the location to place the tower by making the Z:=0.0
set PlaceLocation = vector3{X:=LineEnd.X, Y:=LineEnd.Y, Z:=0.0}
# Get the rotation to place the tower by making the pitch:=0.0
if (Yaw := ViewRotation.GetYawPitchRollDegrees()[0]):
set PlaceRotation = MakeRotationFromYawPitchRollDegrees(Yaw, 0.0, 0.0)
return transform{Translation:=PlaceLocation, Rotation:=PlaceRotation}
SpawnAndMovePlaceholderTower(Agent:agent)<suspends>:void =
# Make sure when the input is pressed for the second time to stop the loop, it doesn't restart the function
if (SpawnedPlaceholder = false):
set SpawnedPlaceholder = true
InitialRayCastResult := DrawDebugLine(Agent) # make a kind of raycast by just getting the localforward
SpawnedProp := SpawnProp(PlaceholderAsset, InitialRayCastResult) # spawn the prop
if (PlaceholderProp := SpawnedProp(0)?): # get the cprop
race: # race expression to stop the loop when the input is pressed again
loop:
# Time to move and interpolation value (alpha)
TimeToMove := 0.025 # duration of moveto
alpha := 0.5 # linear interpolation value
# Get the target location and rotation by the ray cast result
RayCastResult := DrawDebugLine(Agent)
CurrentPosition := PlaceholderProp.GetTransform().Translation
TargetPosition := RayCastResult.Translation
InterpolatedPosition := Lerp(CurrentPosition, TargetPosition, alpha) # create
TargetRotation := RayCastResult.Rotation
PlaceholderProp.MoveTo(InterpolatedPosition, TargetRotation, TimeToMove)
InputTrigger.PressedEvent.Await()