您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

246 行
10 KiB

using System;
using UnityEngine.Playables;
using UnityEngine;
using Unity.Entities;
[DisallowMultipleComponent]
[ClientOnlyComponent]
public class TerraformerWeaponA : MonoBehaviour
{
public Transform muzzle;
public PlayableDirector timelineGrenadeRefill;
public Transform grenadeFuelBase;
public Transform magazineFuelBase;
public Transform[] vents;
public float ventDampSpeed = 5;
public float ventStartSpeed = 1000;
public SoundDef primaryFireSound;
public ParticleSystem primaryFireEffect;
public HitscanEffectTypeDefinition hitscanEffect;
public SpatialEffectTypeDefinition environmentImpactEffect;
public SpatialEffectTypeDefinition characterImpactEffect;
public SoundDef secondaryFireSound;
public ParticleSystem secondaryFireEffect;
public SoundDef meleeImpactSound;
public ParticleSystem meleeImpactEffect;
[NonSerialized] public TickEventHandler primaryFireEvent = new TickEventHandler(0.5f);
[NonSerialized] public TickEventHandler secondaryFireEvent = new TickEventHandler(0.5f);
[NonSerialized] public TickEventHandler meleeImpactEvent = new TickEventHandler(0.5f);
[NonSerialized] public SoundSystem.SoundHandle primaryFireSoundHandle;
public float[] ventRotationSpeed;
public int nextVentIndex;
public Vector3 m_lastGrenadeFuelWorldPos;
public CharacterPredictedState.StateData.Action m_prevAction;
void Awake()
{
if (vents != null)
ventRotationSpeed = new float[vents.Length];
}
}
// System
[DisableAutoCreation]
public class UpdateTerraformerWeaponA : BaseComponentSystem<CharacterItem,TerraformerWeaponA>
{
public UpdateTerraformerWeaponA(GameWorld world) : base(world)
{
ExtraComponentRequirements = new[] {ComponentType.Subtractive<DespawningEntity>(),};
}
protected override void Update(Entity entity, CharacterItem item, TerraformerWeaponA weapon)
{
if (!item.visible)
return;
var abilityCtrl = EntityManager.GetComponentObject<AbilityController>(item.character);
Update(m_world.worldTime, weapon, abilityCtrl);
}
void Update(GameTime time, TerraformerWeaponA weapon, AbilityController abilityCtrl)
{
// Update using AutoRifle ability state
var autoRifleAbility = abilityCtrl.GetAbilityEntity(EntityManager,typeof(Ability_AutoRifle));
GameDebug.Assert(autoRifleAbility != Entity.Null,"AbilityController does not own a Ability_AutoRifle ability");
var autoRifleInterpolatedState = EntityManager.GetComponentData<Ability_AutoRifle.InterpolatedState>(autoRifleAbility);
if (weapon.primaryFireEvent.Update(time, autoRifleInterpolatedState.fireTick))
{
if(weapon.primaryFireSound != null)
{
if (weapon.primaryFireSoundHandle.IsValid() && weapon.primaryFireSoundHandle.emitter.playing)
Game.SoundSystem.Stop(weapon.primaryFireSoundHandle, 0.05f);
weapon.primaryFireSoundHandle = Game.SoundSystem.Play(weapon.primaryFireSound, weapon.muzzle);
}
if(weapon.primaryFireEffect != null)
weapon.primaryFireEffect.Play();
if(weapon.hitscanEffect != null)
HitscanEffectRequest.Create(PostUpdateCommands, weapon.hitscanEffect, weapon.muzzle.position,
autoRifleInterpolatedState.fireEndPos );
if (autoRifleInterpolatedState.impactType != Ability_AutoRifle.ImpactType.None)
{
var rotation = Quaternion.LookRotation(autoRifleInterpolatedState.impactNormal);
if (autoRifleInterpolatedState.impactType == Ability_AutoRifle.ImpactType.Character)
{
SpatialEffectRequest.Create(PostUpdateCommands, weapon.characterImpactEffect,
autoRifleInterpolatedState.fireEndPos, rotation);
}
else
{
SpatialEffectRequest.Create(PostUpdateCommands, weapon.environmentImpactEffect,
autoRifleInterpolatedState.fireEndPos, rotation);
}
}
}
// Update using ProjectileLauncher ability state
var rocketAbility = abilityCtrl.GetAbilityEntity(EntityManager,typeof(Ability_ProjectileLauncher));
GameDebug.Assert(rocketAbility != Entity.Null,"AbilityController does not own a Ability_ProjectileLauncher ability");
var rocketLaunchInterpolatedState = EntityManager.GetComponentData<Ability_ProjectileLauncher.InterpolatedState>(rocketAbility);
if (weapon.secondaryFireEvent.Update(time, rocketLaunchInterpolatedState.fireTick))
{
if(weapon.secondaryFireSound != null)
Game.SoundSystem.Play(weapon.secondaryFireSound, weapon.muzzle);
if(weapon.secondaryFireEffect != null)
weapon.secondaryFireEffect.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);
if(weapon.meleeImpactEffect != null)
weapon.meleeImpactEffect.Play();
}
// Vents disabled vents until we find out what to do with them
// Update vents
// if (entity.vents != null)
// {
// for (int ventIndex = 0; ventIndex < entity.vents.Length; ventIndex++)
// {
// if (entity.ventRotationSpeed[ventIndex] == 0)
// continue;
//
// // Rotate
// float deltaRot = entity.ventRotationSpeed[ventIndex] * m_world.frameDuration;
// Vector3 eulerRot = entity.vents[ventIndex].rotation.eulerAngles;
// eulerRot.z += deltaRot;
// entity.vents[ventIndex].rotation = Quaternion.Euler(eulerRot);
//
// // Damp speed
// float deltaSpeed = entity.ventDampSpeed * m_world.frameDuration;
// float absSpeed = Mathf.Abs(entity.ventRotationSpeed[ventIndex]);
// if (deltaSpeed >= absSpeed)
// entity.ventRotationSpeed[ventIndex] = 0;
// else
// entity.ventRotationSpeed[ventIndex] -= Mathf.Sign(entity.ventRotationSpeed[ventIndex]) * deltaSpeed;
// }
//
// Character.State.Action newAction = weapon.action;
// if (newAction != entity.m_prevAction)
// {
// if (newAction == Character.State.Action.PrimaryFire)
// {
// entity.ventRotationSpeed[entity.nextVentIndex] = entity.ventStartSpeed;
// entity.ventRotationSpeed[entity.nextVentIndex + 1] = -entity.ventStartSpeed;
// entity.nextVentIndex = (entity.nextVentIndex + 2) % entity.vents.Length;
// }
// if (newAction == Character.State.Action.SecondaryFire)
// {
// entity.timelineGrenadeRefill.time = 0;
// entity.timelineGrenadeRefill.Play();
// }
//
// entity.m_prevAction = newAction;
// }
// }
// Velocity based ammo fuel angle
if(weapon.grenadeFuelBase != null)
{
Vector3 basePos = weapon.grenadeFuelBase.position;
Vector3 moveVec = basePos - weapon.m_lastGrenadeFuelWorldPos;
weapon.m_lastGrenadeFuelWorldPos = basePos;
Vector3 rotateAxis = Vector3.Cross(moveVec, Vector3.up).normalized;
float moveVel = moveVec.magnitude / m_world.frameDuration;
float angle = moveVel * 2;
Quaternion targetRot = Quaternion.AngleAxis(-angle, rotateAxis);
weapon.grenadeFuelBase.rotation = Quaternion.Lerp(weapon.grenadeFuelBase.rotation, targetRot, 3 * m_world.frameDuration);
}
}
}
[DisableAutoCreation]
public class TerraformerWeaponClientProjectileSpawnHandler : InitializeComponentGroupSystem<ClientProjectile, TerraformerWeaponClientProjectileSpawnHandler.Initialized>
{
public struct Initialized : IComponentData {}
private ComponentGroup WeaponGroup;
public TerraformerWeaponClientProjectileSpawnHandler(GameWorld world) : base(world)
{}
protected override void OnCreateManager(int capacity)
{
base.OnCreateManager(capacity);
WeaponGroup = GetComponentGroup(typeof(TerraformerWeaponA), typeof(CharacterItem));
}
protected override void Initialize(ref ComponentGroup group)
{
var clientProjectileArray = group.GetComponentArray<ClientProjectile>();
var weaponArray = WeaponGroup.GetComponentArray<TerraformerWeaponA>();
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 pos = weapon.muzzle.position;
//GameDebug.Log("proj count;" + clientProjectileArray.Length + "muzzlepos:" + pos);
clientProjectile.SetMuzzlePosition(EntityManager, pos);
break;
}
}
}
}
}