PGRData/Resources/Scripts/XEntity/XRpgMakerGame/Object/XRpgMakerGameObject.lua

506 lines
16 KiB
Lua
Raw Normal View History

2022-12-26 14:06:01 +05:30
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