c1_lua/lua/app/bf/unity/weapon_object.lua
2023-04-03 10:59:13 +08:00

338 lines
8.8 KiB
Lua

local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager"
local BaseObject = require "app/bf/unity/base_object"
local WeaponObject = class("WeaponObject", BaseObject)
local BF_WEAPON_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_WEAPON_HELPER
local ANIMATOR = GConst.TYPEOF_UNITY_CLASS.ANIMATOR
local ANIMATION_FRAME_PER_SECOND = 30
local SUPPORT_SHADER = {
["BF/Models/Character Battle"] = true,
}
local hash = GFunc.hash
local HashName = {}
local function getHashName(str)
local intName = HashName[str]
if intName == nil then
intName = hash(str)
HashName[str] = intName
end
return intName
end
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local Vector3 = BF.Vector3(0, 0, 0)
local abs = math.abs
function WeaponObject:ctor()
self.timeScale = 1
end
function WeaponObject:initWithPrefab(assetPath, prefab)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.characterHelper = self:getComponent(BF_WEAPON_HELPER)
if self.characterHelper == nil then
self.characterHelper = self:addComponent(BF_WEAPON_HELPER)
end
self.mainModel = self.characterHelper:GetModelObject()
self.objectIndex = -1
self:_genAllBones()
end
function WeaponObject:initWithCharacterHelper(characterHelper, index, gameObject, name, admin)
self.characterHelper = characterHelper
self.objectIndex = index
self.gameObject = gameObject
self.name = name
self.admin = admin
end
function WeaponObject:_genAllBones()
local childMap = {}
if self.characterHelper then
local childNum = self.characterHelper:GetListCount()
for i = 0, childNum do
local gameObject = self.characterHelper:GetGameObjectByIndex(i)
local hashName = self.characterHelper:GetHashNameByIndex(i)
local child = WeaponObject:create()
child:initWithCharacterHelper(self.characterHelper, i, gameObject, hashName, self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
end
function WeaponObject:getBoneByName(name)
return self.childMap[name]
end
function WeaponObject:fastGetPosition()
if self.characterHelper then
self.characterHelper:CachePosition(self.objectIndex)
return self.characterHelper.PositionX, self.characterHelper.PositionY, self.characterHelper.PositionZ
else
local position = self:getTransform().position
return position.x, position.y, position.z
end
end
function WeaponObject:getBonePositionByName(name)
return self.childMap[name]:fastGetPosition()
end
function WeaponObject:getHashCode()
local code = -1
if self.characterHelper then
code = self.characterHelper:GetModelHashCode()
end
return code
end
function WeaponObject:play(name, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(name, layer, normalizedTime)
end
else
self.mainAnimator:Play(name, layer, normalizedTime)
end
end
function WeaponObject:playHashName(hashName, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
else
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
end
function WeaponObject:setAnimatorBool(key, value)
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:SetBool(key, value)
end
else
self.mainAnimator:SetBool(key, value)
end
end
function WeaponObject:getMainAnimator()
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
end
end
return self.mainAnimator
end
function WeaponObject:getMainModelTransform()
if self.mainModelTransform == nil then
self.mainModelTransform = self.mainModel and self.mainModel.transform or nil
end
return self.mainModelTransform
end
function WeaponObject:getMainModel()
return self.mainModel
end
function WeaponObject:getCurrentAnimationHash()
return CS.BF.Utils.GetCurrentAnimationHash(self:getMainAnimator())
end
function WeaponObject:setMainModelLocalScale(x, y, z)
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localScale = Vector3
end
end
function WeaponObject:setMainModelLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetMainModelLocalPosition(x, y, z)
else
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localPosition = Vector3
end
end
end
function WeaponObject:getStateTime(name)
local hashName = getHashName(name)
return self.characterHelper:GetStateTime(hashName)
end
function WeaponObject:getStateTimeHash(hashName)
return self.characterHelper:GetStateTime(hashName)
end
function WeaponObject:getStateKeyTime(name, index)
local hashName = getHashName(name)
local keyTime = self.characterHelper:GetStateKeyFrame(hashName, index) or 0
return keyTime/ANIMATION_FRAME_PER_SECOND
end
function WeaponObject:containsState(name)
return self:getStateTime(name) > 0.00001
end
function WeaponObject:setTimeScale(timeScale)
if abs(self.timeScale - timeScale) < 0.00001 then
return
end
self.timeScale = timeScale
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale*(self.timeScaleAddition or 1)
end
function WeaponObject:setTimeScaleAddition(addition)
self.timeScaleAddition = addition
local timeScale = self.timeScale*addition
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale
end
function WeaponObject:setCullingMode(cullingMode)
local mainAnimator = self:getMainAnimator()
if mainAnimator then
mainAnimator.cullingMode = cullingMode
end
end
function WeaponObject:getCharacterMaterials()
if not self.characterMaterials then
self.characterMaterials = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMaterials, render.material)
end
end
end
return self.characterMaterials
end
function WeaponObject:getCharacterMeshRenderer()
if not self.characterMeshRenders then
self.characterMeshRenders = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMeshRenders, render)
end
end
end
return self.characterMeshRenders
end
function WeaponObject:getMaterialPropertyBlock()
if not self.mpb then
self.mpb = CS.UnityEngine.MaterialPropertyBlock()
end
return self.mpb
end
function WeaponObject:setCustomShadowEnable(enabled)
local materials = self:getCharacterMaterials()
for _, material in ipairs(materials) do
material:SetShaderPassEnabled("Always", enabled)
end
end
function WeaponObject:setCharacterFSM(fsm)
self.fsm = fsm
end
function WeaponObject:setShadowColor(color)
local renderers = self:getCharacterMeshRenderer()
local mpBlock = self:getMaterialPropertyBlock()
for i, renderer in ipairs(renderers) do
renderer:GetPropertyBlock(mpBlock)
mpBlock:SetColor("_shadow_color", color)
renderer:SetPropertyBlock(mpBlock)
end
end
function WeaponObject:setLocalEulerAngles(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function WeaponObject:setLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function WeaponObject:setPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function WeaponObject:setLocalScale(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function WeaponObject:onDestroy()
if self.fsm then
CharacterFSMManager:stopFSM(self.fsm)
self.fsm = nil
end
BaseObject.onDestroy(self)
self.characterHelper = nil
self.mainModel = nil
self.mainAnimator = nil
self.childMap = nil
self.characterMaterials = nil
self.characterMeshRenders = nil
self.mpb = nil
end
return WeaponObject