• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by martinkors · Mar 18, 2019 at 05:05 PM · movementphysics

How to handle conveyor belt turn? (SOLVED)

My conveyor belt works in a straight line but when i add a turn it gets caught on the belt corner. Does anybody have a clue about how to handle a conveyor turn.
This is my code for the conveyor movement:

 public class conveyor_move : MonoBehaviour {
        public float speed = 0.6f;
        private Vector3 beltVelocity;
        public Rigidbody rb;
        private void Start()
        {
            rb = GetComponent
  
   ();
            beltVelocity = transform.right * -speed * Time.deltaTime;
        }
        private void FixedUpdate()
        {
            rb.position -= beltVelocity;
            rb.MovePosition(rb.position + beltVelocity);
        }
    }

  
alt text

Edit 1: I have updated my code to be dependant on velocity. And the corner error still occurs.


public class conveyor_move : MonoBehaviour {
    public float speed = 0.6f;
    private Vector3 beltVelocity;
    private void OnCollisionStay(Collision collision)
    {
        beltVelocity = transform.right * -speed * Time.deltaTime;
        Rigidbody rb = collision.gameObject.GetComponent
  
   ();
        rb.velocity = beltVelocity;
    }
}

  
alt text


Big edit (best solution yet)

I just revisited this project again and i finally found out how to make perfect conveyor movement. For anyone wanting to do something like this themselves, here is the code.

Notes: the target vector is the direction in which the object will move

ConveyorMove.cs for moving objects on top of the belt (is applied to the belt):

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ConveyorMove : MonoBehaviour
 {
     public float moveSpeed = 1f;
     public Vector3 target = Vector3.zero;
     public BoxCollider[] colliders = null;
     public List<GameObject> targets = new List<GameObject>();
     public List<GameObject> deleteMark = new List<GameObject>();
     void Start() {
         colliders = GetComponents<BoxCollider>();
     }
 
     void Update()
     {
         foreach (var i in targets)
         {
             if (i.GetComponent<ObjectData>().gameObjectData["Moving"] == this.gameObject) {
                 i.transform.position = Vector3.MoveTowards(i.transform.position, new Vector3(transform.position.x + target.x, i.transform.position.y, transform.position.z + target.z), Time.deltaTime * moveSpeed);
                 if (target.x != 0) {
                     if (transform.position.x + target.x == i.transform.position.x) {
                         deleteMark.Add(i.gameObject);
                     }
                 }
                 else {
                     if (transform.position.z + target.z == i.transform.position.z) {
                         deleteMark.Add(i.gameObject);
                     }
                 }
             }
             else if (i.GetComponent<ObjectData>().gameObjectData["Moving"] == null) {
                 i.GetComponent<ObjectData>().gameObjectData["Moving"] = this.gameObject;
                 i.transform.position = Vector3.MoveTowards(i.transform.position, new Vector3(transform.position.x + target.x, i.transform.position.y, transform.position.z + target.z), Time.deltaTime * moveSpeed);
             }
         }
         foreach (var i in deleteMark)
         {
             targets.Remove(i);
             i.GetComponent<ObjectData>().gameObjectData["Moving"] = null;
         }
         deleteMark.Clear();
     }
 
     void OnCollisionEnter(Collision col) {
         bool exists = false;
         foreach (var i in targets)
         {
             if (col.gameObject == i) exists = true;
         }
         if (!exists) {
             targets.Add(col.gameObject);
             if (!col.gameObject.GetComponent<ObjectData>().gameObjectData.ContainsKey("Moving")) {
                 col.gameObject.GetComponent<ObjectData>().gameObjectData.Add("Moving", this.gameObject);
             }
         }
     }
 }

ObjectData.cs storing variables in movable objects (is applyed to the moving objects):

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ObjectData : MonoBehaviour
 {
     public Dictionary<string, int> intData = new Dictionary<string, int>();
     public Dictionary<string, bool> boolData = new Dictionary<string, bool>();
     public Dictionary<string, string> stringData = new Dictionary<string, string>();
     public Dictionary<string, float> floatData = new Dictionary<string, float>();
     public Dictionary<string, GameObject> gameObjectData = new Dictionary<string, GameObject>();
 }
 



