working on zombie ai

This commit is contained in:
2025-10-10 18:08:54 +02:00
parent 8cee5fbf9e
commit 128166317d
13 changed files with 149 additions and 13 deletions

View File

@@ -0,0 +1,26 @@
using System;
using Unity.Behavior;
using UnityEngine;
using Action = Unity.Behavior.Action;
using Unity.Properties;
[Serializable, GeneratePropertyBag]
[NodeDescription(name: "FindClosestAttackTarget", story: "Agent finds Target", category: "Action", id: "c335cdd99cc546403f5ca3cd5c5e2fa3")]
public partial class FindClosestAttackTargetAction : Action
{
protected override Status OnStart()
{
return Status.Running;
}
protected override Status OnUpdate()
{
return Status.Success;
}
protected override void OnEnd()
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fe9e1ad43b36c214389aa56933a4b4f9

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.CompilerServices;
using Animancer;
using RebootKit.Engine.AI;
using RebootKit.Engine.Extensions;
using RebootKit.Engine.Main;
using RebootKit.Engine.Network;
@@ -9,8 +11,8 @@ using TriInspector;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using Logger = RebootKit.Engine.Foundation.Logger;
using UnityEvent = UnityEngine.Events.UnityEvent;
namespace RebootReality.jelycho.Enemies {
public class ZombieActorData : IActorData {
@@ -58,6 +60,10 @@ namespace RebootReality.jelycho.Enemies {
}
}
}
public class ZombieBlackboard {
public ZombieActor Self;
}
[DeclareBoxGroup("Body parts")]
public class ZombieActor : Actor, IKillable {
@@ -74,7 +80,7 @@ namespace RebootReality.jelycho.Enemies {
Berserk
}
[SerializeField] Animator m_Animator;
[SerializeField] AnimancerComponent m_Animancer;
[SerializeField] NavMeshAgent m_NavAgent;
@@ -98,12 +104,24 @@ namespace RebootReality.jelycho.Enemies {
float m_NextAttackTimer;
public UnityEvent died = new UnityEvent();
BehaviourTree m_BehaviourTree;
//
// @MARK: Unity callbacks
//
void Awake() {
SetRagdollLocal(false);
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);
}
//
@@ -117,7 +135,7 @@ namespace RebootReality.jelycho.Enemies {
}
float velXZ = m_NavAgent.velocity.With(y: 0).magnitude;
m_Animator.SetFloat(s_MovementSpeedHash, velXZ);
// m_Animator.SetFloat(s_MovementSpeedHash, velXZ);
}
public override void OnServerTick(float deltaTime) {
@@ -127,6 +145,9 @@ namespace RebootReality.jelycho.Enemies {
s_Logger.Error("Invalid world context");
return;
}
m_BehaviourTree.Process(deltaTime);
return;
switch (m_State) {
case AIState.Idle: {
@@ -190,7 +211,7 @@ namespace RebootReality.jelycho.Enemies {
if (distToPlayerSq <= m_MaxAttackDistance * m_MaxAttackDistance) {
m_NextAttackTimer -= dt;
if (m_NextAttackTimer <= 0.0f) {
m_Animator.CrossFade("Attack_0", 0.0f, 0);
// m_Animator.CrossFade("Attack_0", 0.0f, 0);
m_NextAttackTimer = m_AttackDelay;
}
@@ -284,7 +305,7 @@ namespace RebootReality.jelycho.Enemies {
ragdollRigidbody.isKinematic = !active;
}
m_Animator.enabled = !active;
m_Animancer.enabled = !active;
}
//