--- 角色对象 local XSceneObject = require("XHome/XSceneObject") local XHomeCharObj = XClass(XSceneObject, "XHomeCharObj") --设置数据 function XHomeCharObj:SetData(data, isSelf) self.CharData = data self.IsSelf = isSelf self.Id = data.CharacterId self.CeilSize = XHomeDormManager.GetCeilSize() end --进入房间设置出生点 function XHomeCharObj:Born(map, room) self.Map = map self.Room = room self:ReSetPosition() self.Agent:SetVarDicByKey("DormitoryId", self.CharData.DormitoryId) self.NavMeshAgent.IsObstacle = true self:ChangeStatus(XHomeBehaviorStatus.IDLE) self:ChangeStateMachine(XHomeCharFSMType.IDLE) self.GameObject:SetActive(true) self.Visible = true end --事件改变 function XHomeCharObj:OnEventChange(event) if XHomeBehaviorStatus.IDLE ~= self.Status then return end self:ChangeStatus(event.BehaviorId) end --退出房间 function XHomeCharObj:ExitRoom() self:DisInteractFurniture() self:DisPreInteractFurniture() XHomeCharManager.DespawnHomeCharacter(self.Id, self) end function XHomeCharObj:Recycle() XHomeCharManager.DespawnHomeCharacter(self.CharData.CharacterId, self) end --加载完成 function XHomeCharObj:OnLoadComplete() --行为代理 self.Agent = self.GameObject:GetComponent(typeof(CS.BehaviorTree.XAgent)) if XTool.UObjIsNil(self.Agent) then self.Agent = self.GameObject:AddComponent(typeof(CS.BehaviorTree.XAgent)) self.Agent.ProxyType = "HomeCharacter" self.Agent:InitProxy() end self.Agent.Proxy.LuaAgentProxy:SetHomeCharObj(self) self.Animator = self.GameObject:GetComponent(typeof(CS.UnityEngine.Animator)) self.DormPutOnAnimaTime = CS.XGame.ClientConfig:GetFloat("DormPutOnAnimaTime") self.IsPressing = false self.FondleType = 0 --寻路组件 -- self.NavMeshAgent = CS.XNavMeshUtility.AddNavMeshAgent(self.GameObject) -- self.NavMeshAgent.radius = 0.35 self.NavMeshAgent = CS.XNavMeshUtility.AddMoveAgent(self.GameObject) self.NavMeshAgent.Radius = 0.35 self.NavMeshAgent.IsObstacle = true self.GoInputHandler = self.GameObject:GetComponent(typeof(CS.XGoInputHandler)) if XTool.UObjIsNil(self.GoInputHandler) then self.GoInputHandler = self.GameObject:AddComponent(typeof(CS.XGoInputHandler)) end --层级 self.GameObject:SetLayerRecursively(CS.UnityEngine.LayerMask.NameToLayer(HomeSceneLayerMask.HomeCharacter)) --阴影 CS.XMaterialContainerHelper.ProcessCharacterShadowVolume(self.GameObject) if not XTool.UObjIsNil(self.GoInputHandler) then self.GoInputHandler:AddPointerClickListener(function(eventData) self:OnClick(eventData) end) self.GoInputHandler:AddDragListener(function(eventData) self:OnDrag(eventData) end) self.GoInputHandler:AddPointerDownListener(function(eventData) self:OnPointerDown(eventData) end) self.GoInputHandler:AddPressListener(function(pressTime) self:OnPress(pressTime) end) self.GoInputHandler:AddPointerUpListener(function(eventData) self:OnPointerUp(eventData) end) self.GoInputHandler:AddPointerExitListener(function(eventData) self:OnPointerExit(eventData) end) end end ----------------------------------------------------------- --获取属性 function XHomeCharObj:GetAtrributeValue(attributeKey) return self.CharData[attributeKey] end --播放动作 function XHomeCharObj:DoAction(actionId, needFadeCross, crossDuration) if (needFadeCross) then self.Animator:CrossFade(actionId, crossDuration, -1, 0) else self.Animator:Play(actionId, -1, 0) end end --显示气泡 function XHomeCharObj:ShowBubble(id, callBack) XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_SHOW_DIALOBOX, self.Id, id, self.Transform, function() if callBack then callBack() end end) end --显示气泡 function XHomeCharObj:ShowRandomBubble(callBack) local config = XDormConfig.GetCharacterDialog(self.CharData, self.Status) if not config then if callBack then callBack() end return end XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_SHOW_DIALOBOX, self.Id, config.Id, self.Transform, function() if callBack then callBack() end end) end --隐藏气泡 function XHomeCharObj:HideBubble() XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_HIDE_DIALOBOX, self.Id) end --随机寻路 function XHomeCharObj:DoPathFind(minDistance, maxDistance) local findPath = false local x = self.Pos.x local y = self.Pos.y local distance self.Pos = XHomeDormManager.WorldPosToGroundGridPos(self.Transform.position, self.Room.Transform) local findCount = 0 while (not findPath) do math.randomseed(os.time()) distance = math.random(minDistance, maxDistance) local vec = CS.UnityEngine.Random.insideUnitCircle x = math.floor(0.5 + distance * vec.x + self.Pos.x) y = math.floor(0.5 + distance * vec.y + self.Pos.y) if x > 1 and x < CS.XHomeMapManager.Inst.MapSize.x - 2 and y > 1 and y < CS.XHomeMapManager.Inst.MapSize.y - 2 then local gridInfo = self.Map:GetGridInfo(x, y) --local gridMask = CS.XRoomMapInfo.GetMapGridMask(gridInfo, CS.XRoomBlockType.Blocked, CS.XRoomBlockType.Furniture, CS.XRoomBlockType.Interaction) if gridInfo <= 0 then findPath = true end end findCount = findCount + 1 if findCount >= 10000 then return self.Agent:SetVarDicByKey("Destination", XHomeDormManager.GetLocalPosByGrid(self.Pos.x, self.Pos.y, CS.XHomePlatType.Ground, 0)) end end self.Pos.x = x self.Pos.y = y local pos = XHomeDormManager.GetLocalPosByGrid(x, y, CS.XHomePlatType.Ground, 0) pos = self.Room.Transform.localToWorldMatrix:MultiplyPoint(pos) self.Agent:SetVarDicByKey("Destination", pos) end --改变状态机 function XHomeCharObj:ChangeStateMachine(stateM) if self.StateMachine and self.StateMachine.name == stateM then return end if self.StateMachine then self.StateMachine:Exit() end self.StateMachine = XHomeCharFSMFactory.New(stateM, self) self.StateMachine:Enter() self.StateMachine:Execute() end --改变状态 function XHomeCharObj:ChangeStatus(state) if self.Status == state and self.Status ~= XHomeBehaviorStatus.IDLE then return end self.FondleTypeList = {} --隐藏特效 self:HideEffect() --隐藏气泡 self:HideBubble() --检测事件 local event = XHomeCharManager.GetCharacterEvent(self.CharData.CharacterId, self.IsSelf) if event and XHomeBehaviorStatus.IDLE == state then state = event.BehaviorId end self.Status = state local temp = XDormConfig.GetCharacterBehavior(self.Id, state) if not temp then XLog.Error("获取角色行为树失败,角色id=".. tostring(self.Id) .. ", state=" .. tostring(state)) return end local behaviorTreeId = temp.BehaviorId self.CanClick = temp.CanClick == 1 --切换状态机 self:ChangeStateMachine(temp.StateMachine) XLuaBehaviorManager.PlayId(behaviorTreeId, self.Agent) CsXGameEventManager.Instance:Notify(XEventId.EVENT_HOME_CHARACTER_STATUS_CHANGE, self.Id) end --播放特效 function XHomeCharObj:PlayEffect(effectId, bindWorldPos) XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_SHOW_3DIOBJ, self.Id, effectId, self.Transform, bindWorldPos) end --隐藏特效 function XHomeCharObj:HideEffect() XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_HIDE_3DIOBJ, self.Id) end --设置是否阻挡 function XHomeCharObj:SetObstackeEnable(obstackeEnable) self.NavMeshAgent.IsObstacle = obstackeEnable end --播放事件奖励 function XHomeCharObj:ShowEventReward() XHomeCharManager.ShowEventReward(self.Id) end --获取状态 function XHomeCharObj:GetState() return self.Status end --检测附近的人物交互 function XHomeCharObj:CheckCharacterInteracter() local result = XHomeCharManager.CheckCharacterInteracter(self.Id) return result end --检测附近的家具交互点 function XHomeCharObj:CheckFurnitureInteract() local result, dest, interact = XHomeCharManager.CheckFurnitureInteract(self.Id) if result then self.Agent:SetVarDicByKey("Destination", dest) self.Furniture = interact.Furniture self.InteractInfo = interact for _, v in ipairs(self.Furniture.InteractInfoList) do if v.GridPos.x == self.InteractInfo.GridPos.x and v.GridPos.y == self.InteractInfo.GridPos.y then local haveBehavior = false local relation = XDormConfig.GetDormF2CBehaviorRelative(self.Furniture.Cfg.Id, self.Id, v.PosIndex) if relation then haveBehavior = true else local state = XDormConfig.GetCharacterBehavior(self.Id, v.AttractBehaviorType) haveBehavior = state ~= nil end if haveBehavior then local state = self:GetInteractInfoAttractBehavior(v) v.UsedType = v.UsedType | XFurnitureInteractUsedType.Character v.CharacterId = self.Id self:ChangeStatus(state) end break end end end return result end --检测任务完成 function XHomeCharObj:CheckEventCompleted(completeType, callBack) local temp = XHomeCharManager.CheckCharacterEventCompleted(self.Id, completeType, self.IsSelf) if not temp then return false end XDataCenter.DormManager.RequestDormitoryCharacterOperate(self.Id, self.CharData.DormitoryId, temp.EventId, 1, callBack) return true end --检测任务存在 function XHomeCharObj:CheckEventExist(eventId) return XHomeCharManager.CheckCharacterEventExist(self.Id, eventId, self.IsSelf) end --检测是否正在播放指定动画 function XHomeCharObj:CheckIsPlayingAnimation(animationName) if not animationName or #animationName <= 0 then return false end local curStateInfo = self.Animator:GetCurrentAnimatorStateInfo(0) local nextStateInfo = self.Animator:GetNextAnimatorStateInfo(0) for _, v in ipairs(animationName) do local newHash = CS.UnityEngine.Animator.StringToHash(v) if (curStateInfo.shortNameHash == newHash or nextStateInfo.shortNameHash == newHash) then return true end end return false end --侧身摄像机 function XHomeCharObj:SidewaysSceneCamera() local currentCamera = XHomeSceneManager.GetSceneCamera() local direction = currentCamera.transform.position - self.Transform.position local Direct = CS.UnityEngine.Vector3(direction.z, 0, -direction.x); self.Transform.rotation = CS.UnityEngine.Quaternion.LookRotation(Direct, CS.UnityEngine.Vector3.up); end --面向摄像机 function XHomeCharObj:FaceToSceneCamera() local currentCamera = XHomeSceneManager.GetSceneCamera() local direction = currentCamera.transform.position - self.Transform.position local Direct = CS.UnityEngine.Vector3(direction.x, 0, direction.z); self.Transform.rotation = CS.UnityEngine.Quaternion.LookRotation(Direct, CS.UnityEngine.Vector3.up); end function XHomeCharObj:Dispose() if not XTool.UObjIsNil(self.GoInputHandler) then self.GoInputHandler:RemoveAllListeners() end self.GoInputHandler = nil self:HideBubble() self:HideEffect() XHomeCharObj.Super.Dispose(self) end function XHomeCharObj:OnDrag(eventData) if not self.IsSelf then return end if self.Status ~= XHomeBehaviorStatus.GRAB_UP then return end -- 托起 local currentCamera = XHomeSceneManager.GetSceneCamera() local direction = self.Transform.position - currentCamera.transform.position local z = CS.UnityEngine.Vector3.Dot(direction, currentCamera.transform.forward); local screenPos = CS.UnityEngine.Vector3(eventData.position.x, eventData.position.y, z) local pos = currentCamera:ScreenToWorldPoint(screenPos) local gridPos = XHomeDormManager.WorldPosToGroundGridPos(pos, self.Room.Transform) --判断拖拽越界 if gridPos.x <= 0 or gridPos.y <= 0 or gridPos.x >= XHomeDormManager.GetMapWidth() - 1 or gridPos.y >= XHomeDormManager.GetMapHeight() - 1 then return end self.Transform.position = CS.UnityEngine.Vector3(pos.x, self.OrignalPosition.y + 0.5, pos.z) --判断射线碰到家私 local layerMask = CS.UnityEngine.LayerMask.GetMask("Device") if layerMask then local hit = self.Transform:PhysicsRayCast(CS.UnityEngine.Vector3.up * 100, CS.UnityEngine.Vector3.down, layerMask) if not XTool.UObjIsNil(hit) then local obj = XSceneEntityManager.GetEntity(hit.gameObject) if self.PreInteractFurniture ~= nil and (obj == nil or obj.Data.Id ~= self.PreInteractFurniture.Data.Id) then self.PreInteractFurniture:RayCastSelected(false) self.IsRayCastFurniture = false end if obj then local interactInfo = obj:GetAvailableInteract(self.CharData.CharacterId) if interactInfo then self.PreInteractFurniture = obj self.PreInteractFurniture:RayCastSelected(true) self.IsRayCastFurniture = true else if self.PreInteractFurniture then self.PreInteractFurniture:RayCastSelected(false) end self.IsRayCastFurniture = false self.PreInteractFurniture = nil end end else if self.PreInteractFurniture ~= nil then self.PreInteractFurniture:RayCastSelected(false) self.PreInteractFurniture = nil self.IsRayCastFurniture = false end end end end --长按 function XHomeCharObj:OnPress(pressTime) if not self.IsSelf then return end if self.Status ~= XHomeBehaviorStatus.GRAB_UP then if not self.IsPressing then XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_PUT_ON, self.Id, self.Transform, true) self.IsPressing = true elseif pressTime >= self.DormPutOnAnimaTime then self:SidewaysSceneCamera() self.OrignalPosition = self.Transform.position self.Transform.position = CS.UnityEngine.Vector3(self.OrignalPosition.x, self.OrignalPosition.y + 0.5, self.OrignalPosition.z) self:ChangeStatus(XHomeBehaviorStatus.GRAB_UP) self:HideBubble() XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_CATCH) self.NavMeshAgent.IsObstacle = false self.IsPressing = false end end end --点击:会直接被外部调用,不会传eventData function XHomeCharObj:OnClick(eventData) if not self.IsSelf then return end if eventData then self.Agent:SetVarDicByKey("BindWorldPos", eventData.pointerCurrentRaycast.worldPosition) end if self.CanClick then local currentCamera = XHomeSceneManager.GetSceneCamera() local direction = currentCamera.transform.position - self.Transform.position direction.y = 0 local eulerAngle = CS.UnityEngine.Quaternion.LookRotation(direction).eulerAngles self.Agent:SetVarDicByKey("TurnTo", eulerAngle) XHomeCharManager.SetSelectCharacter(self) self:ChangeStatus(XHomeBehaviorStatus.SELECTED) self:HideBubble() XEventManager.DispatchEvent(XEventId.EVENT_DORM_EXP_DETAIL_SHOW, self.Id, self.Transform) end CsXGameEventManager.Instance:Notify(XEventId.EVENT_DORM_CHARACTER_CLICK_SUCCESS, self.Id) end --手指压下 function XHomeCharObj:OnPointerDown() if not self.IsSelf then return end if self.CanClick then self:HideBubble() local currentCamera = XHomeSceneManager.GetSceneCamera() local direction = currentCamera.transform.position - self.Transform.position direction.y = 0 local eulerAngle = CS.UnityEngine.Quaternion.LookRotation(direction).eulerAngles self.Agent:SetVarDicByKey("TurnTo", eulerAngle) self:ChangeStatus(XHomeBehaviorStatus.WAIT) end end --手指松开 function XHomeCharObj:OnPointerUp() if not self.IsSelf then return end if self.Status == XHomeBehaviorStatus.GRAB_UP or self.IsPressing then XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_PUT_DOWN) end if self.Status == XHomeBehaviorStatus.GRAB_UP then self:FaceToSceneCamera() if not self.PreInteractFurniture then self.NavMeshAgent.IsObstacle = true CsXGameEventManager.Instance:Notify(XEventId.EVENT_DORM_CHARACTER_POINTER_UP_SUCCESS, self.Id) else self.NavMeshAgent.IsObstacle = false local interactInfo = self.PreInteractFurniture:GetNearAvailableInteract(self.Transform.position, self.CharData.CharacterId) if not interactInfo then self.PreInteractFurniture:RayCastSelected(false) self.IsRayCastFurniture = false self.PreInteractFurniture = nil self.NavMeshAgent.IsObstacle = true CsXGameEventManager.Instance:Notify(XEventId.EVENT_DORM_CHARACTER_POINTER_UP_SUCCESS, self.Id) return end self.PreInteractFurniture:RayCastSelected(false) self.IsRayCastFurniture = false self.Transform.eulerAngles = interactInfo.StayPos.transform.eulerAngles self.Furniture = self.PreInteractFurniture self.InteractInfo = interactInfo local state = self:GetInteractInfoBehavior(interactInfo) self.Transform.position = CS.UnityEngine.Vector3(interactInfo.StayPos.transform.position.x, self.OrignalPosition.y, interactInfo.StayPos.transform.position.z) self:ChangeStatus(state) end end self.PreInteractFurniture = nil if self.IsPressing then self.IsPressing = false end end function XHomeCharObj:GetInteractInfoBehavior(info) local relation = XDormConfig.GetDormF2CBehaviorRelative(self.Furniture.Cfg.Id, self.Id, info.PosIndex) if relation and relation.BehaviorWeight then local totalweight = 0 for _, weight in pairs(relation.BehaviorWeight) do totalweight = totalweight + weight end math.randomseed(os.time()) local random = math.random(0, totalweight) local countWeight = 0 for index, weight in pairs(relation.BehaviorWeight) do countWeight = countWeight + weight if random <= countWeight then return relation.Behavior[index] end end end return info.BehaviorType end function XHomeCharObj:GetInteractInfoAttractBehavior(info) local relation = XDormConfig.GetDormF2CBehaviorRelative(self.Furniture.Cfg.Id, self.Id, info.PosIndex) if relation and relation.AttractBehaviorWeight then local totalweight = 0 for _, weight in pairs(relation.AttractBehaviorWeight) do totalweight = totalweight + weight end math.randomseed(os.time()) local random = math.random(0, totalweight) local countWeight = 0 for index, weight in pairs(relation.AttractBehaviorWeight) do countWeight = countWeight + weight if random <= countWeight then return relation.AttractBehavior[index] end end end return info.AttractBehaviorType end --手指退出 function XHomeCharObj:OnPointerExit() if not self.IsSelf then return end if self.IsPressing then XEventManager.DispatchEvent(XEventId.EVENT_CHARACTER_EXIT) self.IsPressing = false end end --关联家具 function XHomeCharObj:InteractFurniture() if self.Furniture == nil or not self.InteractInfo then return false end for _, v in ipairs(self.Furniture.InteractInfoList) do if v.GridPos.x == self.InteractInfo.GridPos.x and v.GridPos.y == self.InteractInfo.GridPos.y then v.UsedType = v.UsedType | XFurnitureInteractUsedType.Character v.CharacterId = self.Id break end end return true end -- 播放关联家具动画 function XHomeCharObj:PlayInteractFurnitureAnimation() if self.Furniture == nil or not self.InteractInfo then return false end self.Furniture:PlayInteractAnimation(self.Id) return true end --到达家具交互 function XHomeCharObj:ReachFurniture() if self.Furniture == nil then self:ChangeStatus(XHomeBehaviorStatus.IDLE) return false end for _, v in ipairs(self.Furniture.InteractInfoList) do local state = self:GetInteractInfoBehavior(v) if XDormConfig.GetCharacterBehavior(self.Id, state) then self:ChangeStatus(state) return true end end return false end --取消家具预关联 function XHomeCharObj:DisPreInteractFurniture() if self.PreInteractFurniture == nil then return false end for _, v in ipairs(self.PreInteractFurniture.InteractInfoList) do if v.CharacterId == self.Id and (v.UsedType & XFurnitureInteractUsedType.Character) > 0 then XHomeCharManager.SetFurnitureInteractTime(self.Id) v.UsedType = v.UsedType - XFurnitureInteractUsedType.Character v.CharacterId = nil break end end return true end --取消家具关联 function XHomeCharObj:DisInteractFurniture() if self.Furniture == nil then return false end for _, v in ipairs(self.Furniture.InteractInfoList) do if v.CharacterId == self.Id and (v.UsedType & XFurnitureInteractUsedType.Character) > 0 then XHomeCharManager.SetFurnitureInteractTime(self.Id) v.UsedType = v.UsedType - XFurnitureInteractUsedType.Character v.CharacterId = nil break end end self.Furniture = nil self.InteractInfo = nil return true end --检测是否可以取消家具关联 function XHomeCharObj:CheckDisInteractFurniture() if self.Furniture == nil then return false end for _, v in ipairs(self.Furniture.InteractInfoList) do if v.CharacterId == self.Id and (v.UsedType & XFurnitureInteractUsedType.Character) > 0 then local canReach = CS.XNavMeshUtility.CheckCanReachNavMeshSamplePosition(v.InteractPos.transform.position, CS.XHomeMapManager.Inst.CeilSize * 0.75) if (v.UsedType & XFurnitureInteractUsedType.Block) > 0 or not canReach then return false else return true end end end return true end --取消选择 function XHomeCharObj:UnSelected() XHomeCharManager.SetSelectCharacter(nil) self:ChangeStatus(XHomeBehaviorStatus.IDLE) end --设置爱抚类型 function XHomeCharObj:SetFondleType(fondleType) self.FondleTypeList = self.FondleTypeList or {} local length = #self.FondleTypeList if self.FondleType == fondleType then return end if length < 2 then table.insert(self.FondleTypeList, fondleType) return end if fondleType == XHomeCharFondleType.REFUSE then return elseif self.FondleTypeList[length] <= XHomeCharFondleType.PLAY then self.FondleTypeList[length] = fondleType end end --出列 function XHomeCharObj:DequeueFondleType() if self.FondleTypeList and #self.FondleTypeList > 0 then self.FondleType = table.remove(self.FondleTypeList, 1) end if not self.FondleType then self.FondleType = 0 end end --获取爱抚类型 function XHomeCharObj:GetFondleType() if self.FondleTypeList and #self.FondleTypeList > 0 then self.FondleType = self.FondleTypeList[1] else self.FondleType = 0 end return self.FondleType end -- 重新出生点 function XHomeCharObj:ReBorn() self.GameObject:SetActive(true) self.NavMeshAgent.IsObstacle = true self:ChangeStatus(XHomeBehaviorStatus.IDLE) end -- 刷新位置 function XHomeCharObj:ReSetPosition() if self.LastInteractInfoPos then self.LastInteractInfoPos = nil end local canReachList = self.Room:GetCanReachList() local isBornPos = false local targetPos = CS.UnityEngine.Vector2.one local x = 0 local y = 0 --最大的随机次数 local limit = 30 --设置随机数种子 math.randomseed(os.time() + self.Id) while (not isBornPos and limit >= 0) do local index = math.random(1, #canReachList) x = canReachList[index].x y = canReachList[index].y local pos = XHomeDormManager.GetLocalPosByGrid(x, y, CS.XHomePlatType.Ground, 0) pos = self.Room.Transform.localToWorldMatrix:MultiplyPoint(pos) isBornPos, targetPos = CS.XNavMeshUtility.NavMeshSamplePositionByWalkable(pos) if not isBornPos then targetPos = pos end limit = limit - 1 end self.Transform.position = targetPos self.OrignalPosition = self.Transform.position self.Pos = { ["x"] = x, ["y"] = y } self.Agent:SetVarDicByKey("x", x) self.Agent:SetVarDicByKey("y", y) end -- 检查是否在交互,如果在与家具交互,构造体重置到家具交互位置 function XHomeCharObj:CheckInteractFurniture() if self.LastInteractInfoPos then self.Transform.position = CS.UnityEngine.Vector3(self.LastInteractInfoPos.x, self.LastInteractInfoPos.y, self.LastInteractInfoPos.z) self.LastInteractInfoPos = nil end end function XHomeCharObj:OnShow(isResetPosition) if self.Visible then return end if isResetPosition then self:ReSetPosition() else self:CheckInteractFurniture() end self.Visible = true self:ReBorn() end function XHomeCharObj:OnHide() if not self.Visible then return end -- 保存家具交互点信息 if self.Furniture then local info = self.Furniture:GetInteractById(self.Id) self.LastInteractInfoPos = { x = info.InteractPos.transform.position.x, y = info.InteractPos.transform.position.y, z = info.InteractPos.transform.position.z } end self:ChangeStateMachine(XHomeCharFSMType.EMPTY) self:HideBubble() self.Visible = false end --检测是否在家具上方 function XHomeCharObj:CheckRayCastFurnitureNode() return self.IsRayCastFurniture end --面向交互的构造体 function XHomeCharObj:InteractWith(charObj) local direction = charObj.Transform.position - self.Transform.position direction.y = 0 local eulerAngle = CS.UnityEngine.Quaternion.LookRotation(direction).eulerAngles self.Agent:SetVarDicByKey("TurnTo", eulerAngle) end --交互家具面向方向调整 function XHomeCharObj:SetForwardToFurniture(forward) local furniture = self.Furniture local info = self.InteractInfo if not furniture or not info then return false end local interact = furniture:GetInteract(info.GridPos.x, info.GridPos.y) local eulerAngle = interact.InteractPos.transform.eulerAngles if forward < 0 then eulerAngle = eulerAngle + CS.UnityEngine.Vector3(0, 180, 0) end self.Agent:SetVarDicByKey("TurnTo", eulerAngle) return true end --设置构造体交互开关 function XHomeCharObj:SetCharInteractTrigger(isOn) self.CharInteractTrigger = isOn end --检测构造体是否在坐标索引上 function XHomeCharObj:CheckCharInteractPosByIndex(index) if not self.Furniture or not self.Furniture.InteractInfoList then return false end for _, v in ipairs(self.Furniture.InteractInfoList) do if v.CharacterId == self.Id and (v.UsedType & XFurnitureInteractUsedType.Character) > 0 then return v.Index == index end end return false end return XHomeCharObj