PhysX 3.2: Simple box dynamic are not moving - simulation

I've uppgraded to PhysX 3.2 and have been struggling for days to have my test box moved by gravity but it simply won't to it.
I've followed the PhysX documentation but implemented it in my way. It's pretty much a default setup:
physx::PxSceneDesc sceneDesc = physx::PxSceneDesc((physx::PxTolerancesScale()));
sceneDesc.gravity = physx::PxVec3(0.0f, -9.8f, 0.0f);
if(!sceneDesc.cpuDispatcher)
{
physx::PxDefaultCpuDispatcher* mCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(4);
if(!mCpuDispatcher)
LOG("PxDefaultCpuDispatcherCreate failed!");
sceneDesc.cpuDispatcher = mCpuDispatcher;
}
if(!sceneDesc.filterShader)
sceneDesc.filterShader = &physx::PxDefaultSimulationFilterShader;
physxScene = physMgr->getSDK()->createScene(sceneDesc);
Creating the dynamic actor:
PxRigidDynamic* body = mPxSDK->createRigidDynamic(Convert::toPxTransform(transform));
PxRigidBodyExt::updateMassAndInertia(*body, 1.0f);
mPxScene->addActor(*body);
Add the box shape:
PxBoxGeometry geometry = PxBoxGeometry(Convert::toPxVector3(size));
if(geometry.isValid())
{
PxMaterial* material = api->createMaterial(0.5f, 0.5f, 0.1f);
PxShape* shape = createShape(actor, geometry, material);
PxRigidBodyExt::updateMassAndInertia(*body, 33.0f);
}
Simulating the scene as:
float elapsedTime = float((float)mTime.getElapsedTime() / 1000.0f);
mAccumulator += elapsedTime;
if(mAccumulator < mStepSize)
{
return;
}
else
{
mAccumulator -= mStepSize;
mPxScene->simulate(mStepSize);
mDynamicBodySys->updateGameObjectPositions();
mPxScene->fetchResults(true);
mTime.restart();
}
When I look into the Visual Debugger I can see the box and the frame count increasing. But it's not moving. The actor's and the box shape seem to have the correct propeties. LinearVelocity is increasing in negative Y axis, its mass is 33 etc. But the pose is still zero/identity. What am I missing?

Solved. The error was in my own logic. There was a sync logic problem where PhysX was trying to update my graphics while in the same time my positioning logic was telling PhysX to update with its previous position. So it got stuck and appeared to never be simulated.

Related

unity2d Problem With local positioning of child with rotating parent

I am making a game, in which I have clouds that when shot are hidden using sprite masks, the sprite masks are then attached to the cloud via parenting, here is the function that attaches and positions the masks.
public void SpawnGasCloudMask(Transform collisionTransform, Vector2 difference)
{
GasCloudMaskController selectedGasCloudMask = null;
for (int i = 0; i < gasCloudMaskList.Count - 1; i++)
{
if (!gasCloudMaskList[i].gameObject.activeSelf)
{
selectedGasCloudMask = gasCloudMaskList[i];
break;
}
}
if(selectedGasCloudMask == null)
{
selectedGasCloudMask = InstantiateGasCloudMaskController();
}
selectedGasCloudMask.transform.SetParent(collisionTransform);
float angle = collisionTransform.rotation.z;
Vector2 straightPosition = new Vector2(difference.x / collisionTransform.localScale.x, difference.y / collisionTransform.localScale.y);
selectedGasCloudMask.transform.localPosition = straightPosition;
selectedGasCloudMask.gameObject.SetActive(true);
}
enter image description here
This is the result when the cloud is not rotated, However if I rotate it, say 90 degrees.enter image description here
I have tried using RotateAroundLocal, but it is said to be deprecated and I cannot see it having an effect. Obviously what I want is for the masks to be properly attached to the parent based on its rotation, I tried doing some geometry, but solving this remains yet out of my reach. I believe I have to change its local parameter position, I did manage to do it with non parented gameObject, however the local parameter does not offer the RotateAround function. I will appreciate any help.TY.
I found my answer:
selectedGasCloudMask.transform.RotateAround(collisionTransform.position,
-collisionTransform.forward, collisionTransform.eulerAngles.z);
Since the position to which the child attaches to the parent, you need to account for the parent's rotation. The deprecate function that did exactly that was replaced by the generic function, which requires you to understand what is going on.

How can I make a simple automatic shoot function for a gun in Unity?

