您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
193 行
7.7 KiB
193 行
7.7 KiB
using System;
|
|
using UnityEngine;
|
|
using Unity.Entities;
|
|
|
|
public struct GunBarrelState
|
|
{
|
|
public Vector3 startPosition;
|
|
public float animTime;
|
|
}
|
|
|
|
[Serializable]
|
|
public class GunBarrelSetup
|
|
{
|
|
public Transform[] barrels;
|
|
public ParticleSystem[] fireParticle;
|
|
public SoundDef fireSound;
|
|
public AnimationCurve fireAnimCurve;
|
|
|
|
[NonSerialized] public SoundSystem.SoundHandle fireSoundHandle;
|
|
[NonSerialized] public GunBarrelState[] states;
|
|
[NonSerialized] public int index;
|
|
}
|
|
|
|
|
|
[ClientOnlyComponent]
|
|
public class RobotWeaponA : MonoBehaviour
|
|
{
|
|
[NonSerialized] public TickEventHandler primFireEvent = new TickEventHandler(0.5f);
|
|
[NonSerialized] public TickEventHandler secFireEvent = new TickEventHandler(0.5f);
|
|
[NonSerialized] public TickEventHandler meleeImpactEvent = new TickEventHandler(0.5f);
|
|
|
|
public GunBarrelSetup barrelSetup;
|
|
|
|
public SoundDef secondaryFireSound;
|
|
public ParticleSystem secondaryFireParticle;
|
|
|
|
public SoundDef meleeImpactSound;
|
|
public ParticleSystem meleeImpactEffect;
|
|
}
|
|
|
|
|
|
// System
|
|
[DisableAutoCreation]
|
|
public class System_RobotWeaponA : BaseComponentSystem<RobotWeaponA,CharacterItem>
|
|
{
|
|
public System_RobotWeaponA(GameWorld world) : base(world)
|
|
{
|
|
ExtraComponentRequirements = new[] {ComponentType.Subtractive<DespawningEntity>()};
|
|
}
|
|
|
|
protected override void Update(Entity entity, RobotWeaponA weapon, CharacterItem item)
|
|
{
|
|
if (!item.visible)
|
|
return;
|
|
|
|
var abilityCtrl = EntityManager.GetComponentObject<AbilityController>(item.character);
|
|
Update(m_world.worldTime, weapon, abilityCtrl, m_world.frameDuration);
|
|
}
|
|
|
|
|
|
public void Update(GameTime time, RobotWeaponA weapon,AbilityController abilityCtrl, float deltaTime)
|
|
{
|
|
GameDebug.Assert(weapon.barrelSetup != null && weapon.barrelSetup.barrels.Length > 0, "Robotweapon has no barrels defined");
|
|
|
|
// Initialize barrels
|
|
if (weapon.barrelSetup.states == null)
|
|
{
|
|
weapon.barrelSetup.states = new GunBarrelState[weapon.barrelSetup.barrels.Length];
|
|
for (var i = 0; i < weapon.barrelSetup.states.Length; i++)
|
|
{
|
|
weapon.barrelSetup.states[i].startPosition = weapon.barrelSetup.barrels[i].transform.localPosition;
|
|
weapon.barrelSetup.states[i].animTime = 1;
|
|
}
|
|
}
|
|
|
|
// Update using chaingun ability state
|
|
var chaingunAbility = abilityCtrl.GetAbilityEntity(EntityManager,typeof(Ability_Chaingun));
|
|
GameDebug.Assert(chaingunAbility != Entity.Null,"AbilityController does not own a Ability_Chaingun ability");
|
|
var chaingunInterpolatedState = EntityManager.GetComponentData<Ability_Chaingun.InterpolatedState>(chaingunAbility);
|
|
|
|
if (weapon.primFireEvent.Update(time, chaingunInterpolatedState.fireTick))
|
|
{
|
|
weapon.barrelSetup.index = (weapon.barrelSetup.index + 1) % weapon.barrelSetup.barrels.Length;
|
|
|
|
var index = weapon.barrelSetup.index;
|
|
weapon.barrelSetup.states[index].animTime = 0;
|
|
weapon.barrelSetup.fireParticle[index].Play();
|
|
if (weapon.barrelSetup.fireSoundHandle.IsValid() && weapon.barrelSetup.fireSoundHandle.emitter.playing)
|
|
Game.SoundSystem.Stop(weapon.barrelSetup.fireSoundHandle, 0.1f);
|
|
weapon.barrelSetup.fireSoundHandle = Game.SoundSystem.Play(weapon.barrelSetup.fireSound,
|
|
weapon.barrelSetup.fireParticle[index].transform.position);
|
|
}
|
|
|
|
// Update using grenade ability state
|
|
var grenadeAbility = abilityCtrl.GetAbilityEntity(EntityManager,typeof(Ability_GrenadeLauncher));
|
|
GameDebug.Assert(grenadeAbility != Entity.Null,"AbilityController does not own a Ability_GrenadeLauncher ability");
|
|
var grenadeInterpolatedState = EntityManager.GetComponentData<Ability_GrenadeLauncher.InterpolatedState>(grenadeAbility);
|
|
if (weapon.secFireEvent.Update(time, grenadeInterpolatedState.fireTick))
|
|
{
|
|
if (weapon.secondaryFireSound != null)
|
|
Game.SoundSystem.Play(weapon.secondaryFireSound, weapon.transform.position);
|
|
|
|
if (weapon.secondaryFireParticle != null)
|
|
weapon.secondaryFireParticle.Play();
|
|
}
|
|
|
|
|
|
// Update using Melee ability ability state
|
|
var meleeAbility = abilityCtrl.GetAbilityEntity(EntityManager,typeof(Ability_Melee));
|
|
GameDebug.Assert(meleeAbility != Entity.Null,"AbilityController does not own a Ability_Melee ability");
|
|
var meleeInterpolatedState = EntityManager.GetComponentData<Ability_Melee.InterpolatedState>(meleeAbility);
|
|
if (weapon.meleeImpactEvent.Update(time, meleeInterpolatedState.impactTick))
|
|
{
|
|
if(weapon.meleeImpactSound != null)
|
|
Game.SoundSystem.Play(weapon.meleeImpactSound, weapon.transform.position);// TODO this should be hand position
|
|
|
|
if(weapon.meleeImpactEffect != null)
|
|
weapon.meleeImpactEffect.Play();
|
|
}
|
|
|
|
// Update barrel state
|
|
for (var i = 0; i < weapon.barrelSetup.states.Length; i++)
|
|
{
|
|
weapon.barrelSetup.states[i].animTime += deltaTime;
|
|
}
|
|
|
|
// Apply barrel state
|
|
for (var i = 0; i < weapon.barrelSetup.states.Length; i++)
|
|
{
|
|
var localPos = weapon.barrelSetup.states[i].startPosition;
|
|
|
|
var animDuration = weapon.barrelSetup.fireAnimCurve[weapon.barrelSetup.fireAnimCurve.length - 1].time;
|
|
if (weapon.barrelSetup.states[i].animTime < animDuration)
|
|
{
|
|
var offset = weapon.barrelSetup.fireAnimCurve.Evaluate(weapon.barrelSetup.states[i].animTime);
|
|
localPos.z += offset;
|
|
}
|
|
|
|
weapon.barrelSetup.barrels[i].transform.localPosition = localPos;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
[DisableAutoCreation]
|
|
public class RobotWeaponClientProjectileSpawnHandler : InitializeComponentGroupSystem<ClientProjectile,RobotWeaponClientProjectileSpawnHandler.Initialzied>
|
|
{
|
|
public struct Initialzied : IComponentData {}
|
|
|
|
private ComponentGroup WeaponGroup;
|
|
|
|
public RobotWeaponClientProjectileSpawnHandler(GameWorld world) : base(world)
|
|
{}
|
|
|
|
protected override void OnCreateManager(int capacity)
|
|
{
|
|
base.OnCreateManager(capacity);
|
|
WeaponGroup = GetComponentGroup(typeof(RobotWeaponA), typeof(CharacterItem));
|
|
}
|
|
|
|
protected override void Initialize(ref ComponentGroup group)
|
|
{
|
|
var clientProjectileArray = group.GetComponentArray<ClientProjectile>();
|
|
var weaponArray = WeaponGroup.GetComponentArray<RobotWeaponA>();
|
|
var itemArray = WeaponGroup.GetComponentArray<CharacterItem>();
|
|
|
|
for (var i = 0; i < clientProjectileArray.Length; i++)
|
|
{
|
|
var clientProjectile = clientProjectileArray[i];
|
|
|
|
var projectileData = EntityManager.GetComponentData<ProjectileData>(clientProjectile.projectile);
|
|
var projectileOwner = projectileData.projectileOwner;
|
|
|
|
for (var j = 0; j < itemArray.Length; j++)
|
|
{
|
|
var item = itemArray[j];
|
|
|
|
if (!item.visible)
|
|
continue;
|
|
|
|
if (item.character == projectileOwner)
|
|
{
|
|
var weapon = weaponArray[j];
|
|
var index = weapon.barrelSetup.index;
|
|
var pos = weapon.barrelSetup.barrels[index].position;
|
|
// GameDebug.Log("MATCH weapon:" + weapon.name + "proj count;" + clientProjectileArray.Length + " Index:" + index + "muzzlepos:" + pos + " tick:" + m_world.worldTime.tick);
|
|
clientProjectile.SetMuzzlePosition(EntityManager, pos);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|