A couple of notes about character controller usage first:
I am using CharacterController and set it's Body Linear Velocity property to this vector.
Setting a CharacterController's LinearVelocity won't work very well in most cases. Its motion is controlled by the CharacterController.HorizontalMotionConstraint. It attempts to stop any motion which doesn't go along with the constraint's MovementDirection. So, if the MovementDirection is still at its default (0,0), the constraint will try to make the character stop relative to its support.
But I want to rotate a body to this direction as well.
I would recommend against rotating the CharacterController.Body. It's designed to have a fixed orientation- that's why the inertia tensor is infinite. No physical force can change its orientation or make it fall over.
Instead of rotating the character's body itself, I would recommend handling character facing direction in the gameplay logic and graphics side of things. For example, to draw the character with the right orientation, the graphical transform would take into the facing direction. It could additionally take into account the full view direction to transform the upper body or head to look up and down. (This approach captures more detail than the CharacterController.Body.Orientation version, since the body's orientation can't include any view pitch angle. It would make the whole cylinder tip over in a physically disruptive way.)
Check out the BEPUphysicsDemos CharacterControllerInput class for an example of how to control the character. Note the setting of both the CharacterController.HorizontalMotionConstraint.MovementDirection and CharacterController.ViewDirection in the Update method. The MovementDirection is interpreted based on the given ViewDirection.
Regarding the general transform manipulation issues:
So I getting actual forward direction. Multiplying speed vector from client with speed, then multiply Z part to -1 (I don't know why I need to do it, but for correct displaying in unity I need to do it). Then I took difference between actual and desired directions (orientations). And then add this difference to actual orientation. But on client it rotates character wrong. Maybe I doing something wrong?
One problem is that the Quaternion.GetQuaternionBetweenNormalizedVectors function assumes that the vectors it is given are unit length. Given that an orientation matrix is orthonormal, the 'frd' vector is unit length, but the refVector (WalkDirection * MoveSpeed) is not unit length.
Additionally, if the WalkDirection ever has any Y component (assuming the character's up direction is along the Y axis), the character's orientation could get into very strange states because it would include rotations which aren't strictly yawing. There's also the possibility that the character will rotate vertically rather than horizontally to reach a WalkDirection 180 degrees away from the current forward direction, since all rotations to the goal state are equally short.
2. I desided to do a simple app with BEPUPhysics (using XNAFramework). Add some entity's and try to rotate it in the same way. To see, maybe I am doing well, but problem in client side diasplaying. I created this app using some classes from demos, loaded static mesh, but didn't found any way to rotate it, so, how I can do it?
StaticMeshes are transformed by the AffineTransform passed into the constructor. Note the third parameter, from the StaticMeshDemo:
Code: Select all
var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(Matrix3x3.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), new Vector3(0, -10, 0)));
The affine transform is the combination of a linear transform (a 3x3 matrix) and a translation. To rotate it, pass in a different linear transform.
The transform can also be accessed after creating the mesh through the staticMesh.WorldTransform property.