#Frame Logic with OnCollisionEnter2D

1 messages · Page 1 of 1 (latest)

mortal fog
#

It's more the other way around.
Unity determines when Update is called.
In the background, it gets all the Update() methods from all scripts and run them in sequence.

#

But that's besides the point.

unreal night
mortal fog
#

If no specific framerate has been set, Update() will run as often as possible. My PC has around 300 FPS on a blank project.

#

That means the Update method will run 300 times in one second

unreal night
#

sorry I mean frame not second

#

mb

mortal fog
#

It's fine. This is not an easy field, but I'll try to ease this in with your current issue.

unreal night
#

yeah, it's a lot to learn haha

mortal fog
#

Movement is coded in either Update() or FixedUpdate()

  • Update runs per visual frame (the game FPS)
  • FixedUpdate runs every Physics tick, which by default is 50 times per second, regardless of framerate.

The idea is that anything related to game-logic should be happen equally as often among all players.
While Update() is used for things that need to be more in visual sync.

OnCollisionEnter2D is a physics event, that happens for a single frame.
Since it only runs the first time an object collides, it it mostly used to flip bools, that change behavior.

So in that method you should replace the transform.position line,
with hasTouchedPlayer = true;

unreal night
#

Well doesn't it make it move based on time and not framrate since I multiplied it with Time.deltaTime?

mortal fog
#

OnCollisionEnter2D happens for a single frame.

#

the first moment the game registers a collision

unreal night
#

ah yes

mortal fog
#

so it can't carry movement over time

unreal night
#

Yeah, makes sense.

mortal fog
#

so we flip a bool, and move the movement logic to Update/FixedUpdate

#
private bool hasTouchedPlayer;

private void OnCollisionEnter2D(...)
{
    if (..) hasTouchedPlayer = true;
}

private void Update()
{
    if (hasTouchedPlayer) // Move
}
#

Once you get that to work, we can work on the correct way to move objects that have colliders (not transform.position)

#

so that they can interact properly with other colliders

#

Any questions?

unreal night
#

gimme a sec

#

if (..) hasTouchedPlayer = true; , should the (..) be the ground then? a bit confused

mortal fog
#

The code is not meant for copying, just a guide to where things are in your script

#

(...) means you already have something there in your code, and I didn't bother to write it

#

only 2 methods 😅

#

it's the existing if-statement in that method

unreal night
#

ah ye

#

so, you want me to use a void update()?

mortal fog
#

well, if you do that, it will visually move the way you want (great success)
but it will conflict when encountering other colliders, because the physics system is supposed to be solely responsible for moving physics objects (colliders).
Using transform.position is overriding what physics wants to do.

#

so you can do it just to see how the code actually works

unreal night
#

and use OnCollisionEnter and not Stay then? as I have rn

mortal fog
#

Yes, at least for this one.
Once we nail movement, you can elaborate on the entirety of the mechanic.

#

(as in, what more you want than just moving)

unreal night
#

Kinda sound very newbie lol, but I'm not sure if this is what you meant.

#

private bool hasTouchedPlayer;

private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
{
    if (OnCollisionEnter2D.gameObject.CompareTag("Player")) hasTouchedPlayer = true;
    {
        
    }
}

// Update is called once per frame
void Update()
{
    if (hasTouchedPlayer) // Move
}
mortal fog
#

!code

wide kestrelBOT
#
Posting code

📃 Large Code Blocks
Large code blocks should be posted as links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/
https://paste.myst.rs/, https://hastebin.com/

📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To get C# formatting the first line should only contain cs or csharp.
Add a comment with a line number if there is an error message.
```cs
// Your code here
```
Do not share screenshots of code unless requested.

mortal fog
#

// Your code here <--- read that

#

repost like this

private string name = "code blocks with syntax highlighting";
#

if-statements can be written in three ways

if (true) DoThing();

if (true) 
    DoThing();

if (true)
{
    DoThing();
}
#
private string name = "code blocks with syntax highlighting";
unreal night
#

