Snake - body part. ( C# )

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 :

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 :slight_smile:

NB : I’m not using any tutorial.

1 Like

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.

1 Like

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 and with the “new” method ( like this ) :

    PlayerInput playerInputSession;

    private void Awake()
    {
         playerInputSession = new PlayerInput();
    }

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.

1 Like

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.

1 Like

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
using System.Collections.Generic;
using UnityEngine;

public class PlayerInput : MonoBehaviour
{

    //speed to modify
    public float speed;

    //contain the player extension prefab
    public GameObject playerExtensionPrefab;

    //rigidbody of the playerhead
    private Rigidbody playerRb;

    //contains old direction
    private Vector3 oldMovement;

    //contains applied movement
    private Vector3 movement;

    //contains every player extension prefab
    private List<GameObject> bodyParts;

    void Start()
    {
        playerRb = GetComponent<Rigidbody>();
        bodyParts = new List<GameObject>();
        oldMovement = new Vector3(1.0f, 0, 0);
        playerRb.AddForce(oldMovement*speed);
       
    }

    void FixedUpdate()
    {
        Movement();
    }

    void Movement ()
    {
       //..
    }

    void ReverseRotation90 ()
    {
       //..
    }

    void Rotation90 ()
    {
       //..
       
    }

    void StopPlayerMovement()
    {
       //...
    }

    string DirectionFaced()
    {
       //..
    }

    public void SpawnExtension ()
    {
        if (bodyParts.Count != 0)
        {
            bodyParts.Add(
                Instantiate(playerExtensionPrefab,
                new Vector3(bodyParts[bodyParts.Count-1].transform.position.x - 1.0f, transform.position.y, transform.position.z),
                Quaternion.identity,
                transform) as GameObject);
        }
        else
        {
            bodyParts.Add(
                Instantiate(playerExtensionPrefab,
                new Vector3(transform.position.x - 1.0f, transform.position.y, transform.position.z),
                Quaternion.identity,
                transform) as GameObject);
        }
    }
}
  1. PickUpEvent
using UnityEngine;

public class PickUpEvent : MonoBehaviour {

    PlayerInput playerInputSession;

    private void Awake()
    {
        playerInputSession = gameObject.AddComponent<PlayerInput>();
    }

    void OnTriggerEnter()
    {
        Destroy(gameObject);
        playerInputSession.SpawnExtension();
    }
}
1 Like