- Home /
Is this an [optimal, adequate, ftarded] way to make a snake follow its head?
The first thing I tried was: every time the head turns, it iterates through the array of body segments and sends each one an Invoke message in (segmentIndex / snakeSpeed) seconds. This was a total failure. Small errors got larger every turn until the segments were flying all over the map with minds of their own.
Now each segment has two arrays- actually Lists- called turnQueue (String) and wayPoints (Vector3). As the head starts a turn, it sends every segment the current head position and pushes it onto wayPoints, and the direction it is turning which gets pushed onto turnQueue. And that's all I've written so far.
When a segment reaches the position wayPoints[1] it Shifts wayPoints, making the position returned its new destination and wayPoints[2] the new wayPoints[1]. It then calls its own "Turn"+turnQueue[1]+"()" function and Shifts turnQueue too.
I'm not sure how it will know when it gets there. I first thought I could Lerp from the position after the last turn to the next waypoints' position over the time it should take to get there, then round off the error when it does. This would fail if the snake speeds up midway through, which it eventually will. I don't want to have to switch through all the directions to find out which way the segment is going to know which axis of the Vector3 to compare against. And I can't count on the segment position ever exactly equalling the waypoint position, it could skip right over it from one frame to the next. (The waypoints will always be on integer coordinates, though I'm not sure if that helps me for this purpose.)
So I will just check if the distance to the next waypoint is less than (some fraction of a unit that is still more than the segment could travel in a single frame) and if so, then Lerp from the current location to the waypoint location over the fraction of a second that is left, do the turn, and finally snap to the nearest grid point.
If there are still errors or gaps that accumulate, when I've finished banging my forehead on the desk I guess I will make a "tensioning" function that propagates from the tail to the head and snaps each not-presently-turning segment to the back of the segment in front of it.
The whole thing feels kind of kludgy and wasteful I fear it will start to really lag once the snake gets long enough. So before I put too much time into this, is there a more efficient method of getting the same result that would be obvious to someone with more programming experience?
It seems like you only need one list of WayPoints, which you build as you move. Each segment has a speed, a position and the next node in the path. Each smooths their speed to their "parent"'s speed. If you go off the WayPoints, you keep moving the way you were. Initially you have two points (0,0) and (5,0) for five segment snake going right, with segements placed at (0,0) (1,0) ... .
Answer by terablargh · Apr 02, 2011 at 04:50 PM
I finally figured it out- as often seems to be the case with Unity, the solution was to ask myself; "is there a way this could be done with triggers?"
Yes, there is. (how could I have forgotten func_trains and path_corners?) The head lays down turnZone colliders every time it turns, and these turn every segment that enters them and then sends it off at 90. Then the tail object destroys the turnZone objects onTriggerExit. There's no direct communication between the head and the segments, and the segments are not actually being moved or rotated during the turn, just playing one of their animations and then repositioned at the end.
Answer by AngryOldMan · Mar 19, 2011 at 11:29 PM
This may seem stupid or even a waste of time but Occams Razor suggests that the simplest explanation is often best. What I mean by that is try having hinge joints on the back of the head which the front of the tail part connects to then so on and so forth for the rest of the tail segments. This involves a lot less scripting also and as much fun as scripting is it seems that maybe you should try a change, you have tried some pretty damn complex stuff by the sounds of it.
That will cause the back of the snake to "cut across" when the head makes a 90 degree turn. The classic snake game has each segment copy the moves of the front parts.
It would work fine for the old version but would require a lot of tweaking for a high res version. Seen as though you have sack all reputation and have made multiple accounts for when you loose reputation, I don't think anyone should listen to your input. The fact is I have created a simliar thing to what terablargh is trying to achive and I did it through this method, so sod off you uninsightful little child.
I just tested it with 6 cubes, hinge on the "front" cube linked to the back: Hinge axis set to Y. Limits set to 90 and Bounce set to 1 (helped prevent the "whip tail" effect on stopping.) Looked fine as long as I don't stop too fast. In hindsight, the cubes should have been segment
prefabs for ease in tweaking. BUT, the back cubes cut diagonal on 90 degree turns, as a real connected system should. It's like dragging a rope.
double up on the hinge joints (so one connected to another) or add an empty prefab inbtetween joints
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Camera rotation around player while following. 6 Answers
Having a friendly character follow player 0 Answers