I needed to make a conveyor belt, so I followed a tutorial on how to do it. Once I implemented the code and put it into Unity, instead of the conveyer belt actually working, it starts drifting away.
My Conveyer belt has a rigidbody that Kinematic but has no gravity
My First Person Controller(which is the thing that is supposed to move in the conveyer belt) also has a rigidbody which is not Kinematic but has gravity
ConveyerBelt.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ConveyerBelt : MonoBehaviour
{
public Rigidbody rb;
public float speed = 10f;
public Vector3 direction;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
GetComponent<Rigidbody>().position -= transform.forward * speed * Time.deltaTime;
GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position + transform.forward * speed * Time.deltaTime);
}
}
Well according to the tutorial, both GetComponent().position GetComponent is supposed to make anything on the gameObject move towards a certain direction but not the gameObject itself.
What youâve got looks like a common way of implementing conveyors, except that youâre running those code in Update instead of FixedUpdate. Iâm not certain thatâs the issue, but thatâs the first thing Iâd change.
The first thing you should do is take those GetComponent calls out of Update. Youâre completely killing your gameâs performance - these calls are extremely expensive. Use the rb variable instead and move the code to FixedUpdate.
It might look like that, but thatâs not what happens in practice. I use basically the same approach for conveyors. You change the position of the conveyor in one direction by setting the transform position, then immediately MovePosition to put it back where it was at the start of the frame. The ultimate effect is that the conveyor doesnât actually have any net movement, but any objects touching it will be moved along.
I suspect the issue is that this only works properly in FixedUpdate and not in Update.
Yeah, I just confirmed that I can break my conveyors in the way the OP is referring to by putting that code in Update instead of FixedUpdate. So, @BoxTraininc , put that code in FixedUpdate.
And, do what others have mentioned, and donât use GetComponent like that, especially since you already have public Rigidbody rb; in a class variable.
Well that fixed the Conveyer belt from drifting away, but itâs still not forcing my player to move. I suspect that it has something to do with the components of the player:
My player is a gameobject containing a model, a main camera and a gun prefab. The gameobject has a Character Controller, a Player movement script, a going up a ladder script and a Rigidbody with Gravity and Kinematics on.
In no part of the tutorial that it said what components should your object should contain(the one that you want to move), well at least none that I know of.
If youâre talking about âContinuous Dynamicâ, then yes I did, but nothing really changed.
Just to double check, all I had to do was switch GetComponent with rb and turn the void to FixedUpdate, right?
The way that conveyor works, it will only move rigidbodies where IsKinematic is off/false. If your character controller needs to have IsKinematic enabled, then youâll need to use a different approach to get the conveyor to move those kinds of objects. Something more along the lines of what others have already mentioned, where you probably need to call MovePosition on the characterâs rigidbody while theyâre standing on the conveyor. This probably isnât too difficult, and there are various approaches you might take here. But Iâm also not sure whether theyâd be compatible with your character controller.
My Character controller is from a tutorial of Brackeys(Who is a great YouTuber by the ways) and nowhere in the tutorial it said to add a Rigidbody. I added a Rigidbody because I thought I needed one. So youâre saying that if I turn off Kinematic on my Player Rigidbody, it should work?
Well, if you did that, the conveyor belt would probably move the player. But I wouldnât be very confident that your character controller would work anymore. If the character controller isnât designed for non-kinematic rigidbodies, adding a rigidbody can easily break it.
Ultimately, you probably want one of the two pairings:
Find a Rigidbody Character controller that uses a non-kinematic rigidbody, then Iâd expect that to work with the conveyors.
If you use a different kind of character controller, youâll need to write some custom code to make it interact with the conveyor properly. Probably something that ties in with a Ground Test behavior to detect youâre standing on a conveyor, and manually move the player each frame in that case.
Well, looking back at my code, it turns out I was mistaken. I do indeed need a Rigidbody with Kinematics on, in order for the player to climb ladders. Iâve tried turning Kinematics of and putting my player on the Conveyer belt but to no avail
Dâyou think it might work if I were to add a function in the Character Controller Script telling it to move Backwards a bit if it collides with the Conveyer Hitbox?
Something like that would probably work. It feels a bit sloppy, but I imagine it would get the job done. If I were trying to do this quickly, Iâd do it something like this. Note that this isnât code, itâs just a rough approach:
Use a Raycast to test for the kind of surface youâre standing on. Your character controller is probably already doing something like this to see if itâs allowed to jump. (Grounded Tests are common in character controllers.)
See if the tag of the surface you hit is âConveyorBeltâ. This assumes you assign a tag of ConveyorBelt to your conveyor belt collider.
If the tag is âConveyorBeltâ, then on the RaycastHit call something like var conveyorController = raycastHit.collider.gameObject.GetComponent<ConveyorBeltController>();. This assumes the controller script for the conveyor belt is on the same object as the collider. If not, you might need to use GetComponentInParent to walk up from the collider to the parent.
Now that you have âconveyorControllerâ, you can ask it things like its speed and direction. With that information, you can apply some movement to the characterâs rigidbody.
On second thought, I donât really want to take the âlazyâ way out of things, so Iâm just going to dismiss that idea. Iâll try to tweak the ladder script in order to make it not dependent on the players rigidbody