Hello, so I followed the course and completed it, however, I do have a couple of bugs. First off I don’t have any errors or crashes, so finding the exact reason why these are happening are hard.
This is a video of all my current bugs, as you can see the enemy can hit me twice but can’t do any damage after that.
The 2nd bug you can also see is that when I get hit the character moves too deep into the floor. I know the reason is that the character’s controller is at their knees and not at their feet, I had to add different numbers than are given in the series. However in this video, you can see if I do swap it to the correct numbers the character is floating off the ground and I am not sure why, despite having the same stuff as the series had.
In this video, I switch the character controller to the right values, but as you can see I am off the floor.
I am not sure what scripts/values I should give to help lead you in the right direction for the bugs though.
Here is the enemy attacking state
public class EnemyAttackingState : EnemyBaseState
{
private readonly int AttackHash = Animator.StringToHash("Attack");
private const float TransitionDuration = 0.1f;
public EnemyAttackingState(EnemyStateMachine stateMachine) : base(stateMachine)
{
}
public override void Enter()
{
stateMachine.Weapon.SetAttack(stateMachine.AttackDamage, stateMachine.AttackKnockback);
stateMachine.Animator.CrossFadeInFixedTime(AttackHash, TransitionDuration);
}
public override void Tick(float deltaTime)
{
if (GetNormalizedTime(stateMachine.Animator, "Attack") >= 1)
{
stateMachine.SwitchState(new EnemyChasingState(stateMachine));
}
FacePlayer();
}
public override void Exit()
{
}
}
and the chasing state
public class EnemyChasingState : EnemyBaseState
{
private readonly int locomotionHash = Animator.StringToHash("Locomotion");
private readonly int SpeedHash = Animator.StringToHash("Speed");
private const float CrossFadeDuration = 0.1f;
private const float AnimatorDampTime = 0.1f;
public EnemyChasingState(EnemyStateMachine stateMachine) : base(stateMachine)
{
}
public override void Enter()
{
stateMachine.Animator.CrossFadeInFixedTime(locomotionHash, CrossFadeDuration);
}
public override void Tick(float deltaTime)
{
Move(deltaTime);
if (!IsInChaseRanger())
{
stateMachine.SwitchState(new EnemyIdleState(stateMachine));
return;
}else if(IsInAttackRange())
{
stateMachine.SwitchState(new EnemyAttackingState(stateMachine));
return;
}
MoveToPlayer(deltaTime);
FacePlayer();
stateMachine.Animator.SetFloat(SpeedHash, 1f, AnimatorDampTime, deltaTime);
}
public override void Exit()
{
stateMachine.agent.ResetPath();
stateMachine.agent.velocity = Vector3.zero;
}
private void MoveToPlayer(float deltaTime)
{
if(stateMachine.agent.isOnNavMesh)
{
stateMachine.agent.destination = stateMachine.Player.transform.position;
Move(stateMachine.agent.desiredVelocity.normalized * stateMachine.MovementSpeed, deltaTime);
}
stateMachine.agent.velocity = stateMachine.Controller.velocity;
}
private bool IsInAttackRange()
{
if(stateMachine.Player.IsDead) { return false; }
float playerDistanceSqr = (stateMachine.Player.transform.position - stateMachine.transform.position).sqrMagnitude;
return playerDistanceSqr <= stateMachine.AttackRange * stateMachine.AttackRange;
}
}
also, the targeted.cs
public class Targeter : MonoBehaviour
{
[SerializeField]
private CinemachineTargetGroup cineTargetGroup;
private Camera maincamera;
private List<Target> targets = new List<Target>();
public Target CurrentTarget { get; private set; }
private void Start()
{
maincamera = Camera.main;
}
private void OnTriggerEnter(Collider other)
{
Target target = other.GetComponent<Target>();
if (target == null) { return; }
targets.Add(target);
target.OnDestroyed += RemoveTarget;
}
private void OnTriggerExit(Collider other)
{
Target target = other.GetComponent<Target>();
if(target == null) { return; }
RemoveTarget(target);
}
public bool SelectTarget()
{
if(targets.Count == 0)
{
return false;
}
Target closestTarget = null;
float closestTargetDistance = Mathf.Infinity;
foreach(Target target in targets)
{
Vector2 viewPos = maincamera.WorldToViewportPoint(target.transform.position);
if(!target.GetComponentInChildren<Renderer>().isVisible)
{
continue;
}
Vector2 toCenter = viewPos = new Vector2(0.5f, 0.5f);
if(toCenter.sqrMagnitude < closestTargetDistance)
{
closestTarget = target;
closestTargetDistance = toCenter.sqrMagnitude;
}
}
if(closestTarget == null) { return false; }
CurrentTarget = closestTarget;
cineTargetGroup.AddMember(CurrentTarget.transform, 1f, 2f);
return true;
}
public void Cancel()
{
if(CurrentTarget == null) { return; }
cineTargetGroup.RemoveMember(CurrentTarget.transform);
CurrentTarget = null;
}
private void RemoveTarget(Target target)
{
if(CurrentTarget == target)
{
cineTargetGroup.RemoveMember(CurrentTarget.transform);
CurrentTarget = null;
}
target.OnDestroyed -= RemoveTarget;
targets.Remove(target);
}
}