after that, just copy it from the website and paste it here?

mortal fog
#

No, I mean copy your code from inside Visual Studio, directly into Discord
but before pasting it in Discord, make a code-block

unreal night
#

oh lol

#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnCollisionMoveGround : MonoBehaviour
{
    private bool hasTouchedPlayer;


    private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player")) hasTouchedPlayer = true;
        {
            
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (hasTouchedPlayer) // Move
    }
}
#

oops

mortal fog
#

edit the post

unreal night
#

there

mortal fog
#

Good stuff

unreal night
#

haha took a while

mortal fog
#

Now, re-read the thing I wrote about if-statements, and fix yours

#

it's good practice to use { scope brackets }

#

whichever way you write it, the goal is for the code to be readable

unreal night
#

yeah

#

hmm I'm sorry but I still don't understand really how to implement it

#

if yk

mortal fog
#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnCollisionMoveGround : MonoBehaviour
{
    private bool hasTouchedPlayer;


    private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player")) 
        {
            hasTouchedPlayer = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (hasTouchedPlayer)
        {
            // The old movement code you had
        }
    }
}
unreal night
#

Now I'm kinda confused if I'm supposed to use the Update? Since you refer to it as the old movement code

mortal fog
#

What I mean is for you to paste the exact line you used for movement in your original example

unreal night
#

ah

mortal fog
#

The first code example I posted, was meant to be an instruction for how to edit the original script

#

I only specified which changes were to be made

unreal night
#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnCollisionMoveGround : MonoBehaviour
{
    private bool hasTouchedPlayer;


    private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player"))
        {
            hasTouchedPlayer = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (hasTouchedPlayer)
        {
            transform.position = transform.position + (Vector3.left * moveSpeed) * Time.deltaTime;
        }
    }
}

#

this is what I've got now

mortal fog
#

there's a mistake

#

the first if-statement

unreal night
#

oh

mortal fog
#
if (true) DoThing();

if (true) 
    DoThing();

if (true)
{
    DoThing();
}
unreal night
#

like that?

mortal fog
#

good stuff

#

any errors?

unreal night
#

yes that moveSpeed doesn't fit in the context lol I removed it

mortal fog
#

wait what?

unreal night
#

I refer to moveSpeed in my script

#

in the void update

#

line 24

mortal fog
#

yes, it should be there. You removed it?

unreal night
mortal fog
#

post the full script

unreal night
#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnCollisionMoveGround : MonoBehaviour
{
    private bool hasTouchedPlayer;
    public float moveSpeed = 8;


    private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player"))
        {
            hasTouchedPlayer = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (hasTouchedPlayer)
        {
            transform.position = transform.position + (Vector3.left * moveSpeed) * Time.deltaTime;
        }
    }
}
#

here

#

but I fixed it, and it's starting to resemble what I want the platform to be

#

now it moves by itself, but for every frame I touch it, it speeds up

#

kinda

mortal fog
#

That would be from your Rigidbody colliding and adding force

#

the code is either On/Off

#

no Off at the moment

unreal night
#

wdym on/off?

mortal fog
#

You could copy the contents of OnCollisionEnter2D,
and paste them into OnCollisionExit2D, but setting the bool false
Then you'd have a platform that only moves when the player is touching it.

unreal night
#

like the player?

mortal fog
unreal night
unreal night
#

that like stops it after one trigger

mortal fog
#

That's an example of something you could do, to easily add immersive functionality

unreal night
#

yea alr

mortal fog
unreal night
#

private void OnCollisionExit2D(Collision2D OnCollisionExit2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player"))
        {
            hasTouchedPlayer = false;
        }
    }
#

kinda like that?

mortal fog
#

Yes, exactly.

#

Anyway, that's only an example, not what you set out to create.

unreal night
mortal fog
#

Is this platform supposed to move between A and B all the time, or only activate like a ferry for transport?

unreal night
#

Like a ferry

#

So when you collide, it will take you there

