506 lines
No EOL
16 KiB
Lua
506 lines
No EOL
16 KiB
Lua
local XRpgMakerGamePosition = require("XEntity/XRpgMakerGame/XRpgMakerGamePosition")
|
||
|
||
local type = type
|
||
local pairs = pairs
|
||
local Vector3 = CS.UnityEngine.Vector3
|
||
local CSXScheduleManagerUnSchedule = XScheduleManager.UnSchedule
|
||
local LookRotation = CS.UnityEngine.Quaternion.LookRotation
|
||
local CSXResourceManagerLoad = CS.XResourceManager.Load
|
||
|
||
local Default = {
|
||
_Id = 0,
|
||
}
|
||
|
||
local MoveSpeed = CS.XGame.ClientConfig:GetInt("RpgMakeGameMoveSpeed")
|
||
|
||
local XRpgMakerGameObject = XClass(XRpgMakerGamePosition, "XRpgMakerGameObject")
|
||
|
||
function XRpgMakerGameObject:Ctor(id, gameObject)
|
||
for key, value in pairs(Default) do
|
||
if type(value) == "table" then
|
||
self[key] = {}
|
||
else
|
||
self[key] = value
|
||
end
|
||
end
|
||
|
||
self._Id = id
|
||
self.Animator = nil --动画控制器
|
||
self.ModelPath = nil --模型路径
|
||
self.ModelRoot = nil --模型根节点
|
||
self.ModelName = nil --模型名,作为key检索其他配置表用,可为nil
|
||
|
||
if not XTool.UObjIsNil(gameObject) then
|
||
self:SetModel(gameObject)
|
||
end
|
||
end
|
||
|
||
function XRpgMakerGameObject:Dispose()
|
||
if not XTool.UObjIsNil(self.BeAtkEffect) then
|
||
CS.UnityEngine.GameObject.Destroy(self.BeAtkEffect)
|
||
self.BeAtkEffect = nil
|
||
end
|
||
|
||
if self.BeAtkResource then
|
||
self.BeAtkResource:Release()
|
||
self.BeAtkResource = nil
|
||
end
|
||
|
||
if not XTool.UObjIsNil(self.GameObject) then
|
||
CS.UnityEngine.GameObject.Destroy(self.GameObject)
|
||
self.GameObject = nil
|
||
self.Transform = nil
|
||
end
|
||
|
||
if self.ModelResource then
|
||
self.ModelResource:Release()
|
||
self.ModelResource = nil
|
||
end
|
||
|
||
self.ModelPath = nil
|
||
end
|
||
|
||
function XRpgMakerGameObject:SetId(id)
|
||
self._Id = id
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetId()
|
||
return self._Id
|
||
end
|
||
|
||
--------------场景对象相关 begin----------------
|
||
--移动
|
||
function XRpgMakerGameObject:PlayMoveAction(action, cb)
|
||
local transform = self:GetTransform()
|
||
local startPosX = action.StartPosition.PositionX
|
||
local startPosY = action.StartPosition.PositionY
|
||
local endPosX = action.EndPosition.PositionX
|
||
local endPosY = action.EndPosition.PositionY
|
||
|
||
local startCube = self:GetCubeObj(startPosY, startPosX)
|
||
local endCube = self:GetCubeObj(endPosY, endPosX)
|
||
local startCubePosition = startCube:GetGameObjUpCenterPosition()
|
||
local endCubePosition = endCube:GetGameObjUpCenterPosition()
|
||
local cubeDistance = CS.UnityEngine.Vector3.Distance(startCubePosition, endCubePosition)
|
||
local playActionTime = cubeDistance / MoveSpeed
|
||
|
||
--计算播放音效的位置
|
||
local distance = math.sqrt(XTool.MathPow((endPosY-startPosY), 2) + XTool.MathPow((endPosX - startPosX), 2))
|
||
local playMoveSoundSpacePosition = distance > 0 and (endCubePosition - startCubePosition) / distance or Vector3(0, 0, 0)
|
||
local currPlayMoveSoundPosition = startCubePosition + playMoveSoundSpacePosition
|
||
|
||
self:SetGameObjectPosition(startCubePosition)
|
||
|
||
local moveX = endCubePosition.x - startCubePosition.x
|
||
local moveZ = endCubePosition.z - startCubePosition.z
|
||
|
||
local gameObjPositionY = transform.position.y
|
||
|
||
self:ChangeDirectionAction(action)
|
||
|
||
local modelName = self:GetModelName()
|
||
local runAnima = XRpgMakerGameConfigs.GetRpgMakerGameRunAnimaName(modelName)
|
||
self:PlayAnima(runAnima)
|
||
|
||
local movePositionX
|
||
local movePositionZ
|
||
local currPlayMoveSoundPositionX
|
||
local currPlayMoveSoundPositionZ
|
||
local tempCount = 1
|
||
self.PlayMoveActionTimer = XUiHelper.Tween(playActionTime, function(f)
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
movePositionX = startCubePosition.x + moveX * f
|
||
movePositionZ = startCubePosition.z + moveZ * f
|
||
self:SetGameObjectPosition(Vector3(movePositionX, gameObjPositionY, movePositionZ))
|
||
|
||
--保留2位小数
|
||
movePositionX = movePositionX - movePositionX % 0.01
|
||
movePositionZ = movePositionZ - movePositionZ % 0.01
|
||
currPlayMoveSoundPositionX = currPlayMoveSoundPosition.x - currPlayMoveSoundPosition.x % 0.01
|
||
currPlayMoveSoundPositionZ = currPlayMoveSoundPosition.z - currPlayMoveSoundPosition.z % 0.01
|
||
--每移动一个格子播放一次音效
|
||
if ((playMoveSoundSpacePosition.x > 0 or playMoveSoundSpacePosition.z > 0) and movePositionX >= currPlayMoveSoundPositionX and movePositionZ >= currPlayMoveSoundPositionZ)
|
||
or ((playMoveSoundSpacePosition.x < 0 or playMoveSoundSpacePosition.z < 0) and movePositionX <= currPlayMoveSoundPositionX and movePositionZ <= currPlayMoveSoundPositionZ) then
|
||
XSoundManager.PlaySoundByType(XSoundManager.UiBasicsMusic.RpgMakerGame_Move, XSoundManager.SoundType.Sound)
|
||
currPlayMoveSoundPosition = currPlayMoveSoundPosition + playMoveSoundSpacePosition
|
||
end
|
||
end, function ()
|
||
self:StopPlayMoveActionTimer()
|
||
self:PlayStandAnima(function()
|
||
if cb then
|
||
cb()
|
||
end
|
||
end)
|
||
end)
|
||
end
|
||
|
||
--isEnforceSetObjPos:是否强制设置场景对象的位置
|
||
function XRpgMakerGameObject:StopPlayMoveActionTimer(isEnforceSetObjPos)
|
||
if isEnforceSetObjPos and self.PlayMoveActionTimer then
|
||
CSXScheduleManagerUnSchedule(self.PlayMoveActionTimer)
|
||
self.PlayMoveActionTimer = nil
|
||
end
|
||
|
||
if isEnforceSetObjPos then
|
||
local x = self:GetPositionX()
|
||
local y = self:GetPositionY()
|
||
local transform = self:GetTransform()
|
||
local cube = self:GetCubeObj(y, x)
|
||
local cubePosition = cube:GetGameObjUpCenterPosition()
|
||
local gameObjPositionY = transform.position.y
|
||
self:SetGameObjectPosition(Vector3(cubePosition.x, gameObjPositionY, cubePosition.z))
|
||
end
|
||
end
|
||
|
||
--改变方向
|
||
function XRpgMakerGameObject:ChangeDirectionAction(action, cb)
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
self:SetGameObjectLookRotation(action.Direction)
|
||
|
||
if cb then
|
||
cb()
|
||
end
|
||
end
|
||
|
||
--获得对应方向的坐标
|
||
function XRpgMakerGameObject:GetDirectionPos(direction)
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
local objPosition = transform.position
|
||
local directionPos
|
||
if direction == XRpgMakerGameConfigs.RpgMakerGameMoveDirection.MoveLeft then
|
||
directionPos = objPosition + Vector3.left
|
||
elseif direction == XRpgMakerGameConfigs.RpgMakerGameMoveDirection.MoveRight then
|
||
directionPos = objPosition + Vector3.right
|
||
elseif direction == XRpgMakerGameConfigs.RpgMakerGameMoveDirection.MoveUp then
|
||
directionPos = objPosition + Vector3.forward
|
||
elseif direction == XRpgMakerGameConfigs.RpgMakerGameMoveDirection.MoveDown then
|
||
directionPos = objPosition + Vector3.back
|
||
end
|
||
return directionPos
|
||
end
|
||
|
||
--加载模型
|
||
function XRpgMakerGameObject:LoadModel(modelPath, root, modelName)
|
||
--记录旧模型位置
|
||
local oldPos = self:GetGameObjPosition()
|
||
|
||
self:Dispose()
|
||
|
||
if not modelPath then
|
||
return
|
||
end
|
||
|
||
self.ModelPath = modelPath
|
||
self.ModelRoot = root
|
||
self.ModelName = modelName
|
||
|
||
local resource = self:ResourceManagerLoad(modelPath)
|
||
if not resource then
|
||
return
|
||
end
|
||
self.ModelResource = resource
|
||
|
||
local model = CS.UnityEngine.Object.Instantiate(resource.Asset)
|
||
self:BindToRoot(model, root)
|
||
self:SetModel(model)
|
||
|
||
if oldPos then
|
||
self:SetGameObjectPosition(oldPos)
|
||
end
|
||
|
||
local meshFilter = model.transform:GetComponent("MeshFilter")
|
||
if not XTool.UObjIsNil(meshFilter) and meshFilter.mesh then
|
||
local mesh = meshFilter.mesh
|
||
--实例化出来的模型会静态合批,延迟重新设置(预制体tag改成Dynamic就好,等活动结束再删了这代码)
|
||
XScheduleManager.ScheduleOnce(function()
|
||
self:SetGameObjMesh(mesh)
|
||
end, 1)
|
||
end
|
||
end
|
||
|
||
--加载特效
|
||
function XRpgMakerGameObject:LoadEffect(asset, position, rootTransform)
|
||
local transform = rootTransform or self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
local model = CS.UnityEngine.Object.Instantiate(asset)
|
||
self:BindToRoot(model, transform)
|
||
|
||
if position then
|
||
model.transform.position = position
|
||
end
|
||
|
||
return model
|
||
end
|
||
|
||
--设置动画控制器
|
||
function XRpgMakerGameObject:SetAnimator(modelName, uiName)
|
||
local gameObject = self:GetGameObject()
|
||
if XTool.UObjIsNil(gameObject) then
|
||
return
|
||
end
|
||
|
||
--加载controller
|
||
local controllerPath = XModelManager.GetUiControllerPath(modelName)
|
||
local runtimeController = CS.LoadHelper.LoadUiController(controllerPath, uiName)
|
||
self.Animator = gameObject.transform:GetComponent("Animator")
|
||
self.Animator.runtimeAnimatorController = runtimeController
|
||
end
|
||
|
||
--播放动画
|
||
--animaName:动画名
|
||
--callBack:播放成功回调
|
||
--finishCallBack:播放动画结束后或播放失败回调
|
||
function XRpgMakerGameObject:PlayAnima(animaName, callBack, finishCallBack)
|
||
local animator = self:GetAnimator()
|
||
local gameObj = self:GetGameObject()
|
||
XModelManager.PlayAnima(gameObj, animator, animaName, nil, callBack, finishCallBack, finishCallBack)
|
||
end
|
||
|
||
function XRpgMakerGameObject:BindToRoot(model, root)
|
||
model.transform:SetParent(root)
|
||
model.transform.localPosition = CS.UnityEngine.Vector3.zero
|
||
model.transform.localEulerAngles = CS.UnityEngine.Vector3.zero
|
||
model.transform.localScale = CS.UnityEngine.Vector3.one
|
||
end
|
||
|
||
function XRpgMakerGameObject:SetModel(go)
|
||
self.GameObject = go
|
||
self.Transform = go.transform
|
||
|
||
self:OnLoadComplete()
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetGameObject()
|
||
return self.GameObject
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetTransform()
|
||
return self.Transform
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetAnimator()
|
||
return self.Animator
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetModelName()
|
||
return self.ModelName or ""
|
||
end
|
||
|
||
--设置场景对象位置
|
||
function XRpgMakerGameObject:SetGameObjectPosition(position)
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
if not position then
|
||
XLog.Error("XRpgMakerGameObject:SetGameObjectPosition设置场景对象位置错误,position为nil")
|
||
return
|
||
end
|
||
|
||
local xOffset = 0
|
||
local yOffset = 0
|
||
local zOffset = 0
|
||
local modelName = self:GetModelName()
|
||
if not string.IsNilOrEmpty(modelName) then
|
||
xOffset = XRpgMakerGameConfigs.GetRpgMakerGameXOffSet(modelName)
|
||
yOffset = XRpgMakerGameConfigs.GetRpgMakerGameYOffSet(modelName)
|
||
zOffset = XRpgMakerGameConfigs.GetRpgMakerGameZOffSet(modelName)
|
||
end
|
||
|
||
transform.position = position + Vector3(xOffset, yOffset, zOffset)
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetGameObjPosition()
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
return transform.position
|
||
end
|
||
|
||
--获得模型所在的根节点
|
||
function XRpgMakerGameObject:GetGameObjModelRoot()
|
||
return self.ModelRoot
|
||
end
|
||
|
||
--设置场景对象朝向
|
||
function XRpgMakerGameObject:SetGameObjectLookRotation(direction)
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
|
||
local objPos = self:GetGameObjPosition()
|
||
local directionPos = self:GetDirectionPos(direction)
|
||
if not objPos or not directionPos then
|
||
return
|
||
end
|
||
|
||
local lookRotation = LookRotation(directionPos - objPos)
|
||
self:SetGameObjectRotation(lookRotation)
|
||
end
|
||
|
||
--设置场景对象角度
|
||
function XRpgMakerGameObject:SetGameObjectRotation(rotation)
|
||
local transform = self:GetTransform()
|
||
if XTool.UObjIsNil(transform) then
|
||
return
|
||
end
|
||
transform.rotation = rotation
|
||
end
|
||
|
||
--获得场景对象大小
|
||
function XRpgMakerGameObject:GetGameObjSize()
|
||
local gameObject = self:GetGameObject()
|
||
if XTool.UObjIsNil(gameObject) then
|
||
return {}
|
||
end
|
||
|
||
local meshFilter = gameObject:GetComponent("MeshFilter")
|
||
return meshFilter and meshFilter.mesh.bounds.size or {}
|
||
end
|
||
|
||
function XRpgMakerGameObject:OnLoadComplete()
|
||
-- body
|
||
end
|
||
|
||
--播放攻击动画
|
||
function XRpgMakerGameObject:PlayAtkAction(cb)
|
||
local modelName = self:GetModelName()
|
||
local atkAnima = XRpgMakerGameConfigs.GetRpgMakerGameAtkAnimaName(modelName)
|
||
self:PlayAnima(atkAnima, nil, function()
|
||
self:PlayStandAnima()
|
||
if cb then
|
||
cb()
|
||
end
|
||
end)
|
||
end
|
||
|
||
--播放被攻击特效和音效
|
||
function XRpgMakerGameObject:PlayBeAtkAction(cb)
|
||
local modelName = self:GetModelName()
|
||
local effectPath = XRpgMakerGameConfigs.GetRpgMakerGameBeAtkEffectPath(modelName)
|
||
local effectRootName = XRpgMakerGameConfigs.GetRpgMakerGameEffectRoot(modelName)
|
||
local effectRoot
|
||
--被攻击特效
|
||
if not string.IsNilOrEmpty(effectPath) and not string.IsNilOrEmpty(effectRootName) then
|
||
local transform = self:GetTransform()
|
||
effectRoot = transform:FindTransform(effectRootName)
|
||
|
||
if not self.BeAtkResource then
|
||
self.BeAtkResource = self:ResourceManagerLoad(effectPath)
|
||
end
|
||
|
||
if XTool.UObjIsNil(effectRoot) then
|
||
XLog.Error(string.format("XRpgMakerGameObject:PlayBeAtkAction error: 被攻击特效父节点找不到, effectRootName: %s", effectRootName))
|
||
else
|
||
if not self.BeAtkEffect then
|
||
self.BeAtkEffect = self:LoadEffect(self.BeAtkResource.Asset, effectRoot.transform.position, effectRoot)
|
||
end
|
||
if not XTool.UObjIsNil(self.BeAtkEffect) then
|
||
self.BeAtkEffect.gameObject:SetActiveEx(false)
|
||
self.BeAtkEffect.gameObject:SetActiveEx(true)
|
||
end
|
||
end
|
||
end
|
||
|
||
XSoundManager.PlaySoundByType(XSoundManager.UiBasicsMusic.RpgMakerGame_Death, XSoundManager.SoundType.Sound)
|
||
|
||
local delay = XRpgMakerGameConfigs.BeAtkEffectDelayCallbackTime
|
||
XScheduleManager.ScheduleOnce(function()
|
||
if not XTool.UObjIsNil(self.BeAtkEffect) then
|
||
self.BeAtkEffect.gameObject:SetActiveEx(false)
|
||
end
|
||
self:SetActive(false)
|
||
if cb then
|
||
cb()
|
||
end
|
||
end, delay)
|
||
end
|
||
|
||
--播放站立动画
|
||
function XRpgMakerGameObject:PlayStandAnima(cb)
|
||
local modelName = self:GetModelName()
|
||
local standAnima = XRpgMakerGameConfigs.GetRpgMakerGameStandAnimaName(modelName)
|
||
self:PlayAnima(standAnima, cb)
|
||
end
|
||
|
||
function XRpgMakerGameObject:SetActive(isActive)
|
||
local gameObject = self:GetGameObject()
|
||
if XTool.UObjIsNil(gameObject) then
|
||
return
|
||
end
|
||
gameObject:SetActiveEx(isActive)
|
||
end
|
||
|
||
function XRpgMakerGameObject:SetGameObjScale(scale)
|
||
local transform = self:GetTransform()
|
||
if not transform then
|
||
return
|
||
end
|
||
|
||
transform.localScale = scale
|
||
end
|
||
|
||
function XRpgMakerGameObject:SetGameObjMesh(mesh)
|
||
local transform = self:GetTransform()
|
||
if not transform then
|
||
return
|
||
end
|
||
|
||
local meshFilter = transform:GetComponent("MeshFilter")
|
||
if XTool.UObjIsNil(meshFilter) or XTool.UObjIsNil(meshFilter.mesh) then
|
||
return
|
||
end
|
||
|
||
meshFilter.mesh = mesh
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetGameObjMesh()
|
||
local transform = self:GetTransform()
|
||
if not transform then
|
||
return
|
||
end
|
||
|
||
return transform:GetComponent("MeshFilter").mesh
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetCubeObj(row, col)
|
||
return XDataCenter.RpgMakerGameManager.GetSceneCubeObj(row, col)
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetCubeUpCenterPosition(row, col)
|
||
return XDataCenter.RpgMakerGameManager.GetSceneCubeUpCenterPosition(row, col)
|
||
end
|
||
|
||
function XRpgMakerGameObject:GetCubeTransform(row, col)
|
||
return XDataCenter.RpgMakerGameManager.GetSceneCubeTransform(row, col)
|
||
end
|
||
|
||
function XRpgMakerGameObject:ResourceManagerLoad(path)
|
||
local resource = CSXResourceManagerLoad(path)
|
||
if resource == nil or not resource.Asset then
|
||
XLog.Error(string.format("XRpgMakerGameObject:ResourceManagerLoad加载资源,路径:%s", path))
|
||
return
|
||
end
|
||
|
||
return resource
|
||
end
|
||
--------------场景对象相关 end------------------
|
||
|
||
return XRpgMakerGameObject |