- Home /
Moving a character's legs and feet using one key to initiate lifting of a foot, then an analog stick / directional keys to move the foot to a target.
Hi everyone,
I was interested in making a certain control style described below, and wanted to talk with you folks about ways to implement it. The basic background of the game is you're a big monster that has really laborious controls to move since the character is so massive (to create humor).
The basic concept is as follows:
The character is in a standing position.
The character holds a shoulder button (if a controller) and the foot lifts up. If the Right shoulder is held, the right foot raises. If the Left shoulder is held, the left foot raises. Optional - a little target reticule appears on the ground beneath the foot where it would land if the shoulder button is released.
The player moves the analog stick or WASD / IJKL to move the foot that's currently raised.
Once the player has placed it where they want to stomp / step down, they release the shoulder button.
Upon releasing the shoulder button, the foot returns to the ground. Note: upon hitting the ground, the body will sort of bounce to where the foot landed to balance out. Or, if applicable, will always remain in the center of the two feet. Not sure which is better yet.
Here's a sketch representation of what I mean:
I think a way to get this done is incorporating a portion of this unity answer dealing with moving an object in an arc around another with the analog stick and maybe having a similar joint structure to this unity answer about stretchy legs. I've never approached a movement system like this so I really have no idea what a good way to go about it is. Worst case scenario, I'll fiddle with a few ideas.
What do y'all think?
Answer by justinpatterson · Jan 09, 2014 at 08:27 PM
Hey y'all! Initial solution is below. It's a little messy but I think it might get people's creative juices flowing. This was with 3 cubes (body, leftfoot, rightfoot).
Some future business:
Make it work with a joint system instead of just cubes
Make the parent game object move a bit more accurately without making the inner movements be weird
Set the feet to be a constant level above collider ground, and draw a target where the collider hits the ground
Edit Jan 9: added code to make the feet remain above ground (though should add a hit.tag check to make sure it's the ground).
#pragma strict
private var footLeft:GameObject;
private var footRight:GameObject;
private var body:GameObject;
private var moveState:int = 0; // 0 none, 1 right, 2 left, 3 jump
private var footSpeed:float = 5.0;
private var bodyOffset : float = 0;
function Start () {
footLeft = GameObject.Find("Foot_L");
footRight = GameObject.Find("Foot_R");
body = GameObject.Find("Body");
bodyOffset = body.transform.position.y - footLeft.transform.position.y;
}
function Update () {
MoveStateControl(moveState);
}
function MoveStateControl(i:int){
switch(i){
case 0:
if(Input.GetKey(KeyCode.R)){
Debug.Log("R");
moveState = 1;
}
else if(Input.GetKey(KeyCode.Q)){
Debug.Log("L");
moveState = 2;
}
break;
case 1:
FootControl(footRight);
if(Input.GetKeyUp(KeyCode.R)){
moveState = 0;
FootRaise(footRight,false);
}
break;
case 2:
FootControl(footLeft);
if(Input.GetKeyUp(KeyCode.Q)){
moveState = 0;
FootRaise(footLeft,false);
}
break;
default:
break;
}
}
function FootControl(f:GameObject){
Debug.Log(f.name);
var translationX : float = Input.GetAxis ("Vertical") * footSpeed * Time.deltaTime;
var translationZ : float = Input.GetAxis ("Horizontal") * footSpeed * Time.deltaTime;
f.transform.Translate (translationZ, 0, translationX);
FootRaise(f,true);
body.transform.Translate(translationZ/2, 0, translationX/2);
}
function FootRaise(f:GameObject, b:boolean){
var hit:RaycastHit;
var posY:float = 0;
if(
Physics.Raycast(f.transform.position, Vector3(0,-1,0), hit)
){
if(b) posY = hit.point.y+2.5;
else posY = hit.point.y+2;
}
f.transform.position.y=posY;
body.transform.position.y = (posY+(bodyOffset/2));
}
I know this is old. But is there a C# version of this? :D @justinpatterson
Hi @Bongorebell - it shouldn't be too bad to switch the code to C#.
"function Update" becomes "void Update()"
"var footLeft:GameObject" becomes "GameObject footLeft"
stuff like that.
Give it a shot, and submit your code snippet here if you have any trouble and I'll help you debug it!
Each $$anonymous$$ethod of Unity can be looked up in the scripting API which current gives both UScript and C# version. You can learn a lot about code porting this way and I ENCOURAGE YOU TO DO SO as UnityScript is pretty much Discontinued.
Thank you! I got this far. Hopefully doing it right but i cant seem to figure out what to do with the last bit of lines.
private GameObject footLeft; private GameObject footRight; private GameObject body; private int moveState = 0; // 0 none, 1 right, 2 left, 3 jump private float footSpeed = 5.0f; private float bodyOffset = 0;
void Start()
{
footLeft = GameObject.Find("Foot_L");
footRight = GameObject.Find("Foot_R");
body = GameObject.Find("Body");
bodyOffset = body.transform.position.y - footLeft.transform.position.y;
}
private void Update()
{
$$anonymous$$oveStateControl(moveState);
}
void $$anonymous$$oveStateControl(int i)
{
switch (i)
{
case 0:
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.R))
{
Debug.Log("R");
moveState = 1;
}
else if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.Q))
{
Debug.Log("L");
moveState = 2;
}
break;
case 1:
FootControl(footRight);
if (Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.R))
{
moveState = 0;
FootRaise(footRight, false);
}
break;
case 2:
FootControl(footLeft);
if (Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.Q))
{
moveState = 0;
FootRaise(footLeft, false);
}
break;
default:
break;
}
}
void FootControl(GameObject gameObject)
{
Debug.Log("f.name");
float translationX = Input.GetAxis("Vertical");
float translationZ = Input.GetAxis("Horizontal");
transform.Translate(translationZ, 0, translationX);
FootRaise(f, true);
body.transform.Translate(translationZ / 2, 0, translationX / 2);
}
void FootRaise(GameObject f, bool b)
{
RaycastHit hit;
var posY:float = 0;
if (
Physics.Raycast(f.transform.position, Vector3(0, -1, 0), hit)
)
{
if (b) posY = hit.point.y + 2.5;
else posY = hit.point.y + 2;
}
f.transform.position.y = posY;
body.transform.position.y = (posY + (bodyOffset / 2));
}
}
Hey @Bongorebell, this will be a good learning experience. So, what lines specifically are you having trouble with in your conversion above. When you say "the last bit" - for us forum members, it would be much better if you provide line numbers and such.
I should probably also note this was made when I was first learning how to program, so na$$anonymous$$g conventions and other things that I should have followed... weren't. We can fix that now.
Are these the lines you're having trouble with?
f.transform.position.y = posY;
body.transform.position.y = (posY + (bodyOffset / 2));
Answer by Gizemeral · Apr 10, 2020 at 07:08 AM
@justinpatterson hi are you still here i have problem also like this.İ want my character moves like "Steppy Pants" game character .Can you please help
NOTE - I previously responded with one of my many business accounts. I'll remove that post shortly. Copying it here as my main account.
I've never heard of Steppy Pants - though after a quick google, looks hilarious! I'm not sure how much help I can provide, though I can get you part of the way I'm not an animator / technical artist so describing how to make a physics-based / procedural animation might be beyond me. I can try and help though. As you can see, this post never really gained an audience so a solid solution never really came about for the original problem. I ended up just changing my mechanics to simplify the problem, so maybe now 6 years later we can figure something out. Can you provide me more details about your problem implementing a similar system to the above drawing?