#

and preferably so it can take you back

mortal fog
#

so ideally, for it to move a second time, you'd have to step off, and back on (or at least jump)

#

or use an interface, like a button

unreal night
#

yeah i meant for example so you could go back later and return with it

#

not so it will do it constant

#

as you said lol, step on and off

mortal fog
#

Alright, good stuff.
The immediate issue might be jumping.
Is jumping possible?

unreal night
#

My character can jump yes

#

if that's what you were wondering

mortal fog
#

Yes

unreal night
#

yeah alr, I have basic movement

mortal fog
#

Okay, now let's do proper Physics movement

#

In order to move, colliders need to be able to produce Force,
for which they will require a Rigidbody2D

Add that component to the platform object.
Then in the script:

public Rigidbody2D rb;

and drag the Rigidbody component into your script's Rigidbody2D field.

unreal night
#

should I use the same object and script as before?

mortal fog
#

You can keep the old script, and create a new one, copy the old code into it, and proceed from there.

unreal night
#

I made it a prefab, guess it will automatically save the old script with it?

mortal fog
#

it is a reference to that single script. It will update with changes.

unreal night
#

ah ok

mortal fog
#

so if you want the prefab to use the new script
you'll have to open the prefab itself, remove the old, and add the new.

#

Then the prefab instances in the scene need to be updated with the new override from the parent asset.

#

Or, you can just copy the script to a folder outside the project, to keep it for historical reasons, and keep using the same one, with no extra fuzz 😅

unreal night
#

yeah sounds good

#

ill just use the original

#

fixed the rb

mortal fog
#

good

#

so when you type Rigid in Visual Studio, does it suggest Rigidbody and Rigidbody2D ?

unreal night
#

noo

mortal fog
#

!ide

wide kestrelBOT
#
💡 IDE Configuration

If your IDE is not autocompleting code
or underlining errors, please configure it:

• Visual Studio (Installed via Unity Hub)
• Visual Studio (Installed manually)

• VS Code*
• JetBrains Rider
• Other/None

*VS Code's debugger plugin is unsupported.
We recommend using VS or Rider instead.

mortal fog
#

Go through the appropriate guide, and let me know when it works.
Should be simple enough. 90% don't need help with this process.

unreal night
#

alr

mortal fog
#

If you're among those who do need help, just make sure you've read all the steps.

unreal night
#

btw noticed I have both vs 2019 and 2022

#

I'd guess 2022 is better

mortal fog
#

Yes, very.

unreal night
#

fixed it to be like this, if that is what you meant

mortal fog
#

Good stuff. You're now at all allowed to get help on this server 😆

#

(it's a requirement, because coding without intellisense is just madness)

unreal night
#

oh hahah

#

well there's more colors now I'll tell you that

mortal fog
#

so btw it's 10 PM here, so I'm not sure if I'll be able to help you complete this in time
but at worst, we can go through some basics, and you can explore some short youtube tutorials on moving platforms

#

my own script is nearly 300 lines

mortal fog
#

and I haven't actually made a platform that transports a player
which can be done by parenting the player to the platform object (children move with their parents)

#

so, Rigidbody movement

mortal fog
#

in there, you'll find MovePosition

#

ah fk, wrong link above

unreal night
#

yeh alr

mortal fog
#

fixed it

#

The script example gives a good idea of how that method is used.

#

ignore the stuff in Start()
Just read Update()

unreal night
#

so, I don't really need anything from before exept for the rigidbody?

mortal fog
#

You do need everything. We're just going to modify the movement part.

unreal night
#

ok yeah

#

makes sense

#

But wont it kinda confuse it having multiple lines telling it to move

mortal fog
#

It won't have that, because you will comment out or remove the lines we are replacing.

#
public Rigidbody2D rb;
public float moveSpeed = 8;

private Vector2 direction;

private void FixedUpdate()
{
    direction = rb.transform.forward;
    rb.MovePosition(rb.position + (direction * moveSpeed * Time.deltaTime));
}
#

direction is just there to make it readable
Velocity is the product of a Vector direction multiplied by speed

#

The online script example uses Time.fixedDeltaTime
which is the proper way, but Time.deltaTime is universal; it simply knows how much time has passed since last time.

unreal night
#

alr

mortal fog
#

Now, wrap that movement code inside the same if-statement as the old code

#

and see if it works the same way

#

In this case, you'd just rename Update() to FixedUpdate()

unreal night
mortal fog
#

you can turn off Gravity

#

for that Rigidbody

unreal night
#

ah yes

#

gravity scale to 0 then?

mortal fog
#

yes

#

or you could constrain the Y axis

#

Freeze* I mean

unreal night
#

yeah think I'll have to do that, removing the gravity makes it a bit goofy hahah

#

hmm well it does move but it's also like a wobbly board

#

It swings with it's physics

#

putting body type to static kinda fixed it

mortal fog
#

Since I haven't made a transporting platform, and it's late, I don't think this solution will be perfect.
That said, the reason is probably because of physics simulations, when interacting with the player.

One solution is to make the platform's rigidbody kinematic (it's a checkbox)
That way it won't be affected by physics, but only it's own movement code.

