#I cant push the enemy because its following me

1 messages Β· Page 1 of 1 (latest)

trail sorrel
trail sparrow
trail sorrel
#

it is not disabling as I can see

trail sparrow
#

Alright, before proceeding, there is a minor naming convention issue.

private GameObject GameObject;
//..
public GameObject gameobject;

That practice is very discouraged, as it easily leads to confusion.
While it is possible, it is rarely practical, especially when others read it.
This would be better:

private GameObject _other;
//..
public GameObject Other;
#

Now, inside ScriptFalse()

    private void ScriptFalse()
    {
        Other.GetComponent<EnemyMovement>().enabled = false;
        Debug.Log("Disabled EnemyMovement for: " + Other.name); // Add this <--
    }
trail sorrel
trail sparrow
#

Correcting your existing variable names.

trail sorrel
#

I have only one here

trail sparrow
#

There are two scripts.

trail sorrel
#

okay I did things you said playing

trail sparrow
#

playing?

#

to be clear: The scripts are to be changed before entering Play Mode.

trail sorrel
trail sparrow
#

ok

#

Any progress?

trail sorrel
#

Its like blinking

#
        if (physicsPickupScript != null && physicsPickupScript.hold == true)
        {
            ScriptFalse();
            if (Input.GetKeyDown(KeyCode.F))
            {
                ScriptFalse();
                
            }
        }```
#

I changed this like that

#

just tried

#

still enables it even when hold is true

#

Its getting enabled and disabled repeatedly while I am holding

trail sparrow
#

Ah yes, I see why

#
    private void Update()
    {
        if (physicsPickupScript != null && physicsPickupScript.hold == true)
        {
            ScriptFalse(); // <--- This will always run when Hold == true. 
            if (Input.GetKeyDown(KeyCode.F))
            { 
                Invoke("ScriptTrue", 2);
            }
        }

        if (physicsPickupScript != null && physicsPickupScript.hold == false)
        {
            Invoke("ScriptTrue",2); 
        }
    }

@trail sorrel

#

wait, that's not right

#

(it's late here)

#

Can you show the pickup script?

#

PS: It's beyond midnight here, and if you don't respond fast, I'll probably get distracted.

trail sparrow
#

Alright.
Since the SomeScript is depending on another script's hold property, things could get difficult to debug.
Instead of polling with complex if-chains, it's possible to simplify this by calling Public methods on other scripts, ultimately allowing them to control themselves, instead of each other.

Before I continue, are you following a tutorial?
@trail sorrel

trail sorrel
#

I followed

#

but not right now

trail sparrow
#

if you're done with the tutorial, that is fine
if not, it might cause trouble later

trail sorrel
#

I'm done

#

hold is true but it enables and disables did the debug.log in somescript

trail sparrow
#

I'm making assumptions of how your game works, so correct me if I'm wrong.

In your PhysicsPickup script you have a Raycast.
In that raycast (if it hits), you can do hit.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy)

trail sorrel
#

which line do you mean 55?

trail sparrow
#

there is only one Raycast in the entire script

#

yes

#

Then you can make a Public method in the EnemyMovement script
and use that if the raycast hits.

trail sorrel
#

should I add hit.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy) under if or in the pharanthesis

trail sparrow
#
if (Raycast(...)) // True when hitting something. 
{
    // This only happens if the Raycast hits a collider. 
}
#

inside the { brackets }

trail sorrel
#

But I still need to add the hold variable I think

#

because shouldnt it disable the script when I look at the enemy

trail sparrow
#

There are more things to do, yes.

#

If I understand your code correctly,
void grav() should reverse the process

#

Though it's a bit tricky to follow what happens.

trail sorrel
#

you mean like = !usegravity

trail sparrow
#

I mean the method itself

#

grav()

#

btw all methods should be PascalCase()

#

private fields should be _camelCase prefixed with

trail sorrel
#

I didnt know it thanks

trail sparrow
#

_

#

and Properties should be PascalCase, but never the same name as its type

trail sorrel
#

where do I get the name hit

trail sparrow
#

local variables (inside methods) have camelCasing without _

trail sparrow
trail sorrel
#

what is mine called if you can see , I dont know much about this raycast thing

trail sparrow
#

did you not write this code yourself?

trail sorrel
#

I took it from the tutorial

trail sparrow
#

link the tutorial

trail sorrel
#

I got the picking up and then wrote other one myself

#

I dont remember but I think

trail sparrow
#

Are the variable names from the tutorial?

trail sorrel
#

probably some of them

trail sorrel
trail sparrow
#

I'm sure it gets the desired result, but that tutorial has no idea of C# naming convention, which makes it a bad tutorial.
There's enough to learn, so we don't need confusion πŸ˜†

trail sorrel
trail sparrow
#

So anyway, the tutorial assumes people know how Raycasts work.

Raycast has a number of different overloads.
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

out RaycastHit is in some of them.

out means it's not an argument the method absorbs, but an argument to which a result is given.
RaycastHit contains information about the hit

RaycastHit hit;
if(Raycast(..., out hit, ...))
{
    Debug.Log(hit.gameObject.name)
}

Can also be written like this, to avoid an unnecessary line of code.

if(Raycast(..., out RaycastHit hit, ...))
{
    Debug.Log(hit.gameObject.name)
}
#

so if the Raycast actually hits something, everything in the if-statement will run

#

hit doesn't exist outside the if-statement, unless you declare it, like the first example

trail sorrel
#
                    if (Physics.Raycast(CameraRay, out hit, PickupRange, PickupMask))
                    {
                        hit.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
                        CurrentObject = hit.rigidbody;
                        CurrentObject.useGravity = false;
                    }``` I get 'RaycastHit' does not contain a definition for 'gameObject' and no accessible extension method 'gameObject' accepting a first argument of type 'RaycastHit' could be found (are you missing a using directive or an assembly reference?) on the line starting with hit
#

is it because I havent got a gameObject

trail sparrow
#

Minor mistake from my side.
RaycastHit doesn't directly reference gameObject.
But you can get it from either collider, rigidbody or transform

trail sorrel
#

πŸ‘

trail sparrow
#

name also exists on all those, so gameObject isn't necessary

#

Next:
private Rigidbody CurrentObject;
should be changed into
private EnemyMovement CurrentObject;

trail sorrel
#
                    if (Physics.Raycast(CameraRay, out hit, PickupRange, PickupMask))
                    {
                        if (hold == true)
                        {
                            hit.rigidbody.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
                            
                        }``` its like that now
trail sparrow
#

EnemyMovement should implement a public method named GetPickedUp()
And a method named GetDropped()

run CurrentObject.GetPickedUp() from the raycast if-statement
run CurrentObject.GetDropped() from grav()

trail sorrel
#

I should get the disabling line under hit.rigidbody.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
right

trail sparrow
#

not sure about 'disabling line', but I'll make it clear in a sec

#
if (Raycast...) 
{
    hit.rigidbody.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
    if (enemy) 
    {
        enemy.GetPickedUp();
        CurrentObject = enemy;
    }
}
trail sorrel
#

is enemy here gameobjects name

trail sparrow
#

it's the same gameobject, but different component

#

While this current code example uses the EnemyMovement component,
that is going to be changed last, so that any type of script can be picked up, if implemented.

trail sorrel
#

is there something about the enemys name in hierarchy there?

trail sparrow
#

What do you mean?

trail sorrel
#

one of them is Enemy other one is Enemy (1)

trail sparrow
#

their names mean nothing in this code

#

the only reason we used Debug.Log(name) earlier, was to confirm which object was being hit

trail sorrel
#

hit.rigidbody.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
Cannot implicitly convert type 'EnemyMovement' to 'UnityEngine.Rigidbody'

#

what do you reccomend after hit in first line here

trail sparrow
#

hit.transform.gameObject

#

not rigidbody πŸ˜…

trail sorrel
#
                            if (enemy)
                            {
                                enemy.GetPickedUp();
                                CurrentObject = enemy;
                            }
                        }
                        CurrentObject = hit.transform;
                        CurrentObject.useGravity = false;```
is this true?
#

Cannot implicitly convert type 'UnityEngine.Transform' to 'UnityEngine.Rigidbody'
Cannot implicitly convert type 'EnemyMovement' to 'UnityEngine.Rigidbody'

trail sparrow
#

No. This is:

if (Raycast...) 
{
    hit.transform.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
    if (enemy) 
    {
        enemy.GetPickedUp();
        CurrentObject = enemy;
    }
}
#

useGravity will be moved to the EnemyMovement script, inside GetPickedUp() and GetDropped()

trail sorrel
#

okay

#

CurrentObject = hit.transform;
CurrentObject.useGravity = false;
so deleting these

trail sparrow
#

yes, it should look exactly like what I posted, minus the simplified raycast

trail sorrel
#

Cannot implicitly convert type 'EnemyMovement' to 'UnityEngine.Rigidbody'

trail sparrow
#

If you don't want to delete, you can
Comment by selecting the lines and pressing CTRL + K + C
Uncomment by CTRL + K + U

trail sparrow
#

go to the declaration of CurrentObject, and change its type from Rigidbody to EnemyMovement

#

This is the declaration:

private Rigidbody CurrentObject;
trail sorrel
#

okay I changed it get some errors

#

about functions

#

Getpickedup ,usegravity ,velocity and position

trail sparrow
#

Hm. I didn't consider the FixedUpdate, sec

#

go to the EnemyMovement script and create the public methods GetPickedUp() and GetDropped()

trail sparrow
#

Hm, I'm not sure I have the brainpower to work through this obstacle right now.
But we can work around it.
My idea was to limit direct control to each class for itself, and keep other interactions via methods.
You can probably fix that later, but it might Not be necessary.

#

So to work around it, change CurrentObject back to Rigidbody
and I'll rewrite the Raycast

#

below the declaration of CurrentObject
make a private EnemyMovement CurrentMovement;

#
if (Raycast...) 
{
    hit.transform.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
    if (enemy) 
    {
        enemy.GetPickedUp();
        CurrentObject = hit.rigidbody;
        CurrentMovement = enemy;
    }
}
trail sorrel
#

I got no errors now

trail sparrow
#

Good.
Then add

CurrentMovement.GetDropped();

into grav()

trail sorrel
#

Getdropped and getpickedup are still empty

trail sparrow
#

as well as

CurrentMovement = null;
trail sorrel
trail sparrow
#

yes

#

at the end

trail sorrel
#

πŸ‘

trail sparrow
#

In EnemyMovement add a private bool _canMove = true;
In GetPickedUp() set _canMove = false;
in GetDropped() set _canMove = true;

in FixedUpdate() add this line at the top:

if (_canMove == false) return;
#

if that statement is true, the rest of FixedUpdate won't be run, because it returns early

#

thus cancelling the movement
just as effectively as disabling the script should
but more flexible, as we can still do things with the script

trail sorrel
#

The name '_canMove' does not exist in the current context

trail sparrow
#

The first instruction up there

#

In EnemyMovement add a private bool _canMove = true;

trail sparrow
#

post the full script

trail sorrel
#

enemy movemnt

trail sparrow
#

yes

trail sorrel
trail sparrow
#

Alright. No errors?

#

I think it should be ready for testing now.

trail sorrel
trail sparrow
#

Hm. It is there, though.

#

Copy the error and post it here.

trail sorrel
#

Assets\PhysicsPickup.cs(113,13): error CS0103: The name '_canMove' does not exist in the current context

#

if (_canMove == false) return;

#

ohh

trail sparrow
#

it shouldn't be in that script
That line is supposed to be inside EnemyMovement.FixedUpdate()

trail sorrel
#

I forgot about fixed update in enemymovement

trail sparrow
#

Good stuff.
Try it out now, and see if it all works or not.

trail sorrel
#

trying

#

okay I can throw it properly

#

when I throw it doesn walk anymore

trail sparrow
#

Hm. Post your Pickup script.

trail sorrel
#

trying one more time

trail sparrow
#

so when you throw the enemy, it doesn't follow the player anymore
but it was moving before picking it up?

trail sparrow
#

Did this somehow work before my changes?

trail sorrel
#

and it was following

trail sparrow
#

hm ok

trail sorrel
#

We have nothing about SomeScript right?

#

so I can remove it from enemy

trail sparrow
#

inside GetDropped()
try setting velocity to Vector3.zero

#

might not work, due to the throwing.
I'm not sure what comes first.

#

actually, now I realize

#

kinematic

#

hm, maybe that's not it

trail sorrel
trail sparrow
#

yes, do try and see if it helps

trail sorrel
#

like rigidbody.velocity

trail sparrow
#

yes

trail sorrel
#
    {
        _canMove = true;
        rb.velocity = new Vector3(0, 0, 0);
    }```
trail sparrow
#

Vector3.zero also works

trail sorrel
#

after I throw

#

when I press e one more time

#

enemy starts moving

#

maybe thats because somescript I didnt remove it

trail sorrel
#

_canmove gets false but doesnt get true till I pick enemy

#

up

trail sparrow
#

that's the opposite of what should happen πŸ€”

#

code looks good on my side.
Did you update anything?

#

add a Debug.Log() to GetDropped()

#

add one to GetPickedUp() as well

trail sorrel
#

when I drop enemy it resumes following

#

but when I throw it doesnt

#

it calls get dropped function only when I press e

#

thats the reason I think

trail sparrow
#

Sounds good. Let's stare at some code.

#

Line 99 in PhysicsPickup

#

I need a few moments to come up with how this should be.
The enemy needs a GetThrown() method

trail sorrel
#

If you are tired we can continue later you said it is midnight

trail sparrow
#

In the EnemyMovement script, on the top or bottom, add the following:

private enum EnemyState
{
    Moving,
    NotMoving,
    Thrown
}
#

Do you know about enums?

trail sorrel
#

I have never heard about them

trail sparrow
#

enums are numbers disguised as text

#
private enum EnemyState
{
    Moving = 1,
    NotMoving = 2,
    Thrown = 3
}
trail sorrel
#

oh okay

trail sparrow
#

they can have any number
the numbers are mostly important for other things

#

Since the Enemy will have more than two states,
it will be much more easy to keep track of the code logic, if we use a switch (aka state machine)

#
private EnemyState _state;

private void FixedUpdate()
{
    switch (_state)// Autocomplete here, and it should create the entire switch
}
#

do Not delete anything yet

trail sorrel
#

which script

trail sparrow
#

EnemyMovement

trail sorrel
#

ok

trail sparrow
#

in case it doesn't autocomplete, like it didn't for me just now

switch (_state)
{
    case EnemyState.Moving:
        // All the existing FixedUpdate() code goes here, minus the first line that returns
        break;
    case EnemyState.NotMoving:
        break;
    case EnemyState.Thrown:
        break;
}
#

However

#

instead of placing the code directly in the switch

#

make a method

#

and call it from the switch

#

(much more readable)

trail sorrel
#

The type or namespace name 'EnemyState' could not be found (are you missing a using directive or an assembly reference?)

#

I got this error

trail sparrow
#

private enum EnemyState _state;

#

and you need to create the enum

#
private enum EnemyState
{
    Moving = 1,
    NotMoving = 2,
    Thrown = 3
}
#

Note: EnemyState might be a bad word. It could be InternalState.

trail sorrel
#

okay got rid of it

trail sparrow
#

the variable name, yes

trail sorrel
#

because I got an error

#

The name '_state' does not exist in the current context

trail sparrow
#

This was supposed to be declared:

private EnemyState _state;
trail sorrel
#

I thout we made something wrong about a line but it was a different line

#

now codes okay

trail sparrow
#

Good. Have you moved all the code from FixedUpdate() into a separate method?

#

(minus the switch)

trail sorrel
#

// All the existing FixedUpdate() code goes here, minus the first line that returns

#

I put them here

trail sparrow
trail sorrel
#

where should I put the first line that returns

trail sparrow
#
switch (_state)
{
    case EnemyState.Moving:
        Moving();
        break;
    case EnemyState.NotMoving:
        NotMoving();
        break;
    case EnemyState.Thrown:
        BeingThrown();
        break;
}
trail sparrow
trail sorrel
#

okay I deleted

trail sparrow
#

Now, make sure all the movement code is in Moving() or some other named method.
Make NotMoving() even though it's more like DoNothing() right now.
And BeingThrown() is going to have the new code I'll provide

trail sorrel
#

you mean following right by movement code

trail sparrow
#

well, yes, that is a good distinction

trail sorrel
#

what did you meant by Make NotMoving()

#

creating a new

trail sparrow
#

just make an empty method, in case you ever need to add some code there

trail sorrel
#

okay

trail sparrow
#

those methods should be Private

#

Now, add a bool, or rename the previous one we used to: _isFalling

trail sorrel
trail sparrow
#

then make void OnCollisionEnter
(it should auto-complete the rest)

Inside that, we need to detect when the Enemy should start following again.
Usually by detecting that something in the Ground layer was hit.
Does your game have a Ground layer?

trail sorrel
#

its in ui layer

trail sparrow
#

you're using the UI Layer as the Ground layer?

trail sorrel
trail sparrow
#

Probably best to dedicate a separate layer, or use Default layer

#

UI as ground is confusing πŸ˜†

#

Does this appear to you?

trail sorrel
#

okay it did

#

I copied it

#

thats why i think

trail sparrow
#

ok

#

ANyway, keep UI as ground for now

#

To reduce the amount of chaos

#

I take it the Ground objects are already in the UI Layer?

trail sorrel
#

there is only a plain as ground

#

in ui layer

trail sparrow
#

ok

#

Are you familiar with LayerMask?

public LayerMask _groundLayer; // Choose layer(s) in the inspector.
trail sorrel
#

I used once

trail sparrow
#

it's essentially a sequence of bits (00110101)
an On/Off bit for each of the 32 layers in Unity

#

It can have none, all, or any combination of layers.

#

Add that variable to your script.

trail sorrel
#

added and chose ui in inspector

trail sparrow
#

Then, inside OnCollisionEnter()

if (collision.collider.gameObject.layer == _groundLayer)
{
    _isFalling = false; // Declare this also, in the script (private bool)
}
trail sorrel
#

okay

trail sparrow
#

then, add _isFalling to the if-statement

if (_isFalling && collision.collider.gameObject.layer == _groundLayer)
#

Now, in GetThrown() add

_isFalling = true;
#

Finally, in the three Public methods:

// GetPickedUp()
_state = EnemyState.NotMoving;

// GetDropped()
_state = EnemyState.Moving; 

// GetThrown()
_state = EnemyState.BeingThrown; 
_isFalling = true; // already added
#

and in Awake() set _state = EnemyState.Moving

#

After this, test \o/

trail sorrel
#

Maybe I did something wrong but

#

I cant

#

pick up enemies

trail sparrow
#

are all the scripts Saved?

trail sorrel
#

yes

trail sparrow
#

Post them.

trail sparrow
#

check the PickupMask

trail sorrel
#

its on pickup layer

trail sparrow
#

and the enemy is also?

trail sorrel
#

yes

trail sparrow
#

Disable the EnemyMovement component of one enemy.
See if that one can be picked up.

#

it can be done while in Play mode

trail sparrow
#

Any errors?

trail sorrel
#

no

#

I have a pickable barrel

#

and cant pick it up

#

too

trail sparrow
#

Ok. Let me go through my instructions and your scripts.

trail sorrel
#

Man I have to sleep can you please write if you see something I dont know how to thank you for your help

trail sparrow
#

Alright. I'll see what I can find.
You're welcome o/

#

Looks like you removed an ending bracket.
FixedUpdate() is inside void Update() in Pickup

#

Add } before FixedUpdate
and remove the last } at the bottom of the script

#

then CTRL + K + D to auto-correct indentation (for entire script)

trail sorrel
#

Probably thats the wrong thing

#

Thanks bro

trail sparrow
#

Let me know when it works o/

trail sparrow
#

Once the script is complete, there is one last milestone.
This current solution will work for EnemyMovement, but we can make it work for any script we want.

By declaring an interface, these can be implemented by any other class.

public interface IInteractable
{
    public void GetPickedUp();
    public void GetDropped();
    public void GetThrown();
}

Like so:

public class EnemyMovement : MonoBehaviour, IInteractable  // <-- Add IInteractable in declaration

And be used like so:

private IInteractable CurrentMovement;
//..
hit.transform.gameObject.TryGetComponent<IInteractable>(out IInteractable enemy);
#

And however the class implements the behavior, is up to the class itself.

trail sorrel
#

everything is good but when I throw them or drop them they dont follow me

#

maybe thats because they are lying down and cant stand up

#

I freezed the rotation of enemys and tried

#

but that didnt work

#
        {
            case EnemyState.Moving:
                Moving();

                break;
            case EnemyState.NotMoving:
                break;
            case EnemyState.Thrown:
                GetThrown();
                break;
        }```should I delete GetThrown(); here
trail sparrow
#

Alright. Post your updated scripts.

trail sparrow
trail sorrel
#

I changed some in physicspickup

trail sparrow
#

Being a bit distracted here btw, but starting to look now.

#

Ah yes, looks like I didn't do everything with _isFalling and the State

#

might not need the bool

#

in EnemyMovement
copy the switch from FixedUpdate, into OnCollisionEnter
Remove the Moving() method from it.
Move the existing code in OnCollisionEnter into the Thrown state

#

Then replace this

_isFalling = false; // Declare this also, in the script (private bool)

With that

_state = EnemyState.Moving;
#

That might be all.

#

_isFalling can then be completely removed.

#

I expect that will work, but if not, then I have time right now, or in 7 hrs.

#
private void OnCollisionEnter(Collision collision)
{
    switch (_state)
    {
        case EnemyState.Moving:
            break;
        case EnemyState.NotMoving:
            break;
        case EnemyState.Thrown:
            if (collision.collider.gameObject.layer == _groundLayer)
            {
                _state = EnemyState.Moving;
            }
            break;
    }
}
#

Optional:
Instead of setting the state directly to EnemyState.Moving,
you could make a new state EnemyState.Recovering
to add a delay from when it hits the ground, to when it starts moving.

trail sorrel
#

should I delete the switch in fixedupdate

trail sparrow
#

no

#

that remains just as it was

#

the switch is so other code can also be state-specific

#

It's a good way to control complex code.

#

bool _canMove can be removed

trail sorrel
#

I did a debug.log in OnCollisionEnter

#

but it doesnt detect the collision

trail sparrow
#

is your game 3D or 2D?

trail sorrel
#

3d

trail sparrow
#

and the objects have Rigidbody, not Rigidbody2D?

trail sorrel
#

yeah

#

floor doesnt have one

trail sparrow
#

that's fine. Only one of the colliders needs a rigidbody, for a collision event to occur

trail sorrel
#

enemys have

trail sparrow
#

as they should, for movement

#

Screenshot the object hierarchy, while selecting the object with the EnemyMovement script

trail sorrel
#

I changed something

trail sparrow
#

Tell me which object has the Collider

trail sorrel
trail sorrel
#

player has box too

trail sparrow
#

ok. Screenshot the Enemy prefab hierarchy

trail sorrel
#

components?

trail sparrow
#

I want to see all the objects contained within

#

not the components yet

trail sorrel
#

only enemy is contained in enemys hierarchy

trail sparrow
#

ah so it's only one object. simple, ok.

#

Have you changed anything since yesterday, which I did not specify?

trail sorrel
#
                            {
                                CurrentObject = hit.rigidbody;
                                CurrentObject.useGravity = false;
                            }
                            else
                            {
                                hit.transform.gameObject.TryGetComponent<EnemyMovement>(out EnemyMovement enemy);
                                if (enemy)
                                {
                                    enemy.GetPickedUp();
                                    CurrentObject = hit.rigidbody;
                                    CurrentMovement = enemy;
                                }
                            }```
#

I only changed this

#

it detects collision

#

I saw I wrote debug.log to wrong place

trail sparrow
#

Ok. Post your scripts again.

trail sorrel
#

both?

trail sparrow
trail sorrel
#

yes

trail sparrow
#

inside OnCollisionEnter()
in the Thrown > if groundlayer
Add another line below _state = EnemyState.Moving;

rb.rotation = Quaternion.Euler(0,0,0);

@trail sorrel

#

Note that when using Rigidbody for movement, we should not use Transform to move/rotate, because that would be bypassing the physics system

#

Use Inspector Debug mode, to see the Enemy's state while testing

trail sorrel
#

I played but didnt see anything change

trail sparrow
#

Request:
Screenshot the scene, when the enemy has landed, but is not moving.
Have the Enemy object selected, so I can see all the script's values via the inspector.

trail sorrel
#

okay

#

its on not moving

#

and never see thrown there

trail sparrow
#

inside GetThrown()
add Debug.Break()

#

not pause, but break*

#

it will Pause the editor

trail sorrel
#

no nothing happens when I throw

#

it throws but game doesnt pause

trail sparrow
#

in the code you shared, it seems you haven't added GetThrown() in the Pickup script

trail sorrel
trail sparrow
#

should be placed below Line 107 somewhere

trail sorrel
#

how should write it tried enemy.Getthrown

trail sparrow
#

enemy.GetThrown()

trail sorrel
#

current.getthrown gets no errors

trail sparrow
#

actually

#

private EnemyMovement CurrentMovement;

#

so CurrentMovement.GetThrown();

trail sorrel
#

I think it works

#

paused the game

trail sparrow
#

:D

#

alright, remove the Debug.Break() (or comment out)

#

or just, for now, Unpause the Editor

#

so you can see the rest

trail sorrel
#

but now It just stays on thrown

trail sparrow
#

Does it log the ground when hitting it?

#
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log(gameObject.name);
        switch (_state)
        {
            case EnemyState.Moving:
                break;
            case EnemyState.NotMoving:
                break;
            case EnemyState.Thrown:
                if (collision.collider.gameObject.layer == _groundLayer)
                {
                    Debug.Log("Collided with Ground"); // <-- Add this.
                    _state = EnemyState.Moving;
                }
                break;
                
        }
    

        
    }
#

add that debug log

trail sorrel
#

added

trail sparrow
#

check the inspector

#

is ground layermask still good?

#

oh wait

#

My mistake. Layer index != LayerMask

trail sorrel
#

I have to be somewhere like around past 50 I should close pc a few minutes later

trail sorrel
trail sparrow
#
    public static bool HasLayerInMask(LayerMask layerMask, int layerIndex)
    {
        return (layerMask & (1 << layerIndex)) != 0;
    }
#

sec

#

add that method to your Pickup script

#
if (HasLayerInMask(_groundLayer, collision.collider.gameObject.layer))
{
    Debug.Log("Collided with Ground");
    _state = EnemyState.Moving;
}
trail sorrel
#

where am I adding this

trail sparrow
#

it replaces the existing if-statement regarding layers

trail sorrel
#

πŸ‘

trail sparrow
#

LayerMask uses a sequence of bits internally, so the integer it represents, is not the same as a Layer's index, but the sum of all bits/layers enabled in the mask πŸ€¦β€β™‚οΈ

trail sorrel
#

bro it worked thank you so much

trail sparrow
trail sorrel
#

πŸ™

trail sparrow
#

There are 2-3 small things I wish to do before we part ways.

#

Now that your code works, you should look into simplifying it, so you can understand it later.
We're not doing that right now. You can mention me in Official for that purpose later.

The pickup script has a lot of nesting

if (true) 
    if (true)
        if (true)...etc

Nesting is not good for humans to read, so we usually nest max 3 times, and reduce everything to methods.
If you are able to do that, it's much more maintainable.
And to improve it even better, you could make the Pickup script have States as well.

#

Not that I think you want to do that after all this πŸ˜‚
But it's a thought.

trail sorrel
trail sparrow
#

Next: Rewrite Pickup script to work with IInteractable instead of the EnemyMovement class itself.
The interface needs to be declared outside the class itself, so it is accessible to other classes.
Usually, an interface has its own file.

trail sorrel
#

I will take a look at interfaces it was the first time I heard them when you said

trail sparrow
#

And lastly, your Pickup script is directly modifying the EnemyMovement script, instead of using methods of the Enemy itself.
It works now, so no reason to care, but in the future, try to let each script run its own mechanics, at outside request.

#

That is all.

#

GOOD WORK

#

Have a nice day UnityChanThumbsUp