I am trying to create a procedural gun controller, but I can't find why my gun behaves so weird when I change the fire mod to automatic. To understand this better, I will give an example: when I try to shoot by pressing the "Mouse0" key, on semi auto mod it works fine, it behaves like I want it to (the bolt kicks back when I shoot, the front barrel kicks back - I animate them with code instead of frame animations from Unity or a 3rd party soft like Blender), but..., when I change to automatic, the problem is not that I get errors, The animations of the moving pieces don't work as they should and are not triggered correctly.
I tried to use different methods for shooting(using the WaitForSeconds() and WaitForSecondsRealtime() while using coroutines). It didn't work. I tried using the time function with scaled and unscaled time in the update function. I still got the same results.
What should I do to?
This is the shoot function untill now:
void GunFireManagement()
{
if (fireType == fireMethod.single)
{
foreach (BlowBack anim in animations)
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
gunSoundClone = Instantiate(gunShootSound, this.transform.position, Quaternion.identity) as GameObject;
anim.piece.transform.position = anim.kickbackState.transform.position;
}
if (anim.piece.transform.position != anim.initialPosition.transform.position)
{
anim.piece.transform.position = Vector3.Lerp(anim.piece.transform.position, anim.initialPosition.transform.position, anim.speed);
}
Destroy(gunSoundClone, 0.5f);
}
}
if (fireType == fireMethod.auto)
{
foreach (BlowBack anim in animations)
{
if (Input.GetKey(KeyCode.Mouse0) && Time.time - lastFired > 1f/autoFireRate)
{
lastFired = Time.time;
gunSoundClone = Instantiate(gunShootSound, this.transform.position, Quaternion.identity) as GameObject;
anim.piece.transform.position = anim.kickbackState.transform.position;
}
if (anim.piece.transform.position != anim.initialPosition.transform.position)
{
anim.piece.transform.position = Vector3.Lerp(anim.piece.transform.position, anim.initialPosition.transform.position, anim.speed);
}
Destroy(gunSoundClone, 0.5f);
}
}
}
The issue is how you are using Vector3.Lerp. The first two arguments you pass to the method are supposed to be the start and end positions of the animation, and the third one, t, is supposed to be the progress of the animation from the start towards the end, as a value between 0 and 1.
You can calculate the value of t by dividing the time since the shot started with the duration of the animation. For example if the length of the animation is 2 seconds, and the short started 1 second ago, then t should be 0.5.
if(isFiring)
{
float timeSinceShotStart = Time.deltatime - lastFired;
// t = s / v
float animationDuration = 1f / anim.speed;
UpdateBlockBackAnimationState(timeSinceShotStart / animationDuration);
}
}
private void SetBlowBackAnimationState(float progress01)
{
foreach(BlowBack anim in animations)
{
Vector3 initialPosition = anim.initialPosition.transform.position;
Vector3 finalPosition = anim.finalPosition.transform.position;
anim.piece.transform.position = Vector3.Lerp(initialPosition, finalPosition, progress01);
}
}
I recommend you try to split up your code into smaller methods that are easier to understand. You are trying to do so many things in one generic "GunFireManagement" method that it becomes pretty difficult to keep track of all the different pieces :)
I also recommend considering using a tweening framework such as DOTween to make it easier to animate things over time.

How do i fix the placement tool in my level editor?

