diff --git a/Assets/AddressableAssetsData/AddressableAssetSettings.asset b/Assets/AddressableAssetsData/AddressableAssetSettings.asset index 2b80934..6852236 100644 --- a/Assets/AddressableAssetsData/AddressableAssetSettings.asset +++ b/Assets/AddressableAssetsData/AddressableAssetSettings.asset @@ -33,6 +33,7 @@ MonoBehaviour: m_UniqueBundleIds: 0 m_EnableJsonCatalog: 0 m_NonRecursiveBuilding: 1 + m_AllowNestedBundleFolders: 0 m_CCDEnabled: 0 m_maxConcurrentWebRequests: 3 m_UseUWRForLocalBundles: 0 diff --git a/Assets/RebootKit b/Assets/RebootKit index d1583c9..00b33af 160000 --- a/Assets/RebootKit +++ b/Assets/RebootKit @@ -1 +1 @@ -Subproject commit d1583c9f58f9b774f5662106a02021b526f5c9a7 +Subproject commit 00b33af98b6181b3984c0ca7f9973cd740250933 diff --git a/Assets/jelycho/Code/Enemies/ZombieActor.cs b/Assets/jelycho/Code/Enemies/ZombieActor.cs index 5db6fdd..9475c1b 100644 --- a/Assets/jelycho/Code/Enemies/ZombieActor.cs +++ b/Assets/jelycho/Code/Enemies/ZombieActor.cs @@ -6,6 +6,7 @@ using RebootKit.Engine.Extensions; using RebootKit.Engine.Main; using RebootKit.Engine.Network; using RebootKit.Engine.Simulation; +using RebootReality.jelycho.Beacons; using RebootReality.jelycho.Player; using TriInspector; using Unity.Mathematics; @@ -61,33 +62,65 @@ namespace RebootReality.jelycho.Enemies { } } - public class ZombieBlackboard { - public ZombieActor Self; + class ZombiePickVictim : IStrategy { + public BehaviourNode.Status Process(Actor target, float dt) { + if (target is not ZombieActor zombie) { + return BehaviourNode.Status.Failure; + } + + Debug.Log("Picking victim"); + + Actor victim = zombie.FindNewVictim(); + if (victim == null) { + return BehaviourNode.Status.Failure; + } + + return BehaviourNode.Status.Success; + } + } + + class ZombieGoToPlayer : IStrategy { + public BehaviourNode.Status Process(Actor target, float dt) { + if (target is not ZombieActor zombie) { + return BehaviourNode.Status.Failure; + } + + Debug.Log("Goto player"); + + if (!zombie.HasTravelDestination) { + float3 victimPos = zombie.Victim.transform.position; + float dstToVictimSq = math.distancesq(victimPos, zombie.transform.position); + + if (dstToVictimSq < 1.0f) { + return BehaviourNode.Status.Success; + } + + zombie.GoTo(victimPos); + return BehaviourNode.Status.Running; + } + + return BehaviourNode.Status.Running; + } } [DeclareBoxGroup("Body parts")] + [DeclareBoxGroup("Animations")] public class ZombieActor : Actor, IKillable { static readonly Logger s_Logger = new Logger(nameof(ZombieActor)); - static readonly int s_MovementSpeedHash = Animator.StringToHash("MovementSpeed"); - - enum AIState { - Idle, - Dead, - AttackBase, - AttackCharacter, - PanicEscape, - Berserk - } - [SerializeField] AnimancerComponent m_Animancer; [SerializeField] NavMeshAgent m_NavAgent; + public NavMeshAgent NavAgent { + get { + return m_NavAgent; + } + } [SerializeField] Collider m_RootCollider; [SerializeField] Rigidbody[] m_RagdollRigidbodies; - [SerializeField] float m_MaxAttackDistance = 1.0f; + [SerializeField] float m_MaxAttackDistance = 2.0f; [SerializeField] float m_LoseInterestMinDistance = 10.0f; [SerializeField] ulong m_BaseDamage = 10; [SerializeField] float m_AttackDelay = 1.0f; @@ -97,31 +130,50 @@ namespace RebootReality.jelycho.Enemies { [SerializeField, Group("Body parts")] ZombieBodyPart m_RightArm; [SerializeField, Group("Body parts")] ZombieBodyPart m_LeftLeg; [SerializeField, Group("Body parts")] ZombieBodyPart m_RightLeg; - - AIState m_State = AIState.Idle; - PlayerActor m_PlayerTarget; - float m_NextAttackTimer; - - public UnityEvent died = new UnityEvent(); + [SerializeField, Group("Animations")] AnimationClip[] m_AttackClips; BehaviourTree m_BehaviourTree; + public enum MindState { + Normal, + RunAway, + Berserk + } + public bool IsRagdoll { get; private set; } = false; + public MindState Mind { get; private set; } = MindState.Normal; + public Actor Victim { get; private set; } + + public bool HasTravelDestination { get; private set; } + public float3 TravelDestination { get; private set; } + + public UnityEvent died = new UnityEvent(); + // // @MARK: Unity callbacks // void Awake() { - SetRagdollLocal(false); + SetRagdollLocal(IsRagdoll); m_BehaviourTree = new BehaviourTree("Zombie Behaviour"); var rootSelector = new Selector("Root"); m_BehaviourTree.AddChild(rootSelector); - - var attackPlayerSequence = new Sequence("Attack Player", - () => m_PlayerTarget != null); - rootSelector.AddChild(attackPlayerSequence); + rootSelector.AddChild(CreateNormalSequence()); + } + + BehaviourNode CreateNormalSequence() { + var normalSequence = new Sequence("Normal", () => Mind == MindState.Normal); + normalSequence.AddChild(new Leaf("Pick Victim", new ZombiePickVictim())); + + var attackPlayerSequence = new Sequence("Attack Player", IsVictimPlayer); + normalSequence.AddChild(attackPlayerSequence); + attackPlayerSequence.AddChild(new Leaf("Go to Player", new ZombieGoToPlayer())); + + var attackMotherSequence = new Sequence("Attack Mother", IsVictimMother); + normalSequence.AddChild(attackMotherSequence); + return normalSequence; } // @@ -146,107 +198,69 @@ namespace RebootReality.jelycho.Enemies { return; } - m_BehaviourTree.Process(deltaTime); - return; + if (HasTravelDestination) { + float3 pos = transform.position; - switch (m_State) { - case AIState.Idle: { - ServerTickIdle(deltaTime); - break; - } - - case AIState.AttackBase: { - ServerTickAttackBase(deltaTime); - break; - } - - case AIState.AttackCharacter: { - ServerTickAttackCharacter(deltaTime); - break; - } - - case AIState.PanicEscape: { - break; + if (math.distancesq(pos, TravelDestination) <= 1.0f) { + HasTravelDestination = false; + } } - case AIState.Berserk: { - ServerTickBerserk(deltaTime); - break; - } - } + m_BehaviourTree.Process(this, deltaTime); } // // @MARK: Zombie // - void ServerTickIdle(float dt) { + public bool GoTo(float3 pos) { + if (!RR.IsServer()) { + s_Logger.Error("Only server can call GoTo"); + return false; + } + + TravelDestination = pos; + HasTravelDestination = true; + return m_NavAgent.SetDestination(TravelDestination); + } + + public bool IsVictimPlayer() { + return Victim is PlayerActor; + } + + public bool IsVictimMother() { + return Victim is MotherActor; + } + + public Actor FindNewVictim() { + if (!RR.IsServer()) { + s_Logger.Error("Only server can call FindNewVictim"); + return null; + } + + Victim = null; + (PlayerActor playerActor, float distSqToPlayer) = FindClosestPlayerActor(transform.position); - if (playerActor == null || distSqToPlayer >= m_LoseInterestMinDistance * m_LoseInterestMinDistance) { - return; + if (playerActor != null && distSqToPlayer < m_LoseInterestMinDistance * m_LoseInterestMinDistance) { + Victim = playerActor; + return Victim; } - m_State = AIState.AttackCharacter; - m_PlayerTarget = playerActor; + if (RR.World.Context is WorldContext ctx) { + Victim = ctx.BaseManager.Mother; + return Victim; + } - s_Logger.Info($"Found player actor to attack: {m_PlayerTarget}"); - m_NavAgent.SetDestination(m_PlayerTarget.transform.position); - m_NavAgent.isStopped = false; + return null; } - void ServerTickAttackCharacter(float dt) { - if (m_PlayerTarget == null || !m_PlayerTarget.IsAlive()) { - SetIdleState(); - return; - } - - float3 playerPos = m_PlayerTarget.transform.position; - float3 zombiePos = transform.position; - - float distToPlayerSq = math.distancesq(playerPos, zombiePos); - if (distToPlayerSq >= m_LoseInterestMinDistance * m_LoseInterestMinDistance) { - SetIdleState(); - return; - } - - if (distToPlayerSq <= m_MaxAttackDistance * m_MaxAttackDistance) { - m_NextAttackTimer -= dt; - if (m_NextAttackTimer <= 0.0f) { - // m_Animator.CrossFade("Attack_0", 0.0f, 0); - m_NextAttackTimer = m_AttackDelay; - } - - if (!m_NavAgent.isStopped) { - m_NavAgent.isStopped = true; - } - return; - } - - float distFromDstToTargetSq = math.distancesq(playerPos, m_NavAgent.destination); - if (distFromDstToTargetSq > 1.0f) { - m_NavAgent.isStopped = false; - m_NavAgent.SetDestination(m_PlayerTarget.transform.position); - } - } - - void ServerTickAttackBase(float dt) { - - } - - void ServerTickBerserk(float dt) { - - } - - void SetIdleState() { - m_PlayerTarget = null; - m_State = AIState.Idle; + public void PerformAttack() { + m_Animancer.Play(m_AttackClips.Random()); } void Die() { - s_Logger.Info("Die"); EnableRagdoll(); m_NavAgent.enabled = false; - m_State = AIState.Dead; died.Invoke(); } @@ -281,7 +295,7 @@ namespace RebootReality.jelycho.Enemies { } protected override void OnActorEventClient(ActorEvent actorEvent) { - ZombieActorEvents zombieEvent = (ZombieActorEvents) actorEvent.EventID; + var zombieEvent = (ZombieActorEvents) actorEvent.EventID; switch (zombieEvent) { case ZombieActorEvents.EnableRagdoll: { diff --git a/Assets/jelycho/core/Items/item_dagger.prefab b/Assets/jelycho/core/Items/item_dagger.prefab index 7faee5b..67833b3 100644 --- a/Assets/jelycho/core/Items/item_dagger.prefab +++ b/Assets/jelycho/core/Items/item_dagger.prefab @@ -1,5 +1,153 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1 &7002381419506676794 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2468028753576640433} + - component: {fileID: 5396192429513740654} + m_Layer: 8 + m_Name: Trail + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!4 &2468028753576640433 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7002381419506676794} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -0.032, y: 0.627, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 711236274234327174} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!96 &5396192429513740654 +TrailRenderer: + serializedVersion: 3 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7002381419506676794} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 0 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: bbf6c47920b8378488083e25f9ab31e1, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Time: 1 + m_PreviewTimeScale: 1 + m_Parameters: + serializedVersion: 3 + widthMultiplier: 0.74 + widthCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 1 + value: 0 + inSlope: -3.2915306 + outSlope: -3.2915306 + tangentMode: 0 + weightedMode: 0 + inWeight: 0.0218094 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + colorGradient: + serializedVersion: 2 + key0: {r: 1, g: 1, b: 1, a: 1} + key1: {r: 1, g: 1, b: 1, a: 1} + key2: {r: 0, g: 0, b: 0, a: 0} + key3: {r: 0, g: 0, b: 0, a: 0} + key4: {r: 0, g: 0, b: 0, a: 0} + key5: {r: 0, g: 0, b: 0, a: 0} + key6: {r: 0, g: 0, b: 0, a: 0} + key7: {r: 0, g: 0, b: 0, a: 0} + ctime0: 0 + ctime1: 65535 + ctime2: 0 + ctime3: 0 + ctime4: 0 + ctime5: 0 + ctime6: 0 + ctime7: 0 + atime0: 0 + atime1: 65535 + atime2: 0 + atime3: 0 + atime4: 0 + atime5: 0 + atime6: 0 + atime7: 0 + m_Mode: 0 + m_ColorSpace: -1 + m_NumColorKeys: 2 + m_NumAlphaKeys: 2 + numCornerVertices: 6 + numCapVertices: 0 + alignment: 1 + textureMode: 0 + textureScale: {x: 1, y: 1} + shadowBias: 0.5 + generateLightingData: 0 + m_MinVertexDistance: 0.1 + m_MaskInteraction: 0 + m_Autodestruct: 0 + m_Emitting: 1 + m_ApplyActiveColorSpace: 1 --- !u!1 &7390605608055178527 GameObject: m_ObjectHideFlags: 0 @@ -34,6 +182,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 8232855175872471746} + - {fileID: 2468028753576640433} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &3623051023707969355 @@ -69,8 +218,8 @@ MonoBehaviour: - actor: m_AssetGUID: 50a5e87baaedf5b46ba52646e8e88b74 m_SubObjectName: - m_SubObjectGUID: m_SubObjectType: + m_SubObjectGUID: m_EditorAssetChanged: 0 slotName: dagger_left handsAnimationClipsSets: diff --git a/Assets/jelycho/core/materials/m_weapon_trail.mat b/Assets/jelycho/core/materials/m_weapon_trail.mat new file mode 100644 index 0000000..c01a562 --- /dev/null +++ b/Assets/jelycho/core/materials/m_weapon_trail.mat @@ -0,0 +1,157 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-3534035237265524349 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: m_weapon_trail + m_Shader: {fileID: 4800000, guid: 8516d7a69675844a7a0b7095af7c46af, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: + - _FLIPBOOKBLENDING_OFF + m_LightmapFlags: 0 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BlendOp: 0 + - _BumpScale: 1 + - _CameraFadingEnabled: 0 + - _CameraFarFadeDistance: 2 + - _CameraNearFadeDistance: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _ColorMode: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DistortionBlend: 0.5 + - _DistortionEnabled: 0 + - _DistortionStrength: 1 + - _DistortionStrengthScaled: 0 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EmissionEnabled: 0 + - _EnvironmentReflections: 1 + - _FlipbookBlending: 0 + - _FlipbookMode: 0 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _LightingEnabled: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _SmoothnessSource: 0 + - _SmoothnessTextureChannel: 0 + - _SoftParticlesEnabled: 0 + - _SoftParticlesFarFadeDistance: 1 + - _SoftParticlesNearFadeDistance: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0} + - _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/jelycho/core/materials/m_weapon_trail.mat.meta b/Assets/jelycho/core/materials/m_weapon_trail.mat.meta new file mode 100644 index 0000000..bf026b7 --- /dev/null +++ b/Assets/jelycho/core/materials/m_weapon_trail.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bbf6c47920b8378488083e25f9ab31e1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: