- Home /
Strange "lock" when setup colliders and rigidbody by scripting...
Dear all,
I am facing a strange problem while setup BoxCollider and WheelColliders on a rigidbody character through scripting. All colliders are well installed on the rigidbody in the game view.
If i add ridigbody component before colliders some axis of character seams to be "locked"
The effect disappear when i change a value into rigidbody inspector.
My first workaround was to setup colliders (collider components) before physics (add(rigidbody)).
void Awake() {
setupColliders();
setupPhysX();
}
And in this it work well ! But i got this message:
WheelCollider requires an attached Rigidbody to function.
How i can get my script working properly by setting up rigidbody before colliders?
void Awake() {
setupPhysX();
setupColliders();
}
My full code is just under :)
Thanks for support,
Best regards,
Thomas
public class CharacterBehave : MonoBehaviour {
/** Attributes / // Wheels private WheelCollider wheelFL; private WheelCollider wheelFR; private WheelCollider wheelRL; private WheelCollider wheelRR; private WheelCollider[] wheelsArray; // Reference all wheel in an array private float steeringAngle;
public float jumpForceCoeff; public bool inAir; //public float riderMass = 70.0f;
/** Methods /
void Awake() { setupColliders(); setupPhysX(); }
void Start () {
}
void Update () { }
void FixedUpdate() {
InputListener();
if (Input.GetKeyUp("space"))
{
Debug.Log("Jump");
rigidbody.AddRelativeForce(Vector3.up * rigidbody.mass * jumpForceCoeff);
}
}
public void InputListener() {
float axisX = Input.GetAxis("Horizontal");
steeringAngle = axisX * 1.4f;
wheelFL.steerAngle = steeringAngle;
wheelFR.steerAngle = steeringAngle;
wheelRL.steerAngle = -steeringAngle;
wheelRR.steerAngle = -steeringAngle;
}
public void setupPhysX() { gameObject.AddComponent("Rigidbody");
rigidbody.mass = 70; }
public void setupColliders() {
/**
* Creating Colliders objects
*/
GameObject rootColliderObj = new GameObject("Colliders"); // Creating root Collider GameObject
rootColliderObj.transform.parent = this.transform;
rootColliderObj.transform.localPosition = Vector3.zero + Vector3.up * -0.5f;
GameObject baseColliderObj = new GameObject("base"); // Creating baseColliderGameObject and affect it to Rider
baseColliderObj.transform.parent = rootColliderObj.transform;
baseColliderObj.transform.localPosition = Vector3.zero;
GameObject bodyColliderObj = new GameObject("body"); // Creating baseColliderGameObject and affect it to Rider
bodyColliderObj.transform.parent = rootColliderObj.transform;
bodyColliderObj.transform.localPosition = Vector3.zero;
/**
* Create base
*/
BoxCollider baseCollider = baseColliderObj.AddComponent("BoxCollider") as BoxCollider;
baseCollider.size = new Vector3( transform.localScale.x * 2,
transform.localScale.y / 3,
transform.localScale.z * 7);
baseCollider.center = new Vector3(0, transform.localScale.y * -4.0f, 0); // Set baseCollider position
// Create bodyBox
BoxCollider bodyCollider = bodyColliderObj.AddComponent("BoxCollider") as BoxCollider;
bodyCollider.size = new Vector3( transform.localScale.x * 2,
transform.localScale.y * 7,
transform.localScale.z);
/**
* Create 4 Wheels and affect them
*/
// Create gameObject for wheels
GameObject[] wheelObj = new GameObject[4];
wheelObj[0] = new GameObject("wheel_" + "FL");
wheelObj[1] = new GameObject("wheel_" + "FR");
wheelObj[2] = new GameObject("wheel_" + "RL");
wheelObj[3] = new GameObject("wheel_" + "RR");
// Parent to base and Create WheelColliders
wheelsArray = new WheelCollider[4];
for (int i = 0; i < wheelObj.Length; i++) {
wheelObj[i].transform.parent = baseColliderObj.transform;
wheelsArray[i] = wheelObj[i].AddComponent("WheelCollider") as WheelCollider;
wheelObj[i].transform.localPosition = Vector3.zero;
}
// Affect wheels to position naming convention Front/Rear/Left/Right
WheelFL = wheelsArray[0];
WheelFR = wheelsArray[1];
WheelRL = wheelsArray[2];
WheelRR = wheelsArray[3];
// Placing the wheels
float wheelYPlacement = (bodyCollider.size.y / 2.0f * -1) + baseCollider.size.y - 0.1f;
WheelFL.center = new Vector3(baseCollider.size.x / -2, wheelYPlacement, baseCollider.size.z / 2);
WheelFR.center = new Vector3(baseCollider.size.x / 2, wheelYPlacement, baseCollider.size.z / 2);
WheelRL.center = new Vector3(baseCollider.size.x / -2, wheelYPlacement, baseCollider.size.z / -2);
WheelRR.center = new Vector3(baseCollider.size.x / 2, wheelYPlacement, baseCollider.size.z / -2);
}
}
Because i will often import character from Blender to Unity and i wanted to "computerize" the assignment of rigidbody and Colliders.
Thanks for your reply,
Regards,
$$anonymous$$
Your AddComponent method is weak. AddComponent() is what you should use.
@Jessy i corriged to AddComponent() with your advice. Thanks for your recommendation ! But this is a way to solve my current problem? . I may setup collider and rigidbody through graphical interface? It still doesn't work... Thanks for the support ! Regards, Toum
Answer by Statement · Jan 30, 2011 at 09:45 PM
Here's a weird hack I had to do for some physics init myself: After colliders have been placed on the object with rigidbody (have the rigidbody added first), you can enable and disable the rigidbody. This seems to force a recalculation of inertia etc.
Thanks for reply man. I used "rigidbody.active = false/true;" at the end of colliders setup. Unfortunatly i get again the message "WheelCollider requires an attached Rigidbody to function". Besides "rigidbody.active" seams to be deprecated in Unity 3. Thanks, Toum
Well, yeah, the active member is deprecated. It's the gameObject.active you should use. Hm, it's strange you get that message. Are you very sure you have created the rigidbody (and parented children before adding colliders)? I can do a test tomorrow myself to see if I can get it to work, but tonight I'll just lie in sick.
Yes i am pretty sure. look at my "setupColliders()" function. Have good recovery. Regards. $$anonymous$$
Comment in addition to the previous... If i use "gameObject.active = false/true" i got again the message "WheelCollider requires an attached Rigidbody to function." With rigidbody declared before colliders... !
Answer by Edy · Mar 15, 2011 at 01:17 AM
Try adding the rigidbody, wait one fixed frame, then add the WheelColliders. You should move the function calls SetupPhysX() and SetupColliders() to FixedUpdate, then use some flags or counters to ensure the correct order:
var initCounter = 0;
function FixedUpdate() { if (initCounter == 0) SetupPhysX(); if (initCounter == 1) SetupColliders(); initCounter++; if (initCounter < 2) return;
// (regular FixedUpdate code)
//....
}
You should consideer the function as "initialized" when initCounter >= 2. Then you can operate normally.
Answer by creat327 · Apr 21, 2011 at 02:17 PM
i think this will help you: http://forum.unity3d.com/threads/86549-bug-on-order-of-activation-for-wheelcolliders?p=557907#post557907
I've just posted it. Basically you need to do to manually activate the rigidbody before usage because there seems to be a delay. If it works, please post on the thread so it gets some attention. I've submitted it as a bug already :)
Answer by Nition · Nov 15, 2012 at 08:57 PM
This is still a bug in Unity 4 unfortunately. Now, after adding your wheel colliders, you need to do this:
gameObject.SetActive(false);
gameObject.SetActive(true);
Your answer
Follow this Question
Related Questions
Wheelcolliders stuck in ground 0 Answers
Small colliders go through objects 0 Answers
Is it new in Unity? Collider exception . . . 1 Answer
Multiple Colliders 1 Answer
Unity's collision system VS designing my own basic collision system 0 Answers