-- <* -- @Author: Saber -- @Description: 经验副本主界面,动态创建的怪物模型组件 -- *> ExpHangupMonModelItem = ExpHangupMonModelItem or BaseClass(BaseItem) local ExpHangupMonModelItem = ExpHangupMonModelItem local Status = Status function ExpHangupMonModelItem:__init(parent_wnd,prefab_asset,layer_name) self.base_file = "expDun" self.layout_file = "ExpHangupMonModelItem" self.parent_wnd = parent_wnd self.layer_name = layer_name self.pos_origin = Vector2(250, -25) -- 怪物模型坐标原点 self.first_loaded = true -- 首次加载,如果处在第二阶段首次加载要随机血量,并且需要加载一次模型 self.hp_node_changed = false -- 在动画开始的时候需要将血条外置并置于最底层,避免覆盖 self.is_dead = false -- 该怪物是否已经死亡 self.mon_ran_pos = ExpDunAnimConst.MonRamPos self.model = ExpDunModel:getInstance() self:Load() end function ExpHangupMonModelItem:Load_callback() local nodes = { "mon_con:obj", "hp_bg:obj", -- 血条表现相关 "hp_bg/fill:img", -- 爆炸效果节点 "explode_effect:obj", -- 经验特效节点 "exp_effect:obj", -- 击中效果 "hit_effect:obj", } self:GetChildren(nodes) --微调位置 SetAnchoredPositionY(self.hit_effect, 40) self:AddEvents() self:InitNodeEffects() if self.need_refreshData then self:UpdateView() end end function ExpHangupMonModelItem:AddEvents( ) end -- 预先加载特效资源,后面就不需要重复获取了 function ExpHangupMonModelItem:InitNodeEffects( ) -- 爆炸特效 local function explode_load_callback() -- 加载完成后马上隐藏节点 self.explode_effect_obj:SetActive(false) end self:AddUIEffect("guajibaozha", self.explode_effect, self.layer_name, Vector2(0,0), nil, false, -1, nil, nil, explode_load_callback) -- 经验飘字特效 local function exp_load_callback() self.exp_effect_obj:SetActive(false) end self:AddUIEffect("guajiexp", self.exp_effect, self.layer_name, Vector2(0,0), nil, false, -1, nil, nil, exp_load_callback) -- 受击特效 local function hit_load_callback() self:PlayOrStopHitEffect(false) end self:AddUIEffect("effect_fangzhi_shouji", self.hit_effect, self.layer_name, Vector2(0,10), nil, true, -1, nil, nil, hit_load_callback) end function ExpHangupMonModelItem:UpdateView( ) if self.stage then if self.first_loaded then self:ChangeHpParentNode() if self.stage ~= 1 then self:UpdateMonModel() end end if self.stage == 1 then -- 玩家飞行阶段,这个时候怪物从远处飘过来集合(需要利用蒙版,所以要控制的是怪物模型里面的位置而不是本节点位置) self:UpdateStageOne() elseif self.stage == 2 then -- 战斗阶段,这个时候要接收怪物战斗表现和血条掉落表现 if self.stage_data and self.stage_data.cur_hp then -- 初始化血量 self.mon_hp = self.stage_data.cur_hp end self.mon_pos_origin = self.transform.anchoredPosition self:StartMonAutoMove() elseif self.stage == 3 then -- 将模型节点移出屏幕(如果怪物2阶段先被打倒也会处理这个阶段) self:StopMonAutoAmin() end -- 关闭首次加载 self.first_loaded = false end end -- 设置怪物死亡后的奖励动画位置 function ExpHangupMonModelItem:SetRewardAnimCallback(index, reward_anim_callback) self.index = index self.reward_anim_callback = reward_anim_callback self.transform.name = "ExpHangupMonModelItem_" .. self.index end -- 将血条的节点放在item外,避免出现模型盖住的问题 function ExpHangupMonModelItem:SetHpParentNode(parent_node) self.hp_parent_node = parent_node or self.hp_parent_node self:ChangeHpParentNode() end function ExpHangupMonModelItem:ChangeHpParentNode() if not self.hp_node_changed and self.hp_parent_node then self.hp_bg:SetParent(self.hp_parent_node) self.hp_bg:SetAsLastSibling() self:BindHpPositionFunc() self.hp_node_changed = true end end function ExpHangupMonModelItem:BindHpPositionFunc( ) if not self.hp_position_func_id then local function hp_func() self.hp_bg.anchoredPosition = Vector2(self.transform.anchoredPosition.x, self.transform.anchoredPosition.y + 100) end self.hp_position_func_id = GlobalTimerQuest:AddPeriodQuest(hp_func, 0.02, -1) end end function ExpHangupMonModelItem:UnBindHpPositionFunc( ) if self.hp_position_func_id then GlobalTimerQuest:CancelQuest(self.hp_position_func_id) self.hp_position_func_id = nil end end -- 设置阶段参数,用来控制动画表现 function ExpHangupMonModelItem:SetData( stage, mon_id, stage_data ) self.stage = stage self.mon_id = self.mon_id or mon_id -- 父节点创建的节点数据 -- stage_data:1阶段 pos 代表本节点的最终位置和 mod_pos 动画开始的模型本身起点位置 self.stage_data = stage_data if self.is_loaded then self.need_refreshData = false self:UpdateView() else self.need_refreshData = true end end -- 加载怪物模型 function ExpHangupMonModelItem:UpdateMonModel( ) if not self.mon_con_obj.activeSelf then self.mon_con_obj:SetActive(true) end self.transform.anchoredPosition = self.pos_origin + self.stage_data.pos -- 获取目标宽度和高度,计算缩放比例,避免RT太大导致出现穿透出界面的情况 local left_max = 615 local size_x = (left_max - math.abs(self.transform.anchoredPosition.x)) * 2 local ratio_x = size_x / 1200 if not self.last_anim_mon_id or self.last_anim_mon_id ~= self.mon_id then -- 随机到不同的模型之后要重新加载模型 local res_data = { father_node = self, transform = self.mon_con, fashion_type = FuncOpenModel.TypeId.Monster, figure_id = tonumber(self.mon_id), size = Vector2(600,360), -- raycast_size = Vector2(200, 200), action_name_list = action_list, scale = 42, can_rotate = false, rotate = Vector3(0, -90, 0), position = Vector3(0, 180, 0), show_shadow = false, ui_model_type = UIModelCommon.ModelType.RT, } FuncOpenModel:getInstance():SetModelRes(res_data) self.last_anim_mon_id = self.mon_id self.mon_rt_model = lua_resM:GetPartModel(self, self.mon_con) -- print("Saber:ExpHangupMonModelItem [89] self.mon_rt_model: ",self.mon_rt_model) end end ---------- stage 1 function ExpHangupMonModelItem:UpdateStageOne( ) -- 初始化血量 self.mon_hp = 100 -- self:UpdateGetHit(0) -- 刷新血条 self.is_dead = false self:UpdateMonModel() -- 改变怪物模型坐标 local function change_mon_position(x, y, z) self.mon_rt_model = self.mon_rt_model or lua_resM:GetPartModel(self, self.mon_con) if self.mon_rt_model then self.mon_rt_model:ChangeModelLocalPosition(x, y, z) end end -- 设置位移效果 local mon_default_pos = Vector3(0, 180, 0) local mod_pos = self.stage_data.mod_pos change_mon_position(mod_pos.x, mod_pos.y) self:ClearMonModelMoveId() local cur_time = Status.NowTime local anim_time = ExpDunAnimConst.Stage1_Time local function mon_model_move() local pass_time = Status.NowTime - cur_time local progress = pass_time / anim_time if progress <= 1 then change_mon_position(mon_default_pos.x + mod_pos.x * (1-progress), mon_default_pos.y + mod_pos.y * (1-progress)) else self:ClearMonModelMoveId() end end self.mon_model_move_id = GlobalTimerQuest:AddPeriodQuest(mon_model_move, 0.02, -1) end function ExpHangupMonModelItem:ClearMonModelMoveId( ) if self.mon_model_move_id then GlobalTimerQuest:CancelQuest(self.mon_model_move_id) self.mon_model_move_id = nil end end ---------- stage 2 -- 开启怪物自动漫游的逻辑 function ExpHangupMonModelItem:StartMonAutoMove( ) if not self.mon_ram_pos_index then self.mon_ram_pos_index = math.random(1, #self.mon_ran_pos) else local new_pos = self.mon_ram_pos_index -- 保证获取一个跟上个坐标不相等的位移点 while(new_pos == self.mon_ram_pos_index) do new_pos = math.random(1, #self.mon_ran_pos) end self.mon_ram_pos_index = new_pos end local pos_cfg = self.mon_ran_pos[self.mon_ram_pos_index] local auto_pos = Vector3(self.mon_pos_origin.x + pos_cfg.pos.x, self.mon_pos_origin.y + pos_cfg.pos.y, 0) local amin_scale = Vector3(pos_cfg.scale, pos_cfg.scale, pos_cfg.scale) local call_back = function() self:StartMonAutoMove() end self:StopMonAutoAmin() self.role_model_move_anim_id = TweenLite.to(self, self.transform, TweenLite.UiAnimationType.POS, auto_pos, pos_cfg.anim_time, call_back) self.role_model_scale_anim_id = TweenLite.to(self, self.transform, TweenLite.UiAnimationType.SCALE, amin_scale, pos_cfg.anim_time) end function ExpHangupMonModelItem:StopMonAutoAmin( ) if self.role_model_move_anim_id then TweenLite.Stop(self.role_model_move_anim_id) self.role_model_move_anim_id = nil end if self.role_model_scale_anim_id then TweenLite.Stop(self.role_model_scale_anim_id) self.role_model_scale_anim_id = nil end end -- 更新受击表现 function ExpHangupMonModelItem:UpdateGetHit(damage) if not self.stage == 2 and self.mon_hp > 0 then return end if not self.hp_bg_obj.activeSelf then self.hp_bg_obj:SetActive(true) end self.mon_hp = self.mon_hp - damage self.mon_hp = self.mon_hp < 0 and 0 or self.mon_hp -- self.val_tmp.text = self.mon_hp .. "%" self.fill_img.fillAmount = self.mon_hp / 100 if self.mon_hp > 0 then self:PlayShakeEffect() self:PlayOrStopHitEffect(true) else -- 播放销毁特效,并隐藏节点 self:PlayOrStopHitEffect(false) self.mon_con_obj:SetActive(false) self.hp_bg_obj:SetActive(false) self:PlayExplodeEffectAnim() if self.reward_anim_callback and self.index then self.reward_anim_callback(self.index) end self.is_dead = true end end -- 播放受击抖动效果 function ExpHangupMonModelItem:PlayShakeEffect( ) end -- 播放爆炸效果特效 function ExpHangupMonModelItem:PlayExplodeEffectAnim( ) self:InitNodesPos() local function anim_end_fun() self.explode_effect_obj:SetActive(false) self.exp_effect_obj:SetActive(false) end self.explode_effect_obj:SetActive(true) self.exp_effect_obj:SetActive(true) local target_posx = self.explode_effect.anchoredPosition.x - 300 self:ClearExplodeAnimId() self.explode_effect_anim_id = TweenLite.to(self, self.explode_effect, TweenLite.UiAnimationType.ANCHORED_POSX, target_posx, ExpDunAnimConst.ExplodeMoveTime, anim_end_fun, TweenFunc.EASE_IN) end function ExpHangupMonModelItem:ClearExplodeAnimId( ) if self.explode_effect_anim_id then TweenLite.Stop(self.explode_effect_anim_id) self.explode_effect_anim_id = nil end end function ExpHangupMonModelItem:PlayOrStopHitEffect(play) -- self.particleSystems = self.particleSystems or self.hit_effect:GetComponentsInChildren(typeof(UnityEngine.ParticleSystem)) -- if self.particleSystems then -- for i = 0, self.particleSystems.Length - 1 do -- if play then -- self.particleSystems[i]:Play() -- else -- self.particleSystems[i]:Stop() -- end -- end -- end if play then self.hit_effect_obj:SetActive(true) else self.hit_effect_obj:SetActive(false) end end ---------- stage 3 -- 初始化各种坐标位置 function ExpHangupMonModelItem:InitNodesPos( ) self.explode_effect.anchoredPosition = Vector2(0, 0) end ---------- stage end -- 获取状态相关 function ExpHangupMonModelItem:GetIsDead( ) return self.is_dead end function ExpHangupMonModelItem:GetMonConScale( ) return self.transform.localScale.x end function ExpHangupMonModelItem:__delete( ) self:ClearMonModelMoveId() self:ClearExplodeAnimId() self:StopMonAutoAmin() self:UnBindHpPositionFunc() -- 清除模型引用 lua_resM:clearRoleMode(self) self:ClearUIEffect(self.explode_effect) self:ClearUIEffect(self.exp_effect) self:ClearUIEffect(self.hit_effect) end