Experimental Character Controller package now available (formerly known as "Rival")

Hello everyone!

Welcome to the Character Controller discussion thread. You can use this thread to ask for help, share feedback, and have discussions about the Character Controller package.

For users looking to quickly jump into building their game, the Character Controller experimental package is now available and compatible with the pre-release of ECS for Unity, including documentation and implementation samples. This package provides an efficient and highly-customizable character controller solution for ECS for Unity and can be used with the Unity Physics or Havok Physics for Unity packages. It was designed with netcode prediction in mind, ensuring that the character state is small and that users have full control over the character update.

As a reminder: Experimental releases are not supported or recommended for production but provide early access for those who want to try out the Character Controller package in their projects. This also helps us make progress on development through everyone’s feedback.

Distribution changes
This package was previously distributed on the Asset Store, under the name “Rival - DOTS Character Controller”, and is now being distributed via the package manager in the editor, as we continue to consolidate workflows around ECS for Unity. The asset store listing will also be deprecated as part of this consolidation.

Resources
The following resources are available for the package:

Requirements
The experimental Character Controller package is compatible with Unity 2022.2.6f1 and above, and also depends on the pre-release of com.unity.entities and com.unity.physics packages.

Getting started
Follow these steps to import the package into your project:

  • Open the Package Manager window (be sure to use Unity 2022.2.6f1 and above)
  • Click the “+” button at the top left
  • Select “Add package by name…”
  • Enter com.unity.charactercontroller
  • click “Add”. This will import the package into your project

At this point, if this is the first package depending on Entities that you have imported into your project, you may see an “error CS0006” in the console. If this happens, you should restart Unity before you continue.

Once the character package is imported, navigate to the “Samples” tab of the Character Controller package’s page. Here, you can download the “Standard Characters” sample, which contains pre-made first-person and third-person character controllers that can serve as a starting point for you to create your own character controllers.

For more information, consult the Documentation.

Feedback
Please share your feedback in this thread as we’re always interested in discussing potential improvements!

How to report bugs
Ideally, we’d like any bugs reported through the built-in bug reporter tool, as that will automatically provide us with some relevant context. Once you have submitted a bug report through the bug reporter, please feel free to start a discussion about it in this thread.

35 Likes

It is amazing to see, how contributions of our community member fructuating.

I haven’t had an opportunity to look into packages as of yet. But it I believe, it is great move from Unity, to get community assistance and support in DOTS expanding domain.

1 Like

Any upgrade document for rival user ?

2 Likes

Aside from a namespace change, the code hasn’t really changed compared to the latest version on the store.

Simply delete the old “Rival” folder (imported from the store), import the new package, and convert your “using Rival;” to “using Unity.CharacterController;”. Existing characters built from the store version’s Standard Characters will still work

6 Likes

I have a question related to the design (still very new to ecs). The example characters appear to be based more around trying to mimic a Object-oriented pattern than a Data-Drivin one which seems a little counter intuitive to the reasons why I am trying to learn Dots/Ecs. I would assume that instead of hardcoding a state system like in the platformer example there would be seperate systems for things like swiming,climbing, ect. Is there a specific reason for not being desined like this?

Ex: Is overhead of the seperate systems not worth it or something alike?

There are pros and cons to every approach:

  • Structural changes state machine: the state machine can be split into many jobs by adding/removing state components to the character entity. However, structural changes like this are known to be relatively expensive, so if your states change often, this cost may very well outweigh the benefits

  • Enabled components state machine: instead of adding/removing state components to the character entity, we could just have every state component already on the character, and enable/disable them. This has a much lighter cost than structural changes, but comes with other downsides such as adding a certain constant job overhead and reducing the amount of entities that can fit in the chunk (see the “When IEnableableComponent is not the answer” section of the DOTS Best Practices guide)

  • Switch statement state machine: this approach sacrifices some execution efficiency due to relying on switch statements and operating on all the data across all states, but comes with a few advantages that can sometimes make it preferable to the other approaches:

  • no structural change costs or main thread sync points.

  • no constant jobs overhead added due to jobs constantly iterating on disabled components in chunks.

  • only pay the scheduling costs of one job instead of one job per function per character state. In this case, the character has 12 states of 6 functions each, which would total 72 jobsÂą when implemented using the other approaches.

  • 72 jobs is already potentially starting to enter “too many jobs for just one thing” territory, but in netcode projects where the # of jobs scheduled per frame can get multiplied by ~10 due to rollback/prediction, that would give us up to 720 jobs to schedule just to handle our character state machine. At this point, the scheduling cost alone will probably take a non-negligible % of your frame budget, and if using enabled components, the overhead of 720 jobs iterating over disabled components constantly is likely to be meaningful.

  • There will most likely be a threshold where one of the “many jobs” approaches will outperform this “switch” approach, but that would most likely only be if your game has many thousands active characters in the scene (or maybe even tens of thousands?). Under that threshold, especially for a typical game with 200 or less active characters, the switch approach would probably be the best-performing approach. Basically, if the number of jobs seems disproportionally high compared to the number of entities being worked on (700 jobs for 100 characters), that’s a sign that something like the switch approach might be a better choice.

  • Function pointers state machine: more or less the same pros and cons as the switch state machine. I haven’t compared their performance yet but it would be interesting to see

