PGRData/Resources/Scripts/XEntity/XRpgMakerGame/Object/XRpgMakerGameObject.lua
2022-12-26 14:06:01 +05:30

506 lines
No EOL
16 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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