Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
1
Question by itsmealex100 · Feb 25, 2015 at 08:05 PM · c#movementsnake

Help with Snake Like movement

Hi all,

Simple question, how can I create a movement similar to the original snake but smoother, almost like this: https://www.youtube.com/watch?v=HWpEVyvngNc

I've been working through some other tutorials on movement (I'm still new to c#), i've modified a few but they dont quite get the result i need, here is what i have so far:

 using UnityEngine;
 using System.Collections;
 
     [RequireComponent (typeof (CharacterController))]
 public class Player : MonoBehaviour {
 
     public float rotationSpeed = 450;
     public float walkSpeed = 5;
     
     //System
     private Quaternion targetRotation;
 
     //Components
     private CharacterController controller;
     
     void Start (){
         controller = GetComponent<CharacterController>();
     }
 
 
     void Update () {
         Vector3 input = new Vector3(Input.GetAxisRaw ("Horizontal"), 0,Input.GetAxisRaw ("Vertical"));
 
         if (input != Vector3.zero) {
         targetRotation = Quaternion.LookRotation(input);
             //transform.eulerAngles = new Vector3(0f, 90, 0f);
 
             transform.eulerAngles = Vector3.up * Mathf.MoveTowardsAngle(transform.eulerAngles.y, targetRotation.eulerAngles.y,rotationSpeed * Time.deltaTime);
     }
         Vector3 motion = input;
         motion *= (Mathf.Abs (input.x) == 1 && Mathf.Abs (input.z) == 1) ? .7f : 1;
         motion += Vector3.up * -8;
 
         controller.Move (motion * Time.deltaTime);
 }
 }
 


The movement looks great, except for these problems:

  • I cant make it so the snake keeps moving after button has been let go, (must always be moving in the direction it is facing)

  • If the player holds W and D, the player will be able to move diagonally, I do not want this.

Currently the snake does not get bigger and I'm not really interested in integrating that just yet.

Any help would be great, thanks!

Comment
Add comment · Show 2
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 tebandesade · Feb 25, 2015 at 08:17 PM 0
Share

Hi! Regarding the second issue, how about making an If statement that If(Input.Get$$anonymous$$eyDown.D & Input.Get$$anonymous$$eyDown.W) do nothing, but else do your movement.

avatar image itsmealex100 · Feb 26, 2015 at 12:10 AM 0
Share

good thought, but I tried it and it doesn't seem to work. I think the fact that it needed an if or statement encase it was W and A seemed to brake that method.

3 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by fafase · Feb 26, 2015 at 12:11 PM

Best way would be to create a queue of nodes.

When you press a key, you define the movement the first should use, that is up/down/left/rigth. Since your level is probably a grid, you get the value of the next position and move your first guy there.

Now you have a queue of node with each of them having a ref to the previous one, all you need to do is move the node towards the position of the previous node. Now there is a trick in that, you do not want to move where the previous is currently or that would lead in diagonal movement, you want each node to move towards the last recorded grid position.

 A0 A1 A2 A3
 B0 B1 B2 B3
 C0 C1 C2 C3

Consider you have the head at A0 and two following nodes (N1 and N2) at B0 and C0, user presses right, Head gets A1 as target and starts moving there, N1 starts moving towards A0 which is the last recorded position of the previous node (the Head), N2 is moving towards B0 which is the last recorded position of the previous node (N1).

This will result in a snake movement which is fine if you use distinct items like in the video, if you need a full length and fluid movement for a snake then you should look into some kinda of curve algorithm like Beziers curve or Catmull rom, looks complex but the function is just plain arithmetic. If you use those with LineRenderer for instance, it will look fluid.

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 itsmealex100 · Feb 26, 2015 at 12:38 PM

Okay so i've managed to figure out how to keep the player moving in whichever way they are facing.

simply add the following

 public float fSpeed;
 
 void Update() {
 
 transform.localPosition = transform.localPosition + transform.forward * fSpeed * Time.deltaTime;
 
 }

However I still need help keeping the player from facing a diagonal direction, I need him to only turn 90 degrees like snake.

Comment
Add comment · Show 2 · 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 fafase · Feb 26, 2015 at 02:21 PM 0
Share

you should focus on creating a grid of positions, then based on the input you get a target position, your head has 3 possible movement based on the 4 positions around it $$anonymous$$us the one where the second node is.

