- Home /
How can I move this part in a rectangle when I press a key? [C#]
I am trying to get an object to move in a rectangle when I use either the"Horizontal" or "Vertical" input axes. What I have tried keeps on adding to the position, making the localPosition extremely high, eventually to an error. If I am doing something wrong, please tell me. Any help will be appreciated. (The part is an inverse kinematic tracker part)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IkProceduralAnimation : MonoBehaviour {
Animator anim;
public Transform LeftArmIkTarget;
public Transform RightArmIkTarget;
public Transform LeftLegIkTarget;
public Transform RightLegIkTarget;
public Transform Head;
public Transform UpperTorso;
public Transform LowerTorso;
public Transform LeftEye;
public Transform RightEye;
float ikWeight = 1;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
StartCoroutine("Walk");
}
}
IEnumerator Walk()
{
float LeftLegMovementHeight = 0.01f;
float LeftLegMovementWidth = 0.01f;
float LeftLegMovementSpeed = 2;
yield return new WaitForSeconds(0.1f);
Debug.Log("LegUp");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition,new Vector3(0,0,LeftLegMovementWidth),Time.deltaTime*LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LeftForward");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, LeftLegMovementHeight, 0), Time.deltaTime * LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LegDown");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, 0, -LeftLegMovementWidth), Time.deltaTime * LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LegBack");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, -LeftLegMovementHeight, 0), Time.deltaTime * LeftLegMovementSpeed);
}
void OnAnimatorIK ()
{
anim.SetIKPositionWeight(AvatarIKGoal.LeftFoot, ikWeight);
anim.SetIKPosition(AvatarIKGoal.LeftFoot, LeftLegIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.RightFoot, ikWeight);
anim.SetIKPosition(AvatarIKGoal.RightFoot, RightLegIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, ikWeight);
anim.SetIKPosition(AvatarIKGoal.LeftHand, LeftArmIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.RightHand, ikWeight);
anim.SetIKPosition(AvatarIKGoal.RightHand, RightArmIkTarget.position);
}
}
Answer by Perfecter · Jul 08, 2018 at 10:38 AM
Hi. Seems you starts coroutine too many times. Try this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IkProceduralAnimation : MonoBehaviour {
Animator anim;
public Transform LeftArmIkTarget;
public Transform RightArmIkTarget;
public Transform LeftLegIkTarget;
public Transform RightLegIkTarget;
public Transform Head;
public Transform UpperTorso;
public Transform LowerTorso;
public Transform LeftEye;
public Transform RightEye;
float ikWeight = 1;
private bool moving = false;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update ()
{
if (!moving){
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
StartCoroutine("Walk");
}
}
}
IEnumerator Walk()
{
moving = true;
float LeftLegMovementHeight = 0.01f;
float LeftLegMovementWidth = 0.01f;
float LeftLegMovementSpeed = 2;
yield return new WaitForSeconds(0.1f);
Debug.Log("LegUp");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition,new Vector3(0,0,LeftLegMovementWidth),Time.deltaTime*LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LeftForward");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, LeftLegMovementHeight, 0), Time.deltaTime * LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LegDown");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, 0, -LeftLegMovementWidth), Time.deltaTime * LeftLegMovementSpeed);
yield return new WaitForSeconds(0.1f);
Debug.Log("LegBack");
LeftLegIkTarget.localPosition += Vector3.Lerp(LeftLegIkTarget.localPosition, new Vector3(0, -LeftLegMovementHeight, 0), Time.deltaTime * LeftLegMovementSpeed);
moving = false;
}
void OnAnimatorIK ()
{
anim.SetIKPositionWeight(AvatarIKGoal.LeftFoot, ikWeight);
anim.SetIKPosition(AvatarIKGoal.LeftFoot, LeftLegIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.RightFoot, ikWeight);
anim.SetIKPosition(AvatarIKGoal.RightFoot, RightLegIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, ikWeight);
anim.SetIKPosition(AvatarIKGoal.LeftHand, LeftArmIkTarget.position);
anim.SetIKPositionWeight(AvatarIKGoal.RightHand, ikWeight);
anim.SetIKPosition(AvatarIKGoal.RightHand, RightArmIkTarget.position);
}
}
This is working better, it is running the function correctly, except it is giving extreme values of the localPosition of the object. It going up, left, down, and right should result in it returning to the same localPosition, but it is not. I cannot figure out why. Any help will be greatly appreciated.
Seems it happens because you waiting 0.1 sec between steps but using Time.deltaTime in formulas. It can have different values during playing. Check this moment.
oh. And you using += to plus the reuslt of Vector3.Lerp. I'm not sure but seems you wanted to use equal (=).
Your answer
Follow this Question
Related Questions
Find a position forward of GameObject with possible angle 1 Answer
How can I set the default position of a 3D object? 2 Answers
How do I make my sound work in proper 3D space for VR 1 Answer
Problem with positioning of scaled models 1 Answer
How would you sort gameobjects by their position in a 3D grid? 1 Answer