So i'm currently making a game, and i've recently added a level editor, but the placing tool does not work how i wanted it to.
https://youtu.be/MuUvnVTL6eg
If you've watched this video, you've probably realized that the block placing works pretty much how placing rectangles in ms pain with alt does, and i want it to work like placing rectangles in ms pain without alt xd.
I'm using this code to place the block:
if (Input.GetKeyDown(KeyCode.Mouse0)){
startDrawPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
tmpObj = spawnObject(blocks[selected].gameObject, startDrawPos);
drawing = true;
}
if (Input.GetKey(KeyCode.Mouse0)){
Vector2 mPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 tmpScale = new Vector2(startDrawPos.x - mPos.x, startDrawPos.y - mPos.y);
tmpObj.transform.localScale = tmpScale;
}
if (Input.GetKeyUp(KeyCode.Mouse0))
{
drawing = false;
var scale = tmpObj.transform.localScale;
//Code below destroys the object if it's too small to avoid accidental placements
if (scale.x <= 0.1 && scale.x > -0.1 || scale.y <= 0.1 && scale.y > -0.1)
{
Destroy(tmpObj);
}
}
(All of this code is in the Update() function)
(spawnObject function just instantiates the object prefab)
There is a bit more code but it has nothing to do with the position of the block, it just detect which block is selected and decides if it can be resized or not.
I solved this problem. But because your complete script is not in question, I rebuilt the code with IEnumerator, Here, by pressing the left mouse button, IEnumerator is activated and all commands are grouped in one method to make the code more efficient.
private void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0)) StartCoroutine(DrawRect());
}
How does the Desktop Rect formula work?
By running IEnumerator, the code first records the starting point of the mouse. It also makes a simple cube because I do not have access to your objects. Now until the mouse is pressed. Resize Rect to the difference between current and recorded points. The only thing is that to avoid ALT control, you have to place it between the current and initial points. The reason for adding the camera forward is to be seen in the camera.
cubeObject.transform.position = (startDrawPos + currentDrawPos) / 2;
The final structure of the DrawRect is as follows:
public IEnumerator DrawRect()
{
drawing = true;
var scale = Vector2.zero;
var startDrawPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var cubeObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
while (Input.GetKey(KeyCode.Mouse0))
{
var currentDrawPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
cubeObject.transform.position = (startDrawPos + currentDrawPos) / 2 + Camera.main.transform.forward * 10;
scale = new Vector2(startDrawPos.x - currentDrawPos.x, startDrawPos.y - currentDrawPos.y);
cubeObject.transform.localScale = scale;
yield return new WaitForEndOfFrame();
}
if (scale.x <= 0.1 && scale.x > -0.1 || scale.y <= 0.1 && scale.y > -0.1) Destroy(cubeObject);
drawing = false;
}

In Away3d particles system, adding a particleFollowNode to the particleAnimationSet make BillboardNode did not work

I've made a snow effect with particles system in away3d, but when I added a particleFollowNode to the ParticleAnimationSet,then the billboardNode did not work. Anybody knows how to fix this bug? Thanks for your help.
ActionScript:
//setup the particle animation set
_particleAnimationSet = new ParticleAnimationSet(true, true);
_particleAnimationSet.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.LOCAL_STATIC));
_particleAnimationSet.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.LOCAL_STATIC));
particleFollowNode=new ParticleFollowNode(true,true);
//add particleFollowNode for moving particles around
_particleAnimationSet.addAnimation(particleFollowNode);
//then BillBoad stopped working...
_particleAnimationSet.addAnimation(new ParticleBillboardNode());
_particleAnimationSet.initParticleFunc = initFunc;
I've fixed the bug. the particle mesh's bounds doesn't update properly which cause the mesh culling step cut it off while the mesh's fake bounds isn't in camera's frustum .
How to fix:
1. Set particle mesh's id as "Particles"
2. In MeshNode.cs file, function acceptTraverser, modify as :
override public function acceptTraverser(traverser:PartitionTraverser):void
{
//trace(_mesh.id);
if (traverser.enterNode(this)||_mesh.id=="Particles")
{
super.acceptTraverser(traverser);
var subs:Vector.<SubMesh> = _mesh.subMeshes;
var i:uint;
var len:uint = subs.length;
while (i < len)
traverser.applyRenderable(subs[i++]);
}
}

Chipmunk 6 space initialization

I am trying to use chipmunk6.x and having problems with it. It is not creating the physics environment. How do I enable the chipmunk6.x physics environment in my project? The space manager system is working well. I hope there is no problem with the chipmunk lib attachment.
I am using the cocos2d old version I just replaced the chipmunk lib.
space = cpSpaceNew();
space->gravity = cpv(0, -100);
//
// rogue shapes
// We have to free them manually
//
// bottom
cpShape *walls_[4];
walls_[0] = cpSegmentShapeNew( space->staticBody, cpv(0,0), cpv(s.width,0), 0.0f);
// top
walls_[1] = cpSegmentShapeNew( space->staticBody, cpv(0,s.height), cpv(s.width,s.height), 0.0f);
// left
walls_[2] = cpSegmentShapeNew( space->staticBody, cpv(0,0), cpv(0,s.height), 0.0f);
// right
walls_[3] = cpSegmentShapeNew( space->staticBody, cpv(s.width,0), cpv(s.width,s.height), 0.0f);
for( int i=0;i<4;i++) {
walls_[i]->e = 1.0f;
walls_[i]->u = 1.0f;
cpSpaceAddStaticShape(space, walls_[i] );
}
You need to be more specific than "It is not creating the physics environment."
The code you pasted otherwise looks fine. What happens with it, and what are you expecting should happen.