280 lines
10 KiB
C#
280 lines
10 KiB
C#
using AOT.PostProcess.BlackArea;
|
||
using Code.Scripts.Gameplay.Weapon;
|
||
using Cysharp.Threading.Tasks;
|
||
using Gameplay.Performance;
|
||
using Gameplay.Pool;
|
||
using Gameplay.PostProcess.BlackArea;
|
||
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<WeaponLine> _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;
|
||
|
||
// 绑定武器
|
||
if (bone.transform.childCount == 0)
|
||
{
|
||
this.owner.LogError($"当前角色 {owner.runtimeData.configData.nameId} 武器节点下未正确挂载武器");
|
||
// 未挂载武器,直接使用角色的trans作为fire点
|
||
fireTrans = this.owner.RawAnimator.transform;
|
||
return;
|
||
}
|
||
var findTrans = bone.transform.GetChild(0);
|
||
rootObj = findTrans.gameObject;
|
||
weaponAnim = new WeaponAnim(rootObj, owner);
|
||
|
||
// 美术约定从该节点取fire点
|
||
fireTrans = owner.Skeleton.GetBone("Fire");
|
||
if (fireTrans == null)
|
||
{
|
||
DebugUtil.LogError($"当前角色 {owner.runtimeData.configData.nameId} 没有Fire节点, 使用角色的trans作为fire点");
|
||
fireTrans = owner.RawAnimator.transform;
|
||
}
|
||
|
||
// _lines = new List<WeaponLine>();
|
||
}
|
||
|
||
public void OpenFire(GameUnit enemy)
|
||
{
|
||
if (owner.commonData.troopId != ETroopsId.Self)
|
||
{
|
||
BlackAreaManager.instance.LightUpCell(owner.transData.cellIndex, 1f);
|
||
}
|
||
|
||
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, fireTrans);
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
}
|
||
|
||
public void PlayMatchFireAnim()
|
||
{
|
||
if (weaponAnim == null) return;
|
||
weaponAnim.PlayAnim(rawConfig.FireAnimName);
|
||
}
|
||
|
||
public void PlayMatchReloadAnim()
|
||
{
|
||
if (weaponAnim == null) return;
|
||
weaponAnim.PlayAnim(rawConfig.ReleadAnimName);
|
||
}
|
||
|
||
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<BulletFlyLogic>();
|
||
var flyTime = totalDistance / flySpeed;
|
||
flyLogic.Ctor(startPos, endPos, flyTime);
|
||
effect.AddLogic(flyLogic);
|
||
|
||
#if UNITY_EDITOR
|
||
Debug.DrawLine(startPos, endPos, Color.red, flyTime);
|
||
#endif
|
||
}
|
||
|
||
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 + 180, 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<CmpCharacterEffectPoints>();
|
||
if (cmp == null)
|
||
{
|
||
DebugUtil.LogError("{0} 上未挂载:CmpCharacterEffectPoints 节点", enemy.Node.GameObject.name);
|
||
cmp = enemy.RawAnimator.gameObject.AddComponent<CmpCharacterEffectPoints>();
|
||
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:
|
||
case EGameUnitType.Summon:
|
||
case EGameUnitType.BeProtect:
|
||
case EGameUnitType.Building:
|
||
{
|
||
var getCmp = enemy.Node.GameObject.GetComponent<CmpCharacterEffectPoints>();
|
||
if (getCmp != null)
|
||
{
|
||
return getCmp;
|
||
}
|
||
var cmp = enemy.Node.GameObject.AddComponent<CmpCharacterEffectPoints>();
|
||
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;
|
||
weaponBone.gameObject.SetActive(false);
|
||
var childBone = weaponBone.transform.GetChild(0);
|
||
if (childBone != null)
|
||
{
|
||
childBone.transform.localScale = Vector3.zero;
|
||
childBone.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
|
||
public void Show()
|
||
{
|
||
if (weaponBone == null) return;
|
||
weaponBone.localScale = Vector3.one;
|
||
weaponBone.gameObject.SetActive(true);
|
||
|
||
if (weaponBone.transform.childCount != 0)
|
||
{
|
||
var childBone = weaponBone.transform.GetChild(0);
|
||
childBone.transform.localScale = Vector3.one;
|
||
childBone.gameObject.SetActive(true);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|