Alright, I followed through a bit and I think It’s working now - not entirely sure, though I haven’t been able to reproduce the bug.
I had a script (which I completely forgot about, sorry @Brian_Trotter) that handled picking up gold on trigger enter (filter player tag). I think that it got picked up, but didn’t call the remove event - which caused it to be stuck as current target.
After I added the print,
noticed the bug happens mostly when I fight and kill enemies near the loot.
and that I often had some gold (not a lot though) in my inventory but nothing else.
For anyone who might find this useful (as simple as it might be ):
Here is an updated version I created for my OnEnterPickup.cs,
OnEnterPickup.cs
using RPG.Inventories;
using UnityEngine;
[RequireComponent(typeof(PickupTarget))]
public class OnEnterPickup : MonoBehaviour
{
[SerializeField] private PickupTarget pickupTarget;
private void OnEnable()
{
pickupTarget = GetComponent<PickupTarget>();
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
pickupTarget.PickupItem();
}
}
}
I made it so it calls the method from “PickupTarget” so It doesn’t have to subscribe to the event itself just call the method from the target to handle everything - and still be a component that I can throw on any item I think should be picked up automatically
It appears that enemy animators are sort of bugged at the moment - Pausing the game causes their forward speed to become NaaN, and they dont recover from that automatically on state transitions.
here are the prints from deltaMovement calculation on PatrollingState / Chasing State + animator window:
while unpausing makes gross speed update, it doesn’t update the “FreeLookSpeed” parameter
(recreated on demo project as well)
Any takes on a fix?
EnemyPatrollingState.Tick():
public override void Tick(float deltaTime)
{
if (IsInChaseRange())
{
//Clearing key to ensue that at the end of the battle, the enemy finds the enarest wayopoint
stateMachine.Blackboard.Remove(NextPatrolPointIndexKey);
stateMachine.SwitchState(new EnemyChasingState(stateMachine));
return;
}
if (IsInAcceptanceRange())
{
//Once were close enough t the waypoint we head to a Dwell state
stateMachine.SwitchState(new EnemyDwellState(stateMachine, dwellTime));
return;
}
//This code is the same as out chase state
Vector3 lastPosition = stateMachine.transform.position;
MoveToWayPoint(deltaTime);
Vector3 deltaMovement = lastPosition - stateMachine.transform.position;
float deltaMagnitude = deltaMovement.magnitude;
float grossSpeed = deltaMagnitude / deltaTime;
stateMachine.Animator.SetFloat(FreeLookSpeedHash, grossSpeed / stateMachine.MovementSpeed,
stateMachine.AnimatorDampTime, deltaTime);
Debug.Log(
$"FreeLookSpeed: {grossSpeed / stateMachine.MovementSpeed} grossSpeed: {grossSpeed} , movementSpeed: {stateMachine.MovementSpeed}");
if (deltaMagnitude > 0)
{
FaceTarget(stateMachine.transform.position - deltaMovement, deltaTime);
}
else
{
FaceTarget(targetPatrolPoint, deltaTime);
}
}
Ok, I took a look, and as it turns out, even when TimeScale is set to 0, Update() is still called, but deltaTime is zero, and this is where our issue lies.
If deltaTime is zero, then dividing the magnitude/deltaTime creates the NaN.
Simply starting the Tick() in Patrol and Chasing State with
I was going to touch on that at a certain point, but I was going to point out that it is a creative decision. In reality, if you throw a punch at the bad guy and it hits your best buddy by accident, your best buddy still gets a black eye. Friendly fire is unfortunately the way of reality.
In my personal project, each character (including the player) gets a Team, and the teams have allies and enemies (a bit like the Physics Layer overlaps). That lets me have NPCs actually attacking each other (sort of like in World of Warcraft).
This sound incredible! Seems like a very cool way to set up player and npcs getting into random events together (i.e. ambushes, camp attacks etc)
I just might yoink that idea in the future
Thanks for the help Brian, I have a midterm showcase today and Im crunching to get some stuff working after the merge (No, I did not heed the warnings. The horror! )
Meanwhile I got my dodge and AOE Stun ability working for now, and worked on some animations.
Had to make a state specific SwitchState Effect strategy to get the player stomping, but for now it’s good enough
This is from yesterday + this last hour’s work (it’s 7:30AM here)
lol don’t be surprised, but this idea was on my radar for a while… just that my project is in no way stable to even think of implementing this (or any new ideas in general) anytime soon
Good day Brian. After the agent disabling line of code, which script do we integrate the ‘minimumImpactVelocity’ and ‘smoothDamping’ scripts into? Instructions unclear, apologies (P.S: It’ll probably be a while before I can test this out. My laptop recently became insanely slow, and I have no idea why…)
And since we’re already here, what’s the next step?
Bahaa, right above where you quoted the tutorial, it says to add this to ForceReciever. If you look at the bottom of the page, there is a link to a complete list of all the changes Brian made in this lesson. Scroll down to the ForceReciever.cs entry and it shows every line that is added or removed. This is one of many amazing benefits of using source control. Also at the bottom of the page it shows the title of what is next. In this case, it is impact states. He is still basically following the order from the 3rd person class.
he did mention the Force Receiver for the first part, but looking at the bottom function of the image I quoted, there’s no declaration of where exactly does the impact (or the lines that follow along) go to… hence why I’m confused
lol I’m not sure if my page is somehow different,but at the end of the screenshot I uploaded, there’s… well… no git changes or any indication of what’s next
Edit: I REFRESHED the page, now I see what you’re talking about…
All of the code in the drop down section goes in ForceReceiver. BTW, you probably should have put that screen shot in a spoiler. It is the answer to a challenge and other students might not want to see it.
This line is the last line in the Update() method. The rest of the lines in that code are added.
As a rule of thumb, if I switch to a different script in a section, I will say so in the text.
So if I say “In ForceReceiver”, everything after that will be in ForceReceiver until I say something like, “Now in EnemyBaseState” (or some other script).
For the most part, going forward, this will be the format, rather than wholesale pasting of the entire method. Three reasons:
It makes you look more closely at your existing code to piece in what we’re adding
Some of these scripts are getting pretty long, so it seems a bit silly to keep posting the entire text.
The completed scripts are available in each page’s GitLab commit.
If you kill an enemy, quit to the main menu and return, and then kill another enemy, or maybe even get close to any sort of pickup and hit the ‘P’ key (the one assigned to pickup items off the ground), you’ll get this error from time to time:
MissingReferenceException while executing 'performed' callbacks of 'Player/Pickup[/Keyboard/p]'
UnityEngine.InputSystem.LowLevel.NativeInputRuntime/<>c__DisplayClass7_0:<set_onUpdate>b__0 (UnityEngineInternal.Input.NativeInputUpdateType,UnityEngineInternal.Input.NativeInputEventBuffer*)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate (UnityEngineInternal.Input.NativeInputUpdateType,intptr)
MissingReferenceException while executing 'performed' callbacks of 'Player/Pickup[/Keyboard/p]'
UnityEngine.InputSystem.LowLevel.NativeInputRuntime/<>c__DisplayClass7_0:<set_onUpdate>b__0 (UnityEngineInternal.Input.NativeInputUpdateType,UnityEngineInternal.Input.NativeInputEventBuffer*)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate (UnityEngineInternal.Input.NativeInputUpdateType,intptr)
If I’m not mistaken, I think last time I dealt with something like this, when working on the Resource Gathering System, it was fixed by unsubscribing from an event of some sort, but… that’s not the case for me now, and here’s what I currently have in ‘PickupFinder.cs’:
using System.Linq;
using RPG.Core;
using UnityEngine;
namespace RPG.Inventories
{
public class PickupFinder : RangeFinder<PickupTarget>
{
public PickupTarget GetNearestPickup()
{
CurrentTarget = Targets.OrderBy(t => Vector3.Distance(transform.position, t.transform.position)).FirstOrDefault();
return CurrentTarget;
}
protected override void AddTarget(PickupTarget target)
{
base.AddTarget(target);
target.OnPickedUp += RemoveTarget;
Debug.Log($"Pickup Finder: Adding {target.name}");
}
protected override void RemoveTarget(PickupTarget target)
{
base.RemoveTarget(target);
target.OnPickedUp -= RemoveTarget;
Debug.Log($"Pickup Finder: Removing {target.name}");
}
}
}
Any idea where else do I need to change my code to fix this?