79 lines
2.2 KiB
Lua
79 lines
2.2 KiB
Lua
|
|
local FVector = import "Vector"
|
||
|
|
local FVector2D = import "Vector2D"
|
||
|
|
local Reactive = require "Core.Reactive"
|
||
|
|
local BusyActorManagerSubSystem = import("BusyActorManagerSubSystem")
|
||
|
|
|
||
|
|
|
||
|
|
local Movement = {
|
||
|
|
proxy = {},
|
||
|
|
}
|
||
|
|
|
||
|
|
function Movement:ReceiveComponentBeginPlay()
|
||
|
|
self.proxy = Reactive.ReactiveProperty({
|
||
|
|
isIdle = true,
|
||
|
|
direction = {X = 0, Y = 0},
|
||
|
|
destination = {X = 0, Y = 0}
|
||
|
|
})
|
||
|
|
end
|
||
|
|
|
||
|
|
function Movement:ReceiveComponentTick(delta_time)
|
||
|
|
local proxy = self.proxy
|
||
|
|
if proxy.isIdle then return end
|
||
|
|
local new_pos = FVector()
|
||
|
|
local owner = self:GetOwner()
|
||
|
|
local curr_pos = owner:K2_GetActorLocation()
|
||
|
|
new_pos.Z = curr_pos.Z
|
||
|
|
|
||
|
|
local move_distance = delta_time * owner:GetSpeed()
|
||
|
|
local distance_x = proxy.destination.X - curr_pos.X
|
||
|
|
local distance_y = proxy.destination.Y - curr_pos.Y
|
||
|
|
|
||
|
|
if move_distance^2 >= distance_x^2 + distance_y^2 then
|
||
|
|
proxy.isIdle = true
|
||
|
|
new_pos.X = proxy.destination.X
|
||
|
|
new_pos.Y = proxy.destination.Y
|
||
|
|
proxy.direction = FVector2D()
|
||
|
|
else
|
||
|
|
new_pos.X = curr_pos.X + proxy.direction.X * move_distance
|
||
|
|
new_pos.Y = curr_pos.Y + proxy.direction.Y * move_distance
|
||
|
|
end
|
||
|
|
owner:K2_SetActorLocation(new_pos, true, nil, false)
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
function Movement:SetDestination(x, y)
|
||
|
|
local direction = FVector2D()
|
||
|
|
local destination = FVector2D()
|
||
|
|
|
||
|
|
local owner = self:GetOwner()
|
||
|
|
local curr_pos = owner:K2_GetActorLocation()
|
||
|
|
local delta_x = x - curr_pos.X
|
||
|
|
local delta_y = y - curr_pos.Y
|
||
|
|
-- 计算方向向量
|
||
|
|
local length = math.sqrt(delta_x ^ 2 + delta_y ^ 2)
|
||
|
|
if length > 0 then
|
||
|
|
direction.X, direction.Y = delta_x / length, delta_y / length
|
||
|
|
else
|
||
|
|
direction.X, direction.Y = 0, 0
|
||
|
|
end
|
||
|
|
destination.X , destination.Y = x, y
|
||
|
|
|
||
|
|
self.proxy.isIdle = false
|
||
|
|
self.proxy.direction = direction
|
||
|
|
self.proxy.destination = destination
|
||
|
|
end
|
||
|
|
|
||
|
|
function Movement:Stop()
|
||
|
|
self.proxy.isIdle = true
|
||
|
|
end
|
||
|
|
|
||
|
|
function Movement:BackBonfire()
|
||
|
|
local sub_system = BusyActorManagerSubSystem.Get(self)
|
||
|
|
local bonfire = sub_system:GetNearestBonfire()
|
||
|
|
local position = bonfire:K2_GetActorLocation()
|
||
|
|
self:SetDestination(position.X, position.Y)
|
||
|
|
end
|
||
|
|
|
||
|
|
return Class(nil, nil, Movement)
|