Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 /
  • Help Room /
avatar image
0
Question by gregorip · Oct 07, 2016 at 11:25 PM · movementrigidbodypathpathfollowingsnake

Make an object follow another object's path (Snake game)

Good day, community. I am trying to make a 3D version of the game "Snake", but I am running into serious problems trying to make the first snake segment follow the head of the snake.

First, some explanation of how I am going about making this game: the body and head of the snake are sphere GameObjects. You can only control the head and, whenever you eat an item, the snake will "grow" a "segment" (anything but the head of the snake I will refer to as a segment) and immediately follow either the head or another segment that is directly ahead of it. For simplicity, I am trying to make just one segment follow the head of the snake, as once I figure how to make that one segment follow the head it will be the same logic for the rest of the segments.

Now, after multiple failed attempts at making the segment follow the head (including the use of different kinds of joints), I arrived at the conclusion that the best way to go about it is to have the segment follow the path that the head makes as it moves.

Let me now explain how i move the head: the head is moved applying a velocity to the rigidbody component of the sphere. So, every time I press an arrow key, I set the direction to either a Vector3.right, Vector3.left, Vector3.back or Vector3.forward. Then, in FixedUpdate, I set the rigidbody's velocity to this new direction multiplied by a certain speed. Whenever I press a directional key, i also register the position where the turn in direction took place. The idea is this: whenever I change the direction of the head I register both the position and turn direction so that, when the body segment that follows the head reaches this registered position where the turn took place, it will then change its velocity in the direction that the head turned to in that position. In this way, I can effectively make the segment follow the head's path by sending this position and turn direction to the segment so that it can make a comparison, each LateUpdate, that enables it to know when it has reached that turning position so that it changes direction at that position and adjust its velocity accordingly.

Now, as some of you may already expect, I have failed miserably in trying to make this equality comparison work. Since the positions are vectors, where each component is a float, the comparisons fail 100% of the time and the segment is not able to change its direction at the exact position that the head made its turn. Not even Mathf.Approximately() worked. So i had to subtract the components of both the head's turning position and that of the segment's current position and, if the difference is less than 0.0999999 (which is the number that I found worked most of the time), then go ahead and turn the direction so that when the next FixedUpdate comes, it will change its velocity in the direction that the head made its turn at that exact same position.

The problem with this approach is that it sometimes does not work. Sometimes the comparison seems to fail and the segment flies past the position it was supposed to make the turn. I have no idea why it is happening. The other problem i have is that if i don't make the segment's spawning position AT LEAST 2 units in the opposite direction of the head's current direction, it will miss the turning position 100% of the time. So that means that if I try to make the spheres follow each other as close as possible (in this case, at most 1 unit away from the head's position at any time), then it will not make the turns that it has to make. This makes for a very ugly looking separation between segments.

Thanking you in advance, I would like to know if there is either a more elegant solution to what I am trying to achieve, or at least a little help into what I may do to fix the current implementation. I am attaching the code of the segment that is supposed to follow the head. The naming for the objects are in Spanish, but it may not be that hard to figure out what is going on from a non-Spanish speaking person's perspective.

I have also properly commented the code, so that you can understand what I am doing at each sentence.

 using UnityEngine;
 using System.Collections.Generic;
 using Clases;
 
 public class ControladorSegmento : MonoBehaviour {
 
     //This is a generic list of Objects that store both turning position and turning direction that the head has made
     public List<PosicionCambioDireccion> listaPosicionesCambioDireccion;
 
     //This would be the head in the case of only one segment that is following
     public GameObject lider;
 
     //Speed
     public float rapidez;
 
     //Direction
     public Vector3 direccion;
 
     //This is an index that is used to iterate over the list of turning points
     private int indiceCambioDireccion;
 
     // Use this for initialization
     void Start () {
         
         indiceCambioDireccion = 0;
 
         listaPosicionesCambioDireccion = new List<PosicionCambioDireccion>();
 
         //First find the Head of the snake so that we can access its position in order to determine segment spawning position
         lider = GameObject.Find("Cabeza");
 
         //Set the position of the new segment 2 units right behind the head
         transform.position = lider.GetComponent<Transform>().position - lider.GetComponent<ControladorCabeza>().direccion * 2f;
 
         //Get the current direction of the head so that the segment inmediately moves in its direction
         direccion = lider.GetComponent<ControladorCabeza>().direccion;
     }
 
     void LateUpdate () {
                 
         //Check if there has been a change in direction that the segment has to follow
         if ((listaPosicionesCambioDireccion.Count > 0) && (listaPosicionesCambioDireccion.Count > indiceCambioDireccion)) {
                         
             //Compare how close we are to the turning position. If we are sufficiently close, change segment direction
             if (Mathf.Abs(transform.position.x - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.x) < 0.0999999 &&
                 Mathf.Abs(transform.position.z - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.z) < 0.0999999) {
                 
                 //Change segment direction at the current position
                 direccion = listaPosicionesCambioDireccion[indiceCambioDireccion].direccion;
 
                 //Increment turning positions list index so that we get the next turning point in the list (if there is any)
                 indiceCambioDireccion++;
             }
         }
     }
 
     void FixedUpdate() {
 
 
         //Change the velocity
         GetComponent<Rigidbody>().velocity = direccion * rapidez;
         
     }
 }


Thank you so very much in advance. I am still really new working with Unity and it seems I have still much to learn, but after close to two weeks trying to find a solution to the apparent simple task of just making an object follow another, and failing, I have no choice but to turn to you guys. And again, if you have a more elegant solution to what I am trying to achieve, please let me know. Right know I am aware that this implementation could cause a sort of memory leak in the sense that, as long as the head keeps changing direction, the list of turning points that is stored is going to keep growing and growing which obviously is something one should avoid.

Comment
Add comment
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

0 Replies

· Add your reply
  • Sort: 

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.

Follow this Question

Answers Answers and Comments

96 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

Related Questions

Im having trouble clamping enemies to the game area, can anyone help? 0 Answers

Rigidbody.AddForce moves in a curve 1 Answer

rb. MovePosition slowly enters another Collider 0 Answers

restricting player movement with a path? 1 Answer

Throwing an object whilst moving 1 Answer


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