I am attempting to train a ragdoll to walk by manipulating the parts of it’s legs in a way that mimics walking. The script gets a random Vector3 within a certain range of the target Vector3 for the motion every time increment (waittime). This Vector3 is then applied as force to the respective leg part every frame in FixedUpdate(). The only issue is that if waittime is below 10 seconds, then unity just crashes immediately. No error message, just vanishes after play mode is ready. I’m not entirely sure why this is happening, and if anyone could point out the error in my code that would be amazing
.
Here is what averted the crash:
- Commenting out the 2 lines in FixedUpdate() responsible for applying force
- Setting the “forceapplyfoot * multiplier” and “forceapplyknee * multiplier” to a constant Vector3
- increasing waittime to 10 (should be around 1 ideally)
Here’s the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Walking : MonoBehaviour
{
public List<Rigidbody> legbones;
public bool walkready;
public List<Vector3> kneemotions;
public List<Vector3> footmotions;
public int currentid;
public float divamountx_foot;
public float divamounty_foot;
public float divamountx_knee;
public float divamounty_knee;
public float waittime;
public Rigidbody currentkneerigidbody;
public Rigidbody currentfootrigidbody;
public int legboneid;
public bool legswitched;
public float multiplier;
public Vector3 forceapplyfoot;
public Vector3 forceapplyknee;
public bool movementprepped;
public bool movementready;
//LIST NUMBERS LEGBONES: 1: upper right leg 2: lower right leg 3: upper left leg 4: lower left leg
//ONLY APPLY FORCE ON X AND Y AXES
//PHASES: 1(knee forward up, foot forward) 2(knee forward, foot forward slighly down) NEXT LEG 3(knee forward up, foot forward) 4(knee forward, foot forward slightly down) REPEAT
void FixedUpdate()
{
if(walkready)
{
StartCoroutine("takesteps");
walkready = false;
}
if(movementready)
{
currentkneerigidbody = legbones[legboneid];
currentfootrigidbody = legbones[legboneid + 1];
currentkneerigidbody.AddForce(forceapplyknee * multiplier, ForceMode.Force);
currentfootrigidbody.AddForce(forceapplyfoot * multiplier, ForceMode.Force);
}
}
public IEnumerator takesteps()
{
currentid++;
if(currentid == 3)
{
currentid = 1;
legswitched = !legswitched;
}
if(legswitched)
{
legboneid = 2;
}
else if(!legswitched)
{
legboneid = 0;
}
forceapplyknee = kneemotions[currentid - 1];
float kneevaraiationx = forceapplyknee.x / divamountx_knee;
float kneevaraiationy = forceapplyknee.y / divamounty_knee;
forceapplyknee = new Vector3(Random.Range(forceapplyknee.x - kneevaraiationx, forceapplyknee.x + kneevaraiationx), Random.Range(forceapplyknee.y - kneevaraiationy, forceapplyknee.y + kneevaraiationy), 0);
forceapplyfoot = footmotions[currentid - 1];
float footvaraiationx = forceapplyfoot.x / divamountx_foot;
float footvaraiationy = forceapplyfoot.y / divamounty_foot;
forceapplyfoot = new Vector3(Random.Range(forceapplyfoot.x - footvaraiationx, forceapplyfoot.x + footvaraiationx), Random.Range(forceapplyfoot.y - footvaraiationy, forceapplyfoot.y + footvaraiationy), 0);
yield return new WaitForSeconds(waittime);
walkready = true;
if(movementprepped)
{
movementready = true;
movementprepped = false;
}
I haven’t perfected the code yet, so it probably won’t work as expected, and I haven’t optimized it yet, but nothing in there that I can see should cause a fatal error. Hope someone can help.