How to have Rigidbody based player movement with support for external forces being applied to it?

I’ve been wracking my mind for this for a while now, I’m making a game with first person physics based movement, I’m trying to make knockback so I can make it so the enemies can knock the players back, however I can’t find a way to have both working movement and knockback, its crucial for my game to work because I’m also creating a mechanic where you can fling yourself toward walls, but I can’t find a way to make this work.

This generally requires a component that manages external forces and applies them alongside input all at once. This can be the character controller component itself, or some generalised component, namely if you have other objects that should be influenced as well. I’ve done this by external forces registering themselves to said component, and un-registering themselves as required.

Then you can run down all the registered influences, get the direction they want the thing to move in (including input), add them all together, and you have your combined direction.

Check out what this guy pulled off:

https://www.youtube.com/watch?v=qdskE8PJy6Q

It’s third person but put the camera in the guy’s head, bam, you’re done.

Pretty spiffy.

With a character controller you need to add a velocity vector to its position every frame and make the velocity vector public so that other external scripts can add to it.

Something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveIt : MonoBehaviour
{
    CharacterController cc;

    public Vector3 playerVelocity;    // other scripts can add to this velocity

    void Start()
    {
        cc=GetComponent<CharacterController>();
    }

    void Update()
    {
        Vector3 moveDirection=new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
        playerVelocity+=moveDirection;
        if (cc.isGrounded==false)
            playerVelocity.y-=9.8f;    // gravity

        playerVelocity*=0.8f;   // basic friction
        cc.Move(playerVelocity*Time.deltaTime);
    }
}