Przeglądaj źródła

More work on user manuals

BearishSun 9 lat temu
rodzic
commit
2bc0d229c9

+ 102 - 0
Documentation/Manuals/Native/User/characterController.md

@@ -0,0 +1,102 @@
+Character controller 						{#characterController}
+===============
+
+Character controller is a special type of a dynamic physics objects that is intended to be used primarily for the movement of the user-controller character in your game. Although you could simulate your character using a rigidbody, it is usually preferable to use the character controller due to various specific functionality it offers.
+
+It is represented using the @ref bs::CCharacterController "CharacterController" component.
+
+~~~~~~~~~~~~~{.cpp}
+HSceneObject rigidbodySO = SceneObject::create("Rigidbody");
+HCharacterController charController = rigidbodySO->addComponent<CCharacterController>();
+~~~~~~~~~~~~~
+
+# Shape
+Similar to a rigidbody, the controller requires a shape to represent its surface. This shape is always a capsule, and you can control the size and orientation of it using the following methods:
+ - @ref bs::CCharacterController::setHeight "CCharacterController::setHeight()" - Sets the length of the line going along the center of the capsule.
+ - @ref bs::CCharacterController::setRadius "CCharacterController::setRadius()" - Sets the distance that determines how far away is the capsule's surface from its center line.
+ - @ref bs::CCharacterController::setUp "CCharacterController::setUp()" - Sets the direction of the center line. 
+ 
+When setting the capsule shape, make sure it covers your character model. But without making it too large so there isn't a lot of empty space in order to prevent unrealistic collisions in which the capsule shape collides with an object, but the visible model doesn't.
+ 
+~~~~~~~~~~~~~{.cpp}
+// Make a capsule pointing straight up, with a total height of 1.8 units (e.g. meters) and width/depth of 0.8 units
+charController->setHeight(1.0f);
+charController->setRadius(0.4f);
+charController->setUp(Vector3::UNIT_Y);
+~~~~~~~~~~~~~
+
+# Movement
+Similar to a rigidbody, when needing to move the controller you should use a specialized @ref bs::CCharacterController::move "CCharacterController::move()" method instead of the movement methods available on the scene object. Unlike with **Rigidbody**, this *move()* method takes as a parameter a displacement determining how much to move from the current position, unlike **Rigidbody** whose *move()* method takes absolute coordinates.
+
+~~~~~~~~~~~~~{.cpp}
+// Move 1 unit forward for every frame while W key is pressed
+if(gInput().isButtonHeld(BC_W))
+	charController->move(Vector3(0, 0, 1.0f));
+~~~~~~~~~~~~~
+
+**CCharacterController::move()** will perform the movement immediately, unlike most other physics objects which only move every physics "tick". This also means any collisions can be reported immediately, which is done by the return value of **CCharacterController::move()**. The return value is of type @ref bs::CharacterCollisionFlags "CharacterCollisionFlags" and can be used to tell if the controller collided with anything, and if it has, whether it was on its sides, its top or its bottom (or a combination of these). 
+
+This is similar to collision events reported by colliders and rigidbodies, but as the controller move is executely immediately its collision is also reported right away, meaning you can respond to the event with no delay so there is less input latency (which is important for objects controlled directly by the player).
+
+Unlike with **Rigidbody** rotation must be handled through the scene object. Such rotation will not properly physically interact with the environment.
+
+# Slopes
+Character controller has the ability to limit what is the maximum slope it can be moved on. This is useful to prevent the game character from climbing unrealistically steep slopes. Use @ref bs::CCharacterController::setSlopeLimit "CCharacterController::setSlopeLimit()" to set the maximum slope the controller is allowed to climb, in angles.
+
+~~~~~~~~~~~~~{.cpp}
+// Maximum slope of 45 degrees
+charController->setSlopeLimit(Degree(45));
+~~~~~~~~~~~~~
+
+Once the controller reaches the maximum slope the wanted behaviour can be:
+ - to stop the controller from moving any further
+ - to stop the controller and have it slide down
+
+This behaviour can be controlled by calling @ref bs::CCharacterController::setNonWalkableMode "CCharacterController::setNonWalkableMode()", which accepts a parameter of type @ref bs::CharacterNonWalkableMode "CharacterNonWalkableMode".
+
+~~~~~~~~~~~~~{.cpp}
+charController->setNonWalkableMode(CharacterNonWalkableMode::PreventAndSlide);
+~~~~~~~~~~~~~
+
+# Steps
+Controller can be also made to automatically climb on small steep obstacles, like stairs. Maximum height that the controller can step over is controlled by @ref bs::CCharacterController::setStepOffset "CCharacterController::setStepOffset()".
+
+~~~~~~~~~~~~~{.cpp}
+// Step over anything 0.15 units (e.g. 15cm) in height
+charController->setStepOffset(0.15f);
+~~~~~~~~~~~~~
+
+# Events
+Similar to colliders, character controllers also report events when they collide with other objects. Use @ref bs::CCharacterController::onColliderHit "CCharacterController::onColliderHit" to be notified when the controller hits a collider.
+
+The value reported is @ref bs::ControllerColliderCollision "ControllerColliderCollision" which contains the position, normal and motion of a single contact point, as well as the reference to the collider that was hit.
+
+~~~~~~~~~~~~~{.cpp}
+auto colliderHit = [](const ControllerColliderCollision& data)
+{
+	HCollider hitCollider = data.collider;
+	String hitSceneObjectName = hitCollider->SO()->getName();
+	
+	Vector3 contactPoint = data.position;
+	gDebug().logDebug("Hit " + hitSceneObjectName + " at point " + toString(contactPoint));
+};
+
+charController->onColliderHit.connect(colliderHit);
+~~~~~~~~~~~~~
+
+You can also receive events when the controller hits another controller by subscribing to @ref bs::CCharacterController::onControllerHit "CCharacterController::onControllerHit". 
+
+The value reported is @ref bs::ControllerControllerCollision "ControllerControllerCollision" which contains the position, normal and motion of a single contact point, as well as the reference to the other controller that was hit.
+
+~~~~~~~~~~~~~{.cpp}
+auto controllerHit = [](const ControllerControllerCollision& data)
+{
+	HCharacterController otherController = data.controller;
+	String otherSceneObjectName = otherController->SO()->getName();
+	
+	Vector3 contactPoint = data.position;
+	gDebug().logDebug("Hit " + otherSceneObjectName + " at point " + toString(contactPoint));
+};
+
+collider->onControllerHit.connect(controllerHit);
+~~~~~~~~~~~~~

+ 93 - 1
Documentation/Manuals/Native/User/physicalMaterial.md

@@ -1 +1,93 @@
-Mention collider contact offset/rest offset
+Physics material						{#physicsMaterial}
+===============
+
+Physics material is a type of object that can be applied to a **Collider** to control the physical properties of its surface. In particular it can be used to control friction coefficients that determine how much damping is there when two objects are touching and moving laterally. As well as a restitution coefficient that determines how ellastic are collisions between two objects.
+
+It is represented by @ref bs::PhysicsMaterial "PhysicsMaterial" and created by calling @ref bs::PhysicsMaterial::create "PhysicsMaterial::create()". It is a resource, and as such can be saved and loaded as described in the Resource manual.
+
+~~~~~~~~~~~~~{.cpp}
+// Create physics material with default properties
+HPhysicsMaterial material = PhysicsMaterial::create();
+~~~~~~~~~~~~~
+
+Once created it can be applied to a collider by calling @ref bs::CCollider::setMaterial "CCollider::setMaterial()".
+
+~~~~~~~~~~~~~{.cpp}
+HSceneObject colliderSO = SceneObject::create("Collider");
+HBoxCollider collider = colliderSO->addComponent<CBoxCollider>();
+
+collider->setMaterial(material);
+~~~~~~~~~~~~~
+
+# Friction coefficients
+Friction coefficients determine how much damping to the object's movement will occurr when objects are moving laterally to each other. Each object involved in friction can have its own physics material, and friction coefficients from them all will be accounted for.
+
+There are two types of friction coefficients:
+ - Static
+ - Dynamic
+ 
+## Static friction
+Static friction coefficient determines how hard is to get an object moving from a stand-still, if it is touching another object. Use @ref bs::PhysicsMaterial::setStaticFriction "PhysicsMaterial::setStaticFriction()" to set the coefficient.
+
+~~~~~~~~~~~~~{.cpp}
+// No static friction (e.g. ice)
+material->setStaticFriction(0);
+
+// A little bit of static friction (e.g. wooden floor)
+material->setStaticFriction(1);
+~~~~~~~~~~~~~
+
+## Dynamic friction
+Dynamic friction coefficient determines how much will a moving object be slowed down, when it is touching another object. Use @ref bs::PhysicsMaterial::setDynamicFriction "PhysicsMaterial::setDynamicFriction()" to set the coefficient.
+
+~~~~~~~~~~~~~{.cpp}
+// No dynamic friction (e.g. ice)
+material->setDynamicFriction(0);
+
+// A little bit of dynamic friction (e.g. wooden floor)
+material->setDynamicFriction(1);
+~~~~~~~~~~~~~
+
+# Restitution
+Resitution coefficient controls the elasticity of collisions between two objects (i.e. how "bouncy" they are). Coefficient of 0 means the collisions are non-elastic, and coefficient of 1 means the collisions are fully elastic. Use @ref bs::PhysicsMaterial::setRestitutionCoefficient "PhysicsMaterial::setRestitutionCoefficient()" to set the coefficient.
+
+~~~~~~~~~~~~~{.cpp}
+// Barely elastic collisions (e.g. metal ball)
+material->setRestitutionCoefficient(0.2f);
+
+// Very elastic collisions (e.g. a basketball)
+material->setRestitutionCoefficient(0.8f);
+~~~~~~~~~~~~~
+
+# Offsets
+Offsets are not part of the **PhysicsMaterial** interface, but are rather set directly on a **Collider**. Since they also refer to properties of the collider's surface, they're included in this manual.
+
+Offsets can be used to control the precision of the physics simulation when two objects are interacting. There are two types of offsets:
+ - Contact
+ - Rest
+ 
+You generally only need to tweak offsets if you notice inter-penetration or gaps during collisions and while objects are touching.
+ 
+## Contact offset
+Contact offset determines a "buffer" that is formed around the surface of a collider. Collider will start colliding with other objects when their surfaces (modified by contact offset) start touching.
+
+Generally you want to keep this at a low value, but not too low. When set to a high value the collisions may appear unrealistic as objects moving toward each other will start colliding before their actual collision bounds start touching.
+
+When set to a too low value then the opposite may happen and the objects might start colliding too late, after they are already visually inter-penetrating.
+
+It is generally a matter of tweaking the value to what looks best. Faster moving objects generally need larger contact offset values if inter-penetration is not acceptable. Smaller objects might need smaller contact offset values to avoid collision area much larger than the object.
+
+Use @ref bs::CCollider::setContactOffset "CCollider::setContactOffset()" to change the offset.
+ 
+~~~~~~~~~~~~~{.cpp}
+// Contact offset of 0.01 units (e.g. one centimeter)
+collider->setContactOffset(0.01f);
+~~~~~~~~~~~~~
+ 
+## Rest offset
+Rest offset is similar to contact offset, as it also defines a "buffer" formed around the surface. But it is only used when physical objects are statically touching each other (e.g. a stack of boxes). It can be used to tweak the collision bounds to make the objects appear perfectly touching. If your collision bounds perfectly match the visual representation of the object, no rest offset adjustment is necessary. The value can be negative to reduce the collision bounds.
+
+~~~~~~~~~~~~~{.cpp}
+// No rest offset
+collider->setRestOffset(0f);
+~~~~~~~~~~~~~

+ 2 - 1
Documentation/Manuals/Native/manuals.md

@@ -47,7 +47,8 @@ Manuals									{#manuals}
  - [Physics mesh import](@ref physicsMesh)
  - [Triggers](@ref triggers)
  - [Dynamic objects](@ref rigidbodies)
- - [Physical materials](@ref physicalMaterial)
+ - [Physics material](@ref physicsMaterial)
+ - [Character controller](@ref characterController)
  
 # Developer guides