3D sandbox game development log 3 - famine style battle third person controller

journal

  I haven't written a log for many days. In fact, I've done a lot of things recently, but I've been too lazy to record, so I'll make up the previous log before continuing development these two days
 Well, it's worth mentioning that we have found several suitable resources recently. The days are really looking forward to more and more^_^

  For the first time, we made an exploration style third person perspective, but sandbox games are more about fighting, so we need to develop it
 A general state controller, the previous one can be used in some specific occasions. In terms of fighting, I think famine gives me the most comfortable feeling, so I
 Decided to imitate the character manipulation of famine.

We still supplement the previous two scripts, LocomotionController and ViewController

Character movement

The fact is that if you want to make the character control feel real, the left and right buttons should rotate the character, whether lerp or momentarily adjust the rotation; If you want to make the operation of the character simple, you can go to "walk", then the left and right buttons should directly turn the character to the corresponding angle and move in the corresponding direction. If I press and hold the left button, I want the character to move to the left rather than turn to the left, which is very important
It takes two steps to make the character "move to the left". The first is to turn to the "left", and the second is to go to the "left". The "left" here refers to the left in the viewing direction of the camera, so we should obtain the front, rear, left and right (vieweuler angle, viewDirForward, viewDirRight) in the viewing direction of the camera. Note that the first part turns to the left instead of to the left. Our camera will not rotate with the character. It is controlled separately, so the "left" of the camera is fixed and will not change due to the rotation of the character
But you may also notice that if we do, our characters will not be able to move in any direction of 360 degrees. This is indeed the case. Generally, in this case, we will declare two variables forward and right, which are combined into eight directions (0, - 1, 1) (9 if we count still), and finally form the character's displacement together with the viewing angle direction and speed

void FixedUpdate()
{
    Vector3 viewEulerAngle = viewController.thirdPersonCam.transform.eulerAngles;
    Vector3 viewDirForward = viewController.thirdPersonCam.transform.forward;
    Vector3 viewDirRight = viewController.thirdPersonCam.transform.right;
    Vector3 lastPos = transform.position;
    
    float forward = 0, right = 0;
    if(Input.GetKey(KeyCode.A))
    {
        viewController.model.rotation = Quaternion.Euler(0, viewEulerAngle.y - 90, 0);
        right -= 1;
    }
    if(Input.GetKey(KeyCode.D))
    {
        viewController.model.rotation = Quaternion.Euler(0, viewEulerAngle.y + 90, 0);
        right += 1;
    }
    if(Input.GetKey(KeyCode.W))
    {
        viewController.model.rotation = Quaternion.Euler(0, viewEulerAngle.y, 0);
        forward += 1;
    }            
    if(Input.GetKey(KeyCode.S))
    {
        viewController.model.rotation = Quaternion.Euler(0, viewEulerAngle.y + 180, 0);
        forward -= 1;
    }
    Vector3 moveDir = viewDirForward * forward + viewDirRight * right;
    moveDir.y = 0;
    moveDir.Normalize();
    transform.position += moveDir * Time.deltaTime * runSpeed;
}

There will also be an old question: should I take the camera as a sub object of a character or a separate object?
As mentioned in the first article, it is difficult to control the camera to follow the character alone, and it is easy to produce bug s, so we should make the camera as a sub object as much as possible; But our requirement is that the camera can follow the character's movement, but not follow the character's rotation. Is that possible? In fact, this problem is often not encountered after forming a good habit, because we generally do not mount the script directly on the model, but recreate an empty object, so we only need to "move" the empty object, and "rotate" the model, camera and model are sub objects of the empty object, which meets our requirements.

Third person perspective

In fact, the core problem of the perspective part has been solved. After taking the camera as a sub object, the perspective part does not need to deal with complex movement, but simply rotates the perspective. Because it is in accordance with the style of famine, the perspective rotates around the character, that is, RotateAround. Incidentally, the rotation model is also imitated according to the feeling of famine. Here, you can freely choose whether to rotate or the rotation angle.

void FixedUpdate()
{
    if(Input.GetKeyDown(KeyCode.Q))
    {
        thirdPersonCam.transform.RotateAround(model.position, Vector3.up, 45);
        model.Rotate(0, 45, 0);
    }
    if(Input.GetKeyDown(KeyCode.E))
    {
        thirdPersonCam.transform.RotateAround(model.position, Vector3.up, -45);
        model.Rotate(0, -45, 0);
    }
}

summary

The code looks very simple this time, but it's not. I played back and forth at least three times to reproduce this feeling. The seemingly unreasonable control and rotation mode produces a very smooth control effect. I will really learn a lot in the process of converting a seen effect into code.

design sketch

Tags: C# Unity Game Development Unity3d

Posted on Thu, 16 Sep 2021 22:54:03 -0400 by veronicabend