#

static objects shouldn't be able to move

#

or am I just that rusty on this?

unreal night
#

yellow errors

mortal fog
#

alright

#

try kinematic instead

unreal night
#

but yeah kinematic works

mortal fog
#

Probably no need to freeze Y axis then

#

Does the player move with the platform, or do you need to move to keep up with it?

unreal night
#

for making it switch direction, couldn't you make it like switch direction every time you collide with it? like you jump and collide again, and it switches kinda?

unreal night
#

I think it would make sense, because if you went right with it, to get back, you jump on it again later and then it will switch to left

mortal fog
unreal night
#

ok

mortal fog
mortal fog
unreal night
#

yea

mortal fog
#

post your full script again

unreal night
#

also, I can walk but lik 1% of normal speed while bein a child of the platform

mortal fog
#

hm 😅

unreal night
#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OnCollisionMoveGround : MonoBehaviour
{
    private bool hasTouchedPlayer;
    public float moveSpeed = 8;
    public float deadZone = -50;
    private Vector2 direction;
    public Rigidbody2D rb;


    private void OnCollisionEnter2D(Collision2D OnCollisionEnter2D)
    {
        if (OnCollisionEnter2D.gameObject.CompareTag("Player"))
        {
            hasTouchedPlayer = true;
        }
    }

    private void OnCollisionExit2D(Collision2D OnCollisionExit2D)
    {
        if (OnCollisionExit2D.gameObject.CompareTag("Player"))
        {
            hasTouchedPlayer = false;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (hasTouchedPlayer)
        {
            transform.position = transform.position + (Vector3.left * moveSpeed) * Time.deltaTime;
        }

        if (transform.position.x < deadZone)
        {
            Debug.Log("OnTriggerGroundMove Deleted");
            Destroy(gameObject);
        }

    }

    private void FixedUpdate()
    {
        if (hasTouchedPlayer)
        {
            direction = rb.transform.forward;
            rb.MovePosition(rb.position + (direction * moveSpeed * Time.deltaTime));
        }
    }
   
}
mortal fog
#

then it might not be an ideal solution

unreal night
mortal fog
#

haha, technically, you could work around anything
but that would probably just become a bigger problem later

unreal night
#

hmm yes

mortal fog
#

I'm not sure which one of these supports a Rigidbody player

#

but you should probably find something useful in there

#

Moving between A and B is covered in all of them.

#

The easiest way is to have game objects which represent the waypoints

unreal night
#

yeah found this

#

not really it but

mortal fog
# unreal night

That one doesn't cover Physics, but if it works, then it works
After completing it, you can see if replacing transform.position with rb.position works the same. It would be more correct.

unreal night
#

hmm was working on the rotation part but got stuck at how to rotate it lol

mortal fog