该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

204 行
7.8 KiB

using System;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Sample.Core;
using Unity.Transforms;
using UnityEngine;
using UnityEngine.VFX;
#if UNITY_EDITOR
public partial class TerraformerWeaponPart : MonoBehaviour, IConvertGameObjectToEntity
{
[AssetType(typeof(SoundDef))]
public WeakAssetReference soundRef;
public VisualEffectAsset muzzleEffect;
public VisualEffectAsset hitscanEffect;
public VisualEffectAsset impactEffectEnv;
public WeakAssetReference impactSoundEnv;
public VisualEffectAsset impactEffectChar;
public WeakAssetReference impactSoundChar;
public Transform MuzzleTransform;
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var authoringData = AutoringData.Default;
authoringData.soundRef = soundRef;
authoringData.impactSoundEnv = impactSoundEnv;
authoringData.impactSoundChar = impactSoundChar;
authoringData.MuzzleEntity = conversionSystem.GetPrimaryEntity(MuzzleTransform);
var authoringClass = new AuthoringClass();
authoringClass.muzzleEffect = muzzleEffect;
authoringClass.hitscanEffect = hitscanEffect;
authoringClass.impactEffectEnvironment = impactEffectEnv;
authoringClass.impactEffectCharacter = impactEffectChar;
var state = State.Default;
dstManager.AddComponentData(entity, authoringData);
dstManager.AddComponentData(entity, state);
dstManager.AddComponentData(entity, authoringClass);
}
}
#endif
public partial class TerraformerWeaponPart
{
public struct AutoringData : IComponentData
{
public static AutoringData Default => new AutoringData();
public WeakAssetReference soundRef;
public WeakAssetReference impactSoundEnv;
public WeakAssetReference impactSoundChar;
public Entity MuzzleEntity;
}
public class AuthoringClass : IComponentData, IEquatable<AuthoringClass>
{
public VisualEffectAsset hitscanEffect;
public VisualEffectAsset muzzleEffect;
public VisualEffectAsset impactEffectEnvironment;
public VisualEffectAsset impactEffectCharacter;
public bool Equals(AuthoringClass other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(muzzleEffect, other.muzzleEffect) && Equals(hitscanEffect, other.hitscanEffect);
}
public override int GetHashCode()
{
int hash = base.GetHashCode();
hash = ReferenceEquals(muzzleEffect, null) ? hash : hash * 23 + muzzleEffect.GetHashCode();
hash = ReferenceEquals(hitscanEffect, null) ? hash : hash * 23 + hitscanEffect.GetHashCode();
hash = ReferenceEquals(impactEffectEnvironment, null) ? hash : hash * 23 + impactEffectEnvironment.GetHashCode();
hash = ReferenceEquals(impactEffectCharacter, null) ? hash : hash * 23 + impactEffectCharacter.GetHashCode();
return hash;
}
}
public struct AbilityEntity : IComponentData
{
public Entity Value;
}
public struct State : IComponentData
{
public static State Default => new State();
public int LastFireTick;
}
[UpdateInGroup(typeof(InitializationSystemGroup))]
public class Initialize : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
inputDeps.Complete();
var PostUpdateCommands = new EntityCommandBuffer(Allocator.TempJob);
var OwnedAbilityBufferFromEntity = GetBufferFromEntity<AbilityOwner.OwnedAbility>(true);
Entities.WithNativeDisableContainerSafetyRestriction(PostUpdateCommands)
.WithAll<AutoringData>()
.WithNone<AbilityEntity>()
.WithoutBurst()
.ForEach((Entity entity, ref Part.Owner partOwner) =>
{
var rootOwner = EntityManager.GetComponentData<Item.InputState>(partOwner.Value).owner;
if (rootOwner == Entity.Null)
return;
var abilityEntity = Ability.FindAbility(OwnedAbilityBufferFromEntity, rootOwner, AbilityAutoRifle.Tag);
if (abilityEntity == Entity.Null)
return;
var ability = new AbilityEntity
{
Value = abilityEntity
};
PostUpdateCommands.AddComponent(entity,ability);
}).Run();
PostUpdateCommands.Playback(EntityManager);
PostUpdateCommands.Dispose();
return default;
}
}
[UpdateInGroup(typeof(PresentationSystemGroup))]
[UpdateBefore(typeof(VFXSystem))]
[UpdateBefore(typeof(PresentationSystemGroup))]
[AlwaysSynchronizeSystem]
public class Update : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var vfxSystem = World.GetExistingSystem<VFXSystem>();
// TODO: Burst not compatible with accessing EntityManager
Entities.WithoutBurst()
.ForEach((AuthoringClass authClass, ref AutoringData authData, ref AbilityEntity ability, ref State state, ref Unity.Transforms.LocalToWorld localToWorld) =>
{
if (!EntityManager.Exists(ability.Value))
{
GameDebug.LogWarning(World,"Ability entity:{0}" + ability.Value + " does no longer exist");
return;
}
if (!EntityManager.HasComponent<AbilityAutoRifle.InterpolatedState>(ability.Value))
{
GameDebug.LogWarning(World,"Ability entity:{0}" + ability.Value + " does not have Ability_AutoRifle.InterpolatedState component");
return;
}
var rifleState = EntityManager.GetComponentData<AbilityAutoRifle.InterpolatedState>(ability.Value);
if (rifleState.fireTick > state.LastFireTick) // This will trigger for late joiners
{
var muzzleLTW = EntityManager.GetComponentData<LocalToWorld>(authData.MuzzleEntity);
// DebugDraw.Sphere(muzzleLTW.Position,0.2f,Color.red);
vfxSystem.SpawnPointEffect(authClass.muzzleEffect, muzzleLTW.Position, muzzleLTW.Forward);
vfxSystem.SpawnLineEffect(authClass.hitscanEffect,muzzleLTW.Position, rifleState.fireEndPos);
if (rifleState.impactType != AbilityAutoRifle.ImpactType.None)
{
var impactEffect = rifleState.impactType == AbilityAutoRifle.ImpactType.Character
? authClass.impactEffectCharacter
: authClass.impactEffectEnvironment;
vfxSystem.SpawnPointEffect(impactEffect, rifleState.fireEndPos, rifleState.impactNormal);
var impactSound = rifleState.impactType == AbilityAutoRifle.ImpactType.Character
? authData.impactSoundChar
: authData.impactSoundEnv;
SoundSystem.Instance.Play(impactSound, rifleState.fireEndPos);
}
SoundSystem.Instance.Play(authData.soundRef, localToWorld.Position);
state.LastFireTick = rifleState.fireTick;
}
}).Run();
return default;
}
}
}