Starrkörperbasierter Planetary Player Controller für Unity

Beim Erstellen eines Spieler-Controllers ​​wird die Schwerkraft normalerweise nur in einer Richtung angewendet, nämlich nach unten.

Aber wie sieht es mit der Schwerkraft mit einem zentralen Punkt aus? Dies ist eine Aufgabe für den Planetenwanderer.

Ein Planetenläufer ist eine Art Controller, der es dem Spieler ermöglicht, auf einem kugelförmigen Objekt (genau wie die Planeten) zu laufen, wobei der Schwerpunkt im Zentrum der Kugel liegt.

Schritte

Nachfolgend finden Sie die Schritte zum Bau eines planetarischen Starrkörperläufers mit einem zentralen Schwerpunkt in Unity:

  • Öffnen Sie die Szene mit Ihrer kreisförmigen Wasserwaage (in meinem Fall habe ich ein maßgeschneidertes Planetenmodell und eine benutzerdefinierte Skybox in der Szene)

  • Erstellen ein neues Skript, nennen Sie es "SC_RigidbodyWalker" und fügen Sie den folgenden Code darin ein:

SC_RigidbodyWalker.cs

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

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]

public class SC_RigidbodyWalker : MonoBehaviour
{
    public float speed = 5.0f;
    public bool canJump = true;
    public float jumpHeight = 2.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 60.0f;

    bool grounded = false;
    Rigidbody r;
    Vector2 rotation = Vector2.zero;
    float maxVelocityChange = 10.0f;

    void Awake()
    {
        r = GetComponent<Rigidbody>();
        r.freezeRotation = true;
        r.useGravity = false;
        r.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
        rotation.y = transform.eulerAngles.y;

        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    void Update()
    {
        // Player and Camera rotation
        rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
        rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
        playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0);
        Quaternion localRotation = Quaternion.Euler(0f, Input.GetAxis("Mouse X") * lookSpeed, 0f);
        transform.rotation = transform.rotation * localRotation;
    }

    void FixedUpdate()
    {
        if (grounded)
        {
            // Calculate how fast we should be moving
            Vector3 forwardDir = Vector3.Cross(transform.up, -playerCamera.transform.right).normalized;
            Vector3 rightDir = Vector3.Cross(transform.up, playerCamera.transform.forward).normalized;
            Vector3 targetVelocity = (forwardDir * Input.GetAxis("Vertical") + rightDir * Input.GetAxis("Horizontal")) * speed;

            Vector3 velocity = transform.InverseTransformDirection(r.velocity);
            velocity.y = 0;
            velocity = transform.TransformDirection(velocity);
            Vector3 velocityChange = transform.InverseTransformDirection(targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0;
            velocityChange = transform.TransformDirection(velocityChange);

            r.AddForce(velocityChange, ForceMode.VelocityChange);

            if (Input.GetButton("Jump") && canJump)
            {
               r.AddForce(transform.up * jumpHeight, ForceMode.VelocityChange);
            }
        }

        grounded = false;
    }

    void OnCollisionStay()
    {
        grounded = true;
    }
}
  • Erstellen ein neues Skript, nennen Sie es "SC_PlanetGravity" und fügen Sie den folgenden Code darin ein:

SC_PlanetGravity.cs

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

public class SC_PlanetGravity : MonoBehaviour
{
    public Transform planet;
    public bool alignToPlanet = true;

    float gravityConstant = 9.8f;
    Rigidbody r;

    void Start()
    {
        r = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        Vector3 toCenter = planet.position - transform.position;
        toCenter.Normalize();

        r.AddForce(toCenter * gravityConstant, ForceMode.Acceleration);

        if (alignToPlanet)
        {
            Quaternion q = Quaternion.FromToRotation(transform.up, -toCenter);
            q = q * transform.rotation;
            transform.rotation = Quaternion.Slerp(transform.rotation, q, 1);
        }
    }
}
  • Erstellen Sie ein neues GameObject und nennen Sie es "Player"
  • Erstellen Sie eine neue Kapsel, verschieben Sie sie innerhalb des "Player"-Objekts und ändern Sie ihre Position in (0, 1, 0).
  • Entfernen Sie die Capsule Collider-Komponente aus der Capsule
  • Bewegen Sie die Hauptkamera in das Objekt "Player" und ändern Sie ihre Position in (0, 1,64, 0).
  • Hängen Sie das SC_RigidbodyWalker-Skript an das "Player"-Objekt an (Sie werden feststellen, dass dadurch zusätzliche Komponenten wie Rigidbody und Capsule Collider hinzugefügt werden).
  • Ändern Sie die Höhe des Capsule Colliders auf 2 und die Mitte auf (0, 1, 0).
  • Weisen Sie die Hauptkamera der Player-Kameravariable in SC_RigidbodyWalker zu
  • Zuletzt hängen das SC_PlanetGravity-Skript an das "Player"-Objekt an und weisen Ihr Planetenmodell der Planet-Variablen zu

Drücken Sie „Play“ und beobachten Sie, wie sich der Player an der Planetenoberfläche ausrichtet:

Sharp Coder Videoplayer

Empfohlene Artikel
Spielerbewegung in Einheit schaffen
So fügen Sie dem Character Controller in Unity Unterstützung für bewegliche Plattformen hinzu
RTS- und MOBA-Player-Controller für Unity
Hinzufügen von Double Jump-Unterstützung zu einem 2D-Platformer-Charakter-Controller in Unity
Flugzeugcontroller für Unity
Spieler-3D- und 2D-Wandsprung-Tutorial für Unity
3D-Wurm-Controller-Tutorial für Unity