ezgifcom-optimize.gif (445.7 kB)
ting.gif (200.4 kB)
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Harinezumi · May 24, 2018 at 02:06 PM 0
Share

I see 2 different solutions: either change the area of effect, lengthening the end of the first conveyor belt piece and shortening the side of the second, or create smaller areas that are angled, so that they move the boxes on a curve and guide the them onto the second piece.
Alternatively, if you used non-kinematic rigidbodies, you could place the second piece of conveyor belt lower, and let the boxes fall on them.
There are more complicated solutions, but let's try something simpler first.

avatar image Harinezumi · May 25, 2018 at 11:36 AM 0
Share

Check out this short article: http://www.gamasutra.com/blogs/$$anonymous$$arkHogan/20141103/229201/Easy_Conveyor_Belt_Physics_in_Unity.php
I've just tested it, and it works surprisingly well. It exploits that modifying the transform of an object with rigidbody "teleports" the object (without applying physics), and moving it using $$anonymous$$ovePosition() applies physics, including to objects that are in contact with it.
Of course, I'm not sure it will solve the issue on the corner.

avatar image martinkors Harinezumi · May 25, 2018 at 03:50 PM 0
Share

Yeah i already tried this method and the corner problem vas not solved which is the main problem, and when i have that figured out then i can do everything else myself.

5 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by martinkors · Mar 17, 2019 at 09:38 AM

I just revisited this project again and i finally found out how to make perfect conveyor movement. For anyone wanting to do something like this themselves, here is the code.

ConveyorMove.cs for moving objects on top of the belt (is applied to the belt):

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ConveyorMove : MonoBehaviour
 {
     [TagSelector]
     public string[] filterTags = new string[] {};
 
     public float moveSpeed = 1f;
     public Vector3 target = Vector3.zero;
     public BoxCollider[] colliders = null;
     public List<GameObject> targets = new List<GameObject>();
     public List<GameObject> deleteMark = new List<GameObject>();
     void Start() {
         colliders = GetComponents<BoxCollider>();
     }
 
     void Update()
     {
         foreach (var i in targets)
         {
             if (i.GetComponent<ObjectData>().gameObjectData["Moving"] == this.gameObject) {
                 i.transform.position = Vector3.MoveTowards(i.transform.position, new Vector3(transform.position.x + target.x, i.transform.position.y, transform.position.z + target.z), Time.deltaTime * moveSpeed);
                 if (target.x != 0) {
                     if (transform.position.x + target.x == i.transform.position.x) {
                         deleteMark.Add(i.gameObject);
                     }
                 }
                 else {
                     if (transform.position.z + target.z == i.transform.position.z) {
                         deleteMark.Add(i.gameObject);
                     }
                 }
             }
             else if (i.GetComponent<ObjectData>().gameObjectData["Moving"] == null) {
                 i.GetComponent<ObjectData>().gameObjectData["Moving"] = this.gameObject;
                 i.transform.position = Vector3.MoveTowards(i.transform.position, new Vector3(transform.position.x + target.x, i.transform.position.y, transform.position.z + target.z), Time.deltaTime * moveSpeed);
             }
         }
         foreach (var i in deleteMark)
         {
             targets.Remove(i);
             i.GetComponent<ObjectData>().gameObjectData["Moving"] = null;
         }
         deleteMark.Clear();
     }
 
     void OnCollisionEnter(Collision col) {
         bool exists = false;
         foreach (var i in targets)
         {
             if (col.gameObject == i) exists = true;
         }
         if (!exists) {
             targets.Add(col.gameObject);
             if (!col.gameObject.GetComponent<ObjectData>().gameObjectData.ContainsKey("Moving")) {
                 col.gameObject.GetComponent<ObjectData>().gameObjectData.Add("Moving", this.gameObject);
             }
         }
     }
 }

