using Code.Scripts.Gameplay.Weapon; using Gameplay.Performance; using Gameplay.Pool; using Gameplay.Unit; using Gameplay.Unit.Data; namespace Gameplay.Weapon { using cfg.WeaponCfg; using Character; using Framework; using Common; using Effect; using UnityEngine; public class ViewWeapon { public readonly Character owner; public readonly DataWeapon rawConfig; public readonly GameObject rootObj; public readonly Transform fireTrans; public readonly WeaponAnim weaponAnim; public readonly Transform weaponBone; // private readonly List _lines; public ViewWeapon(Character owner) { this.owner = owner; var weaponId = owner.runtimeData.configData.weaponId; rawConfig = TableManager.Instance.Tables.WeaponConfig.Get(weaponId); // 找到骨骼 var parentPointName = rawConfig.ParentPointName; if (string.IsNullOrEmpty(parentPointName)) { DebugUtil.LogError("武器配置错误: {0}, 没有ParentPointName", weaponId); parentPointName = "Grip_point01"; } var bone = owner.Skeleton.GetBone(parentPointName); if (bone == null) { owner.LogError("找不到骨骼:" + rawConfig.ParentPointName); return; } weaponBone = bone.transform; // 绑定武器 rootObj = bone.transform.GetChild(0).gameObject; weaponAnim = new WeaponAnim(rootObj); // 美术约定从该节点取fire点 fireTrans = owner.Skeleton.GetBone("Fire"); // _lines = new List(); } public void OpenFire(GameUnit enemy) { var groundEffectId = GLConfig.Inst.data.GroundFireEffectId; if (groundEffectId > 0) { var firePos = fireTrans.position; firePos.y = 0.1f; var rot = owner.Node.GameObject.transform.rotation; EffectManager.instance.PlayEffectById(groundEffectId, firePos, rot); } if (rawConfig.FireAudioId.Count > 0) { var fireAudioId = rawConfig.FireAudioId[Random.Range(0, rawConfig.FireAudioId.Count)]; _ = AudioManager.Instance.PlayAudio(fireAudioId, fireTrans.position); } var fireEffectId = rawConfig.FireEffectId; if (fireEffectId > 0) { var rot = owner.Node.GameObject.transform.rotation; EffectManager.instance.PlayEffectById(fireEffectId, fireTrans.position, rot); } var lineEffectId = rawConfig.FlyEffectId; if (lineEffectId > 0 && PerformanceManager.instance.data.enableBulletTail) { var flySpeed = rawConfig.BulletFlySpeed; if (flySpeed <= 0) { DebugUtil.LogError($"武器配置错误: {rawConfig.ID}, 没有FlySpeed"); flySpeed = 100; } _EmitLine(fireTrans, enemy.Node.GameObject.transform, flySpeed); } weaponAnim.PlayAnim(rawConfig.FireAnimName); } private void _EmitLine(Transform start, Transform end, float flySpeed) { var endPos = end.position; var startPos = start.position; endPos.y = startPos.y * 0.5f; var toEnd = endPos - startPos; var angle = Vector3.SignedAngle(Vector3.forward, toEnd, Vector3.up); var effect = EffectManager.instance.PlayEffectById(rawConfig.FlyEffectId, startPos, Quaternion.Euler(0, angle, 0)); var totalDistance = toEnd.magnitude; var flyLogic = ObjPoolManager.instance.Get(); var flyTime = totalDistance / flySpeed; flyLogic.Ctor(startPos, endPos, flyTime); effect.AddLogic(flyLogic); #if UNITY_EDITOR Debug.DrawLine(startPos, endPos, Color.red, flyTime); #endif // var line = ObjPoolManager.instance.Get(); // // line.effect.transform.LookAt(end, Vector3.up); // var position = end.position; // var endPos = position; // var position1 = start.position; // endPos.y = position1.y; // var toEnd = endPos - position1; // var angle = Vector3.SignedAngle(Vector3.forward, toEnd, Vector3.up); // // line.effect = EffectManager.instance.PlayEffectById(rawConfig.FlyEffectId, position1, Quaternion.Euler(0, angle, 0)); // // line.StartFly(position, flySpeed); // _lines.Add(line); } public static void ShowHitEffect(GameUnit enemy, bool isCritical, DataWeapon rawConfig, Transform senderTrans) { var effectId = isCritical ? rawConfig.CriticalHitEffectId : rawConfig.HitEffectId; if (effectId <= 0) return; var hitPoints = GetPoints(enemy); if (hitPoints == null) { DebugUtil.LogError("暂未处理的类型:{0} name: {1}", enemy.gameunitType, enemy.Node.GameObject.name); return; } var points = isCritical ? hitPoints.m_CriticalPoints : hitPoints.m_OtherPoints; var randomPoint = points[Random.Range(0, points.Length)]; var sender = senderTrans; var senderPos = sender.position; var position = randomPoint.position; var toSenderPos = senderPos - position; toSenderPos.y = 0; var angle = Vector3.SignedAngle(Vector3.forward, toSenderPos, Vector3.up); var rot = Quaternion.Euler(0, angle, 0); var effectObj = EffectManager.instance.PlayEffectById(effectId, position, rot); // effectObj.transform.LookAt(fireTrans, Vector3.up); } public static CmpCharacterEffectPoints GetPoints(GameUnit enemy) { switch (enemy.gameunitType) { case EGameUnitType.Character: { if (enemy.RawAnimator == null) return null; var cmp = enemy.RawAnimator.GetComponent(); if (cmp == null) { DebugUtil.LogError("{0} 上未挂载:CmpCharacterEffectPoints 节点", enemy.Node.GameObject.name); cmp = enemy.RawAnimator.gameObject.AddComponent(); cmp.m_CriticalPoints = new Transform[1]; cmp.m_CriticalPoints[0] = enemy.Node.GameObject.transform; cmp.m_OtherPoints = new Transform[1]; cmp.m_OtherPoints[0] = enemy.Node.GameObject.transform; } return cmp; } case EGameUnitType.Vehicle: { var getCmp = enemy.Node.GameObject.GetComponent(); if (getCmp != null) { return getCmp; } var cmp = enemy.Node.GameObject.AddComponent(); cmp.m_CriticalPoints = new Transform[1]; cmp.m_CriticalPoints[0] = enemy.Node.GameObject.transform; cmp.m_OtherPoints = new Transform[1]; cmp.m_OtherPoints[0] = enemy.Node.GameObject.transform; return cmp; } } return null; } public void ViewUpdate(float dt) { // for (var i = 0; i < _lines.Count; ++i) // { // var line = _lines[i]; // line.ViewUpdate(dt); // if (line.needRemove) // { // ObjPoolManager.instance.Return(line); // line.DestroyEffect(); // _lines.RemoveAt(i); // --i; // } // } } // public void Destroy() // { // for (var i = 0; i < _lines.Count; ++i) // { // var line = _lines[i]; // line.DestroyEffect(); // } // _lines.Clear(); // } public void Hide() { if (weaponBone == null) return; weaponBone.localScale = Vector3.zero; } public void Show() { if (weaponBone == null) return; weaponBone.localScale = Vector3.one; } } }