Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Snake - body part. ( C# )

Discussion in 'Getting Started' started by CCnockaert, Sep 4, 2018.

  1. CCnockaert

    CCnockaert

    Joined:
    Sep 4, 2018
    Posts:
    28
    Hello,

    I don't know if i'm posting in the right forum ... whatever.

    So there is my problem :

    I'm working on my first project, a simple 3d copycat of the game "Snake".
    Right now my snake got one body part, its head. ( it can moves, turn around, without any problem )

    And I don't know how to make my snake getting longer when it eats a fruit ... I tried by instantiating a "PlayerExtention" pre-fab, but no matter what I'm not able to make it spawn at the right spot ( sticked to the snake ) and it also follows "PlayerHead" direction ... which is not the behavior I want.

    This is what I tried :

    Code (CSharp):
    1. Instantiate(playerExtension, new Vector3(-1.0f, (GetComponent<Renderer>().bounds.size.y), (GetComponent<Renderer>().bounds.size.z)), transform.rotation, transform);
    I'm really new to C sharp and Unity, so I don't have enough knowledge to resolve this kind of problem without someone.

    I thought to use lists to store the body parts, but I still don't know how I could stick these body parts to the parent "PlayerHead" and to make these body parts following the "PlayerHead" path.

    There is my current hierarchy :


    So I hope that you have some ideas, thanks a lot :)

    NB : I'm not using any tutorial.
     
    Ryiah likes this.
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,860
    This is kind of an advanced thing for somebody new to programming. But I applaud you for attempting it.

    You were right to think of lists. The way the standard Snake game is done, all the body parts appear at points on a grid. There is a list of these, and on each step (movement of the snake), you just take away the last element — the segment at the tip of the tail — and put it where the head was, as you move the head forward.

    So you can't really do this with a bunch of independently-acting scripts on separate GameObjects. You need some master script that keeps a list of all the body parts, and does the trick I described above on every step.
     
    Ryiah likes this.
  3. CCnockaert

    CCnockaert

    Joined:
    Sep 4, 2018
    Posts:
    28
    Hello !

    Sooo ... I worked on this issue, and now i'm able to make instantiate body parts at the right spot every time, but I got a weird issue.

    In my "PickUpEvent" script, I call the "SpawnExtension" method from an other class ( "PlayerInput" ), I tried to create a reference with GetComponent<PlayerInput> and with the "new" method ( like this ) :

    Code (CSharp):
    1.     PlayerInput playerInputSession;
    2.  
    3.     private void Awake()
    4.     {
    5.          playerInputSession = new PlayerInput();
    6.     }
    But the console show a warning and ask me to use the AddComponent method, but I don't find any documentation on this.


    So my question is ;

    How can I make a reference to an other class ?

    Thanks a lot !

    NB : I could create a public variable to drag the script I want, but I feel like it's not a good way to do it.
     
    Ryiah likes this.
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,860
    It's strange that you couldn't find any documentation on AddComponent; the page you want is literally the very first search result when you google "Unity AddComponent". Get good at this; it's the fastest way to find the info you need in most cases.

    Anyway, the compiler warning is quite correct: you can't instantiate components with new. Instead you instantiate them with AddComponent, or get a reference to an existing one with GetComponent (google it).

    It sounds like you tried this...

    but you didn't show that. This was almost certainly the right thing to do; why didn't it work for you?

    Actually, that's probably the best way to do it. But you should learn how to use GetComponent too. Each approach is handy in different situations.
     
    Ryiah likes this.
  5. CCnockaert

    CCnockaert

    Joined:
    Sep 4, 2018
    Posts:
    28
    Thanks you for the documentation !

    Well, it seems like the AddComponent<>() method is working, but I realized that create a reference to this class isn't the thing I need, because my "PlayerInput" class contains an "FixedUpdate()" method to manage the player's movements.

    My "PickUpEvent" class is calling the "FixedUpdate" method for its own GameObject ( the fruits ), so it throws an huge amount of errors ( since the fruits don't have any RigidBody ).

    The thing that I want to do is :

    When a fruit is eaten by the player ( when the player trigger the Collider of the fruit ) it calls the OnTriggerEnter() in the "PickUpEvent" class, which also calls the "SpawnExtension()" method in the "PlayerInput" class.

    I could use static methods, but I just realized that I can get the player's collider when it trigger the fruit's collider ... so maybe I can call the SpawnExtension() method from this, right ?

    There is my script :

    1) PlayerInput class
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class PlayerInput : MonoBehaviour
    5. {
    6.  
    7.     //speed to modify
    8.     public float speed;
    9.  
    10.     //contain the player extension prefab
    11.     public GameObject playerExtensionPrefab;
    12.  
    13.     //rigidbody of the playerhead
    14.     private Rigidbody playerRb;
    15.  
    16.     //contains old direction
    17.     private Vector3 oldMovement;
    18.  
    19.     //contains applied movement
    20.     private Vector3 movement;
    21.  
    22.     //contains every player extension prefab
    23.     private List<GameObject> bodyParts;
    24.  
    25.     void Start()
    26.     {
    27.         playerRb = GetComponent<Rigidbody>();
    28.         bodyParts = new List<GameObject>();
    29.         oldMovement = new Vector3(1.0f, 0, 0);
    30.         playerRb.AddForce(oldMovement*speed);
    31.        
    32.     }
    33.  
    34.     void FixedUpdate()
    35.     {
    36.         Movement();
    37.     }
    38.  
    39.     void Movement ()
    40.     {
    41.        //..
    42.     }
    43.  
    44.     void ReverseRotation90 ()
    45.     {
    46.        //..
    47.     }
    48.  
    49.     void Rotation90 ()
    50.     {
    51.        //..
    52.        
    53.     }
    54.  
    55.     void StopPlayerMovement()
    56.     {
    57.        //...
    58.     }
    59.  
    60.     string DirectionFaced()
    61.     {
    62.        //..
    63.     }
    64.  
    65.     public void SpawnExtension ()
    66.     {
    67.         if (bodyParts.Count != 0)
    68.         {
    69.             bodyParts.Add(
    70.                 Instantiate(playerExtensionPrefab,
    71.                 new Vector3(bodyParts[bodyParts.Count-1].transform.position.x - 1.0f, transform.position.y, transform.position.z),
    72.                 Quaternion.identity,
    73.                 transform) as GameObject);
    74.         }
    75.         else
    76.         {
    77.             bodyParts.Add(
    78.                 Instantiate(playerExtensionPrefab,
    79.                 new Vector3(transform.position.x - 1.0f, transform.position.y, transform.position.z),
    80.                 Quaternion.identity,
    81.                 transform) as GameObject);
    82.         }
    83.     }
    84. }
    85.  
    2) PickUpEvent

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class PickUpEvent : MonoBehaviour {
    4.  
    5.     PlayerInput playerInputSession;
    6.  
    7.     private void Awake()
    8.     {
    9.         playerInputSession = gameObject.AddComponent<PlayerInput>();
    10.     }
    11.  
    12.     void OnTriggerEnter()
    13.     {
    14.         Destroy(gameObject);
    15.         playerInputSession.SpawnExtension();
    16.     }
    17. }
    18.  
     
    Ryiah likes this.