Then you move the head towards that target point and rotate the head to face the direction movement (target.position - transform.position). Then the rest does the same except that the target is not defined by the input but by the previous position of the previous node.

avatar image itsmealex100 · Mar 02, 2015 at 11:21 AM 0
Share

thanks :), my only concern is that screen is consistently moving as it plays like your average runner. Will this still be possible?

avatar image
0

Answer by tedthebug · Jun 09, 2015 at 06:32 AM

Here is a snippet covering movement that I used for a variant. I found that the kids couldn't relate to the snakes local direction so just made it so that the arrow keys represented the direction the player wanted to move on the screen e.g. UP= up screen, LEFT = head across the left of the screen etc. I set the initial # of segments then increased/decreased the int value as needed. Due to the speed the segments destroyed/instantiated I had to set the minimum to be 2 so it appeared there was 1 onscreen. The moveTimer is just how long the segments are onscreen before they loop thru & destroy/instantiate, it is used as a buffer for the speed & may not be the best way but I'm still learning & it worked for what I wanted :)

using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI;

public class Manager : MonoBehaviour { static public Manager instance;

     // create list of body segments
     public List<InstantiateBody>bodySegments = new List<InstantiateBody> ();
     public GameObject bodyPrefab;
     // # of body segments, 2 is the minimum as 1 destroys & instantiates to quick to be seen.
     public int bodyNum = 5;
     // speed of snake & timer between destroy/instaniate for movement
     float speed = 2    ;
     float moveTimer = 0.5f;
     // direction of movement for instantiation, player starts moving up the screen
     public static Vector3 direction;
     // player start position
     private GameObject startspot;
             
     // set exit gameobject
     public GameObject exit;


     
     // Use this for initialization
     void Start ()
     {
             instance = this;
             // get position of starting place        
             startspot = GameObject.Find ("Start");
             // set player initial direction
             direction = Vector3.forward;
                             
             
     }
 
     // Update is called once per frame
     void Update ()
     {
             
         

             // set player move direction by arrow keys

             if (Input.GetKey (KeyCode.UpArrow))
                     direction = Vector3.forward;
             if (Input.GetKey (KeyCode.DownArrow))
                     direction = Vector3.back;
             if (Input.GetKey (KeyCode.LeftArrow))
                     direction = Vector3.left;
             if (Input.GetKey (KeyCode.RightArrow))
                     direction = Vector3.right;

             
             //decrement timer of action to replicate speed.
             moveTimer -= speed * Time.deltaTime;
             if (moveTimer <= 0) {
             
                     // replicate movement along 90 degree paths by destroying the body segment & removing it from the list
                     // at the end of the snake & instantiating one at the beginning 1 unit in the direction of movement
                     // from the segment at the start of the snake.  Insert this new piece into position 0 of the list.
                     
                     //remove last body segment in the list which will be the end of the snake
                     if (InstantiateBody.bodySegments.Count >= bodyNum) {
                             
                             Destroy (InstantiateBody.bodySegments [InstantiateBody.bodySegments.Count - 1].gameObject);
                             InstantiateBody.bodySegments.RemoveAt (InstantiateBody.bodySegments.Count - 1);
                     }
                     // instantiate the body segments.  If it's a new game first piece is at the start position
                     if (InstantiateBody.bodySegments.Count == 0) {
                             Instantiate (bodyPrefab, startspot.transform.position, bodyPrefab.transform.rotation);
                             // keep adding segments to the front of the snake
                     } else if (InstantiateBody.bodySegments.Count < bodyNum)
                             Instantiate (bodyPrefab, InstantiateBody.bodySegments [0].transform.position + direction, InstantiateBody.bodySegments [0].transform.rotation);
             
                     //reset move timer
                     moveTimer = 0.5f;
             }

             // set isTrigger for other segments, not the head, to enable collision detection if the
             // snake hits itself.
             for (int i = 0; i<InstantiateBody.bodySegments.Count-1; i++) {
                     if (i != 0) {
                             InstantiateBody.bodySegments [i].GetComponent<Collider> ().isTrigger = true;
                     }

             }


             
     }

}

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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Making a bubble level (not a game but work tool) 1 Answer

Multiple Cars not working 1 Answer

Help with Snake like movement algorithm. 1 Answer

Distribute terrain in zones 3 Answers

Animate Character movement? 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