ObjectData.cs storing variables in movable objects (is applyed to the moving objects):

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ObjectData : MonoBehaviour
 {
     public Dictionary<string, int> intData = new Dictionary<string, int>();
     public Dictionary<string, bool> boolData = new Dictionary<string, bool>();
     public Dictionary<string, string> stringData = new Dictionary<string, string>();
     public Dictionary<string, float> floatData = new Dictionary<string, float>();
     public Dictionary<string, GameObject> gameObjectData = new Dictionary<string, GameObject>();
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Captain_Pineapple · May 25, 2018 at 05:28 PM

Ok, given this image the code should be working with this configuration:

 public class conveyor_move : MonoBehaviour {
       public float speed = 0.6f;
       private Vector3 beltVelocity;
       private void OnCollisionStay(Collision collision)
       {
           beltVelocity = transform.right * -speed * Time.deltaTime;
           Rigidbody rb = collision.gameObject.GetComponent<Rigidbody>  ();
           rb.velocity = beltVelocity;
           collision.gameObject.transform.GetComponent<Rigidbody>
       ().AddForce(this.transform.forward * this.transform.InverseTransformVector(this.transform.position - collision.gameObject.transform.position).z * collision.gameObject.transform.GetComponent<Rigidbody>().mass);
       }
   }

Perhaps add some Constant factor to increase the force on the body and perhaps the force has to be inverted but i'd say this should work how it is. In case you doubt it take the following line and let it get logged:

Debug.Log("Distance from Center of Belt: " + this.transform.InverseTransformVector(this.transform.position - collision.gameObject.transform.position).z);

and take a look if it gives you a desired/valid distance.

It definetly has to be .forward since it gives you the world coordinate forward axis of your belt part. Glad that it works!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by ayangd · Mar 16, 2019 at 06:09 PM

After finishing my problem, exactly the same as this, I got a very nice solve! Here's the code:

 public class BeltCollide : MonoBehaviour {
     void OnCollisionStay(Collision collision)
     {
         Rigidbody rb = collision.collider.GetComponent<Rigidbody>();
         if (rb != null)
         {
             Vector3 velocityProjection = Vector3.Project(rb.velocity, transform.forward);
             rb.velocity = rb.velocity - velocityProjection + transform.forward;
         }
     }
 }

You first need to change the conveyor collider's material to something slippery.

The script is actually easy if you understand vector projection: It first neutralizes the forward velocity to zero, then add the forward velocity to one. So, when the transporting item collides two conveyors at the same time (different axis), their velocities will sum up.

Surprisingly, when you rotate the conveyor up or down, they tend to ignore gravity in it's forward and back axis.

Hope it helps a lot :)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Zodiarc · May 24, 2018 at 08:03 AM

You could define waypoints along the belt and make the object follow them at the same pace as the conveyor belt. The illusion would be the same.

Comment
Add comment · Show 18 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image martinkors · May 24, 2018 at 08:09 AM 1
Share

The problem is that i want it to be 100% physics based, but if you have an example i could check it out.

avatar image Captain_Pineapple martinkors · May 24, 2018 at 08:20 AM 1
Share

Sorry to dissapoint you there but your example is already not really "physics-based" since you don't use addforce or velocitys to move your cubes.

what you could do though is to give the conveyor a physics material with no friction, then you can add trigger colliders above them that, when entered, apply a force/sets a velocity in the conveyors direction the body that entered the trigger. Then you only have to make sure that the trigger of the second conveyor does not start too early since you would have the same behaviour all over again. You have to let your objects get on the second belt before you actually add a force/velocity in the new direction. Hope this helps.

avatar image martinkors Captain_Pineapple · May 24, 2018 at 08:34 AM 0
Share

How would you go about doing this because the problem i have is that i cannot figure out how to only detect one collision at once. Edit: I tried applying force to the objects while the conveyor had 0 friction but it takes a lot of force to move the object and it doesn't move with a constant speed. alt text

ting.gif (200.4 kB)
Show more comments
avatar image
0

Answer by popupAsylum · May 25, 2018 at 04:57 PM

Might not be possible for what you're aiming for but could you have a small step down to the next conveyer?

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image martinkors · May 25, 2018 at 05:00 PM 0
Share

This has already been solved but thanks for the input :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

176 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Sometimes the ball isn't moving 0 Answers

FIXED: How can I stop a collider from tunneling? 2 Answers

Changing wheel collider direction in Unity 5 0 Answers

Movement script breaks colliders 1 Answer

Player falls through rising platform? 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges