PGRData/Script/matrix/xhome/xdorm/XHomeCharObj.lua

900 lines
28 KiB
Lua
Raw Normal View History

--- 角色对象
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()
-- 没有关联的家具或者没有交互点直接返回获取关联的家具是从Drag的射线判定获取
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