初始化提交
This commit is contained in:
		
							
								
								
									
										68
									
								
								Content/Lua/GamePlay/BusyRole/Animation.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								Content/Lua/GamePlay/BusyRole/Animation.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| local Animation = {} | ||||
| local ERoleState = import("EBusyRoleState") | ||||
| local ERoleMoveDirection = import("ERoleMoveDirection") | ||||
| local Reactive = require("Core.Reactive") | ||||
|  | ||||
|  | ||||
| local direction_mapping = { | ||||
|     [0] = ERoleMoveDirection.Move_Right, | ||||
|     [1] = ERoleMoveDirection.Move_Left, | ||||
| } | ||||
|  | ||||
|  | ||||
| local function GetAnimationIndex(direction, N) | ||||
|     -- 使用自定义 atan2 计算角度 | ||||
|     local angle = math.atan(direction.Y, direction.X) | ||||
|     -- 转换为 [0, 2π) 范围 | ||||
|     if angle < 0 then angle = angle + 2 * math.pi end | ||||
|  | ||||
|     -- 调整角度:使 Y 轴负方向 (0,-1) 成为 0°(第一份的中心) | ||||
|     local adjusted_angle = (angle  + math.pi / N) % (2 * math.pi) | ||||
|     -- local adjusted_angle = (angle + math.pi / 2 + math.pi / N) % (2 * math.pi) | ||||
|  | ||||
|     -- 计算每份的角度大小 | ||||
|     local theta = 2 * math.pi / N | ||||
|     -- -- 计算所属区间的索引(1-based) | ||||
|     local index = math.floor(adjusted_angle / theta) | ||||
|     -- 处理边界情况(adjusted_angle = 2π 时归到第 1 份) | ||||
|     if index > N then index = 0 end | ||||
|     return index | ||||
| end | ||||
|  | ||||
| function Animation:ReceiveLuaBeginPlay() | ||||
|     self.prev_direction = nil | ||||
|     self.watcher = Reactive.Watcher(function() self:UpdateMoveAnimation() end) | ||||
| end | ||||
|  | ||||
| function Animation:UpdateMoveAnimation() | ||||
|     local owner = self:GetOwner() | ||||
|     local movement_proxy = owner.Movement.proxy | ||||
|  | ||||
|     local index = 0 | ||||
|  | ||||
|     if owner.proxy.state == ERoleState.Picking then | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     if movement_proxy.isIdle then | ||||
|         if self.prev_direction ~= nil then | ||||
|             index = GetAnimationIndex(self.prev_direction, ERoleMoveDirection.Move_All_Cnt) | ||||
|         end | ||||
|         self:SetIdleAnimation(direction_mapping[index]) | ||||
|     else | ||||
|         local direction = movement_proxy.direction | ||||
|         if direction.X ~= 0 and direction.Y ~= 0 then | ||||
|             index = GetAnimationIndex(direction, ERoleMoveDirection.Move_All_Cnt) | ||||
|         end | ||||
|         self:SetMoveAnimation(direction_mapping[index]) | ||||
|         self.prev_direction = {X = direction.X, Y = direction.Y} | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Animation:GetMoveDirection() | ||||
|     local index = GetAnimationIndex(self.prev_direction, ERoleMoveDirection.Move_All_Cnt) | ||||
|     return direction_mapping[index] | ||||
| end | ||||
|  | ||||
|  | ||||
| return Class(nil, nil, Animation) | ||||
							
								
								
									
										78
									
								
								Content/Lua/GamePlay/BusyRole/Movement.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								Content/Lua/GamePlay/BusyRole/Movement.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | ||||
| 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) | ||||
		Reference in New Issue
	
	Block a user