The best approach will heavily depend on your precise use case, and should probably be decided by profiling each approach.


Notes

  1. While a direct equivalent implementation would require 72 jobs, there’s always the possibility of thinking of alternatives that do not exactly fit the “state machine” model, where less jobs are required. It’s difficult to discuss this in a general way without looking at one very specific problem though
9 Likes

Thank you very much for the informative response!

8862294--1209336--upload_2023-3-8_15-54-20.png

Tried getting it on 2022.2.8f1 and 2023.1.0b7, but doesn’t seem to work

1 Like

For me it worked when adding the package through git url.

Works for 2022.2.8f1. I like having one folder less in my Assets. Had to fix a few lines of code because I adapted the thirdperson sample.

I’ve seen some reports of people not being able to find the package on 2022.2.8f1, and some who are able to find it. I’ll try to investigate this. I just went and tried it on 2022.2.8f1 and I was able to find it, but there might be something I’m missing

Hi Philsa,

I’m been trying to learn the package and I’m trying to understand 2 parts, the variable vs fixed updating and the update contexts and I am hoping you could give some insight to these topics so that I may get better at using the character controller!

  • What more than rotation of the character should be put in the variable update?
  • What is the point of update contexts? Why not just update the character’s values in the system?

I’d say it would be just for rotation in the majority of cases, but I avoided naming it the “Rotation Update” just in case some people see other uses for it (like handling some gameplay or animation-related values for example)

Some people might also choose to update rotation as part of the physics update in certain cases (see the “Velocity and rotation update frequencies” section of the documentation for additional details)

Contexts are for storing any data that isn’t a component/buffer on the character entity, but that the character might need. An example of this is the “friction surfaces” in the tutorial. Here we need a component lookup for the “friction surface” component, so that when we hit another entity, we can see if it has that component

Since the character aspect can be used by multiple different systems/jobs, contexts provide a centralized way to “build” that data for your character aspect, instead of having to manually build it in all jobs that use the aspect

What was the URL you used?

I think the CharacterController should have it’s own forum section now that it’s official.

Actual question:

KinematicCharacterProperties.SetCollisionDetectionActive(false);
ecb.SetComponentEnabled<KinematicCharacterBody>(entity, false);

This freezes the CC in place and disables any movement. But I’m trying to completely disable the CC in favor of the ragdoll. The catch: I need to be able to reenable the CC, so completely removing all the components is not an option. Think Skyrims active ragdolls.

The same you used, and @philsa-unity shared with us.

From your screenshot it looks like you used the named package, I went for the git url for the package (with the dropdown). Not sure if that would help?

With these two lines, are you seeing anything else that would need to be disabled? I would imagine the physics shape/body are still active, so you might also have to set the physics shape’s collision response to None. Although by default it is set to be a trigger so it shouldn’t interfere with ragdoll physics

EDIT: did you make sure to write back the changes to the KinematicCharacterProperties component, after calling “SetCollisionDetectionActive(false)” on it? I think maybe a utility function modifying the properties by ref would make it clearer that this modifies the component’s data and that it must be written back

Could alternatively remove PhysicsWorldIndex from the CC entity

Removing PhysicsWorldIndex worked fine, thank you. Even tho the PhysicsShape is set to Raise Trigger Events (by default), SetCollisionDetection is set to false and the KinematicCharacterBody is disabled the player can still collide with the invisible CC of the ragdolling npc (and hit it with attacks). I honestly don’t know if doing it this way is a good approach to ragdolling characters/characters getting into vehicles etc. Maybe a good topic for the CC manual.

I see, this might be a bug. I’ll look into it

1 Like