Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mimic.UKCC Initial Implementation #45

Open
Dreaming381 opened this issue Jul 3, 2024 · 0 comments
Open

Mimic.UKCC Initial Implementation #45

Dreaming381 opened this issue Jul 3, 2024 · 0 comments
Labels
open to contributors Want to contribute? This task is available. very difficult This task is for the hard-core only

Comments

@Dreaming381
Copy link
Owner

Mimic.UKCC

Unity’s Kinematic Character Controller package is well-liked by the community.
However, its dependence on Unity Physics means that projects which use it also
inherit the many problems of Unity Physics. We want a character controller
without the side-effects.

Task is Prerequisite For

  • Newcomers
  • Game Jams
  • Community

Base Requirements

Implement a Psyshock-based kinematic character controller solution in Mimic that
provides feature-parity and feel-parity with Unity’s Kinematic Character
Controller package while supporting Psyshock’s multiple code-driven
CollisionLayer design philosophy.

The solution should not use IAspect, since those are anticipated to be going
away. And the solution should also not rely on a single CollisionLayer for all
spatial queries.

Assume that this will not be the recommended solution for massive hordes of
characters in a top-down RTS or tower defense, as a lighter-weight custom
solution would be preferred in such scenarios.

It is not the responsibility of this solution to apply forces onto external
objects. It only needs to provide a means to record such forces so that user
code may apply them.

QVVS Transforms must be supported. Unity Transforms support via
Latios.Transforms.Abstract is not required. The justification here is that
most if not all people using Unity Transforms are doing so because they need
Unity Physics for compatibility with other assets they are using.

The solution does not need to follow the designs outlined below. They are only
provided as a possible direction. Additionally, the name does not need to be
UKCC. That too is only a suggestion.

Solving the IAspect Problem

IAspect allows for bundling multiple components into a single abstracted type
with an API. Without this bundling, we still need a way to provide an abstract
API, and make such an API as simple as possible to use.

This means we want to reduce the amount of component types involved as much as
possible. One way to do this would be to combine all the IComponentData types
into a single IComponentData struct. The KinematicCharacterProperties,
KinematicCharacterBody, StoredKinematicCharacterData, and the Collider
(possibly a specific collider type like a CapsuleCollider) would all be fields
in a single KinematicCharacterController component.

Transforms will still be separate, but this will not be any surprise for a user.

The three dynamic buffers KinematicCharacterHit,
StatefulKinematicCharacterHit, and KinematicVelocityProjectionHit are not
explicitly needed outside of the controller movement update and could instead be
replaced with temporary buffers. The user could then copy these temporary
buffers into dynamic buffers or other data structures if necessary. The last
dynamic buffer KinematicCharacterDeferredImpulse is probably better stored in
a NativeStream. This all could be added to the
KinematicCharacterUpdateContext.

With all of this established, it now becomes true that the single
KinematicCharacterController component can now replace the
KinematicCharacterAspect.

Won’t Combining Everything Hurt Performance?

For the use cases this is targeting, not really. The controller update is going
to use a large amount of the data in the component. And very few other systems
are going to interact with this data directly. We can probably guess at which
kinds of systems would actually need such interactions.

First, there’s stats and ability systems. What is interesting about these is
that they could potentially touch any data, which means the whole component is
fair game. We’d have no way of knowing in advance what the optimal way to split
it is, as that’s usually game-dependent, so it is probably better we just keep
it all together. Achievement systems generally follow the same thought process.
Lastly, there’s the animation system, which while perhaps a little more focused
in which data it needs from the character controller, will also be consuming
computation and memory resources for animation that dwarfs the cost of a
combined component for the character controller.

Solving the PhysicsWorld Problem

While IAspect was relatively simple to work through, the PhysicsWorld within
KinematicCharacterUpdateContext is much more challenging.

The character controller needs to differentiate between static environment,
kinematic platforms, dynamic rigid bodies, and other kinematic character
controllers. In Unity Physics, the PhysicsWorld encodes this information.
However, in Psyshock, it is up to the user to choose how this information is
encoded. There might be a single CollisionLayer that combines static
environment and kinematic platforms. Or there might be multiple
CollisionLayers that each have static colliders.

Most likely, the correct solution is to have a generic struct which does one of
the following:

  • Provides the CollisionLayers needed for each hit
  • Provides the CollisionLayers and indices in layer for each AABB overlap
  • Performs the requested queries, doing any additional filtering on the
    results in-time

To further complicate matters, this is also the most performance-sensitive part
of the whole solution. That is because Unity’s implementation performs quite a
few spatial queries on the PhysicsWorld. These queries are all local around
the character, but Unity’s implementation scans the whole world with every
query. As an optimization, it may be possible to keep a cache of nearby objects
and subcolliders (important for large terrains or mesh landscapes) using an
initial FindObjects (or maybe even a FindPairs pre-pass for all character
controllers?). If any query’s AABB fits within the cached AABB search area, it
can simply do narrow-phase tests on the cache.

Finding a solution that has both good performance and an intuitive API will
prove challenging.

Collaboration

It may be determined during development of this feature that new APIs are
required in Psyshock. It is perfectly acceptable and encouraged to request these
APIs.

@Dreaming381 Dreaming381 added open to contributors Want to contribute? This task is available. very difficult This task is for the hard-core only labels Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open to contributors Want to contribute? This task is available. very difficult This task is for the hard-core only
Projects
None yet
Development

No branches or pull requests

1 participant