בקר נגן פלנטרי מבוסס גוף קשיח לאחדות

בעת יצירת בקר נגן, כוח המשיכה מופעל בדרך כלל רק בכיוון אחד, שהוא למטה.

אבל מה לגבי כוח הכבידה עם נקודה מרכזית? זוהי עבודה עבור ההולך הפלנטרי.

הליכון פלנטרי הוא סוג של בקר המאפשר לשחקן ללכת על עצם כדורי (בדיוק כמו כוכבי הלכת), כאשר מרכז הכובד נמצא במרכז הכדור.

שלבים

להלן השלבים להכנת הליכון פלנטרי קשיח, עם נקודת כבידה מרכזית ב Unity:

  • פתח את הסצנה עם הרמה המעוגלת שלך (במקרה שלי יש לי דגם כוכב הלכת מותאם אישית ו-Skybox מותאם אישית בסצנה)

  • צור סקריפט חדש, קרא לו "SC_RigidbodyWalker" והדבק בתוכו את הקוד למטה:

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;
    }
}
  • צור סקריפט חדש, קרא לו "SC_PlanetGravity" והדבק בתוכו את הקוד למטה:

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);
        }
    }
}
  • צור GameObject חדש וקרא לו "Player"
  • צור קפסולה חדשה, הזז אותה בתוך האובייקט "Player" ושנה את מיקומה ל- (0, 1, 0)
  • הסר את רכיב Capsule Collider מהקפסולה
  • הזז את המצלמה הראשית בתוך האובייקט "Player" ושנה את מיקומה ל- (0, 1.64, 0)
  • צרף את הסקריפט SC_RigidbodyWalker לאובייקט "Player" (תבחין שהוא יוסיף רכיבים נוספים כגון Rigidbody ו-Capsule Collider).
  • שנה את גובה מאיץ הקפסולות ל-2 ואת המרכז ל-(0, 1, 0)
  • הקצה את המצלמה הראשית למשתנה מצלמת שחקן ב-SC_RigidbodyWalker
  • לבסוף, צרף את הסקריפט SC_PlanetGravity לאובייקט "Player" והקצה את מודל הפלנטה שלך למשתנה Planet

לחץ על הפעל וצפה בנגן מיושר אל פני השטח של כדור הארץ:

Sharp Coder נגן וידאו