Skip to content

Commit 04785b4

Browse files
committed
Added support for immediately following a target even when lerping
Fixes #25
1 parent b42b58c commit 04785b4

File tree

5 files changed

+57
-13
lines changed

5 files changed

+57
-13
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ This controls if the camera should follow the target along the horizontal axis o
5555
#### follow_vertical (boolean)
5656
This controls if the camera should follow the target along the vertical axis or not. See `camera.follow()` for details.
5757

58+
### follow_immediately (boolean)
59+
This controls if the camera should immediately position itself on the follow target when initialized or if it should apply lerp (see below). See `camera.follow()` for details.
60+
5861
#### follow_target (hash)
5962
Id of the game object to follow. See `camera.follow()` for details.
6063

@@ -235,7 +238,8 @@ Acceptable values for the `options` table:
235238
* `lerp` (number) - Lerp from current position to target position with `lerp` as t.
236239
* `offset` (vector3) - Camera offset from target position.
237240
* `horizontal` (boolean) - True if following the target along the horizontal axis.
238-
* `vertical` (vector3) - True if following the target along the vertical axis.
241+
* `vertical` (boolean) - True if following the target along the vertical axis.
242+
* `immediate` (boolean) - True if the camera should be immediately positioned on the target even when lerping.
239243

240244
### camera.unfollow(camera_id)
241245
Stop following a game object.
@@ -400,9 +404,9 @@ Message equivalent to `camera.recoil()`. Accepted message keys: `offset` and `du
400404
Message sent back to the sender of a `shake` message when the shake has completed.
401405

402406
### follow
403-
Message equivalent to `camera.follow()`. Accepted message keys: `target`, `lerp`, `horizontal` and `vertical`.
407+
Message equivalent to `camera.follow()`. Accepted message keys: `target`, `lerp`, `horizontal`, `vertical`, `immediate`.
404408

405-
msg.post("camera", "follow", { target = hash("player"), lerp = 0.7, horizontal = true, vertical = false })
409+
msg.post("camera", "follow", { target = hash("player"), lerp = 0.7, horizontal = true, vertical = false, immediate = true })
406410

407411
### unfollow
408412
Message equivalent to `camera.unfollow()`.

example/camera_controls.gui_script

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function init(self)
1616
self.deadzone_enabled = false
1717
self.current_projection = 1
1818
self.lerp = 0
19-
camera.use_projector(CAMERA_ID, PROJECTIONS[self.current_projection].id)
19+
msg.post("#", "use_projector")
2020
end
2121

2222
local function get_scaling_factor()
@@ -51,16 +51,16 @@ function update(self, dt)
5151
gui.set_text(gui.get_node("top_right"), ("%d,%d"):format(bounds.z, bounds.y))
5252
gui.set_text(gui.get_node("zoomlevel"), ("%.2f"):format(tostring(camera.get_zoom(CAMERA_ID))))
5353
gui.set_text(gui.get_node("current_projection"), PROJECTIONS[self.current_projection].name)
54+
end
5455

55-
if self.follow then
56-
msg.post(CAMERA_ID, "follow", {
57-
target = "/player",
58-
lerp = self.lerp,
59-
offset = self.camera_offset,
60-
horizontal = self.follow_horizontal,
61-
vertical = self.follow_vertical,
62-
})
63-
end
56+
local function post_follow_message(self)
57+
msg.post(CAMERA_ID, "follow", {
58+
target = "/player",
59+
lerp = self.lerp,
60+
offset = self.camera_offset,
61+
horizontal = self.follow_horizontal,
62+
vertical = self.follow_vertical,
63+
})
6464
end
6565

6666
function on_input(self, action_id, action)
@@ -76,24 +76,28 @@ function on_input(self, action_id, action)
7676
self.follow_horizontal = true
7777
self.follow_vertical = true
7878
self.lerp = 1
79+
post_follow_message(self)
7980
return true
8081
elseif gui.pick_node(gui.get_node("follow_lerp/button"), action.x, action.y) then
8182
self.follow = true
8283
self.follow_horizontal = true
8384
self.follow_vertical = true
8485
self.lerp = 0.1
86+
post_follow_message(self)
8587
return true
8688
elseif gui.pick_node(gui.get_node("follow_horizontal/button"), action.x, action.y) then
8789
self.follow = true
8890
self.follow_horizontal = true
8991
self.follow_vertical = false
9092
self.lerp = 0.1
93+
post_follow_message(self)
9194
return true
9295
elseif gui.pick_node(gui.get_node("follow_vertical/button"), action.x, action.y) then
9396
self.follow = true
9497
self.follow_horizontal = false
9598
self.follow_vertical = true
9699
self.lerp = 0.1
100+
post_follow_message(self)
97101
return true
98102
elseif gui.pick_node(gui.get_node("shake_both/button"), action.x, action.y) then
99103
msg.post(CAMERA_ID, "shake", { intensity = 0.05, duration = 0.5, direction = hash("both") })
@@ -142,6 +146,8 @@ function on_input(self, action_id, action)
142146
camera.use_projector(CAMERA_ID, PROJECTIONS[self.current_projection].id)
143147
return true
144148
end
149+
elseif message_id == hash("use_projector") then
150+
camera.use_projector(CAMERA_ID, PROJECTIONS[self.current_projection].id)
145151
end
146152
end
147153

example/example.collection

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ instances {
3030
value: "true"
3131
type: PROPERTY_TYPE_BOOLEAN
3232
}
33+
properties {
34+
id: "follow"
35+
value: "true"
36+
type: PROPERTY_TYPE_BOOLEAN
37+
}
38+
properties {
39+
id: "follow_immediately"
40+
value: "true"
41+
type: PROPERTY_TYPE_BOOLEAN
42+
}
43+
properties {
44+
id: "follow_target"
45+
value: "/player"
46+
type: PROPERTY_TYPE_HASH
47+
}
3348
}
3449
scale3 {
3550
x: 1.0

orthographic/camera.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ end
367367
-- offset - Offset from target position (default: nil)
368368
-- horizontal - true if following target along horizontal axis (default: true)
369369
-- vertical - true if following target along vertical axis (default: true)
370+
-- immediate - true if camera should be immediately positioned on the target
370371
function M.follow(camera_id, target, options, __offset)
371372
assert(camera_id, "You must provide a camera id")
372373
assert(target, "You must provide a target")
@@ -376,11 +377,13 @@ function M.follow(camera_id, target, options, __offset)
376377
local offset = nil
377378
local vertical = true
378379
local horizontal = true
380+
local immediate = false
379381
if type(options) == "table" then
380382
lerp = options.lerp
381383
offset = options.offset
382384
horizontal = options.horizontal
383385
vertical = options.vertical
386+
immediate = options.immediate
384387
else
385388
lerp = options
386389
offset = __offset
@@ -392,6 +395,7 @@ function M.follow(camera_id, target, options, __offset)
392395
offset = offset,
393396
horizontal = horizontal,
394397
vertical = vertical,
398+
immediate = immediate,
395399
})
396400
end
397401

orthographic/camera.script

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ go.property("offset_gui", false)
99
go.property("follow", false)
1010
go.property("follow_horizontal", true)
1111
go.property("follow_vertical", true)
12+
go.property("follow_immediately", false)
1213
go.property("follow_target", hash(""))
1314
go.property("follow_lerp", 0.5)
1415
go.property("follow_offset", vmath.vector3(0, 0, 0))
@@ -40,11 +41,21 @@ local UPDATE_CAMERA = hash("update_camera")
4041
local ZOOM_TO = hash("zoom_to")
4142
local USE_PROJECTION = hash("use_projection")
4243

44+
local function position_on_follow(self)
45+
local target_position = go.get_position(self.follow_target)
46+
local camera_position = go.get_position()
47+
target_position.z = camera_position.z
48+
go.set_position(target_position)
49+
end
50+
4351
function init(self)
4452
camera.init(go.get_id(), msg.url(), { zoom = self.zoom })
4553
if self.enabled then
4654
camera.update(go.get_id(), 0)
4755
camera.send_view_projection(go.get_id())
56+
if self.follow and self.follow_immediately then
57+
position_on_follow(self)
58+
end
4859
end
4960
end
5061

@@ -89,6 +100,10 @@ function on_message(self, message_id, message, sender)
89100
self.follow_target = type(message.target) == "string" and hash(message.target) or message.target
90101
self.follow_lerp = message.lerp or 1
91102
self.follow_offset = message.offset or vmath.vector3()
103+
self.follow_immediately = message.immediate
104+
if self.follow and self.follow_immediately then
105+
position_on_follow(self)
106+
end
92107
elseif message_id == DEADZONE then
93108
self.deadzone_right = message.right or 0
94109
self.deadzone_top = message.top or 0

0 commit comments

Comments
 (0)