وحدة التحكم الكوكبية القائمة على الجسم الصلب من أجل الوحدة

عند إنشاء وحدة تحكم المشغل، عادةً ما يتم تطبيق الجاذبية في اتجاه واحد فقط، وهو الأسفل.

ولكن ماذا عن الجاذبية عند نقطة مركزية؟ هذه وظيفة للمشاة الكوكبية.

جهاز المشي الكوكبي هو نوع من وحدات التحكم التي تسمح للاعب بالمشي على جسم كروي (تمامًا مثل الكواكب)، مع وجود مركز الجاذبية في مركز الكرة.

خطوات

فيما يلي خطوات صنع مشاية كوكبية ذات جسم صلب، مع نقطة جاذبية مركزية في 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)
  • قم بإزالة مكون مصادم الكبسولة من الكبسولة
  • قم بتحريك الكاميرا الرئيسية داخل الكائن "Player" وقم بتغيير موضعه إلى (0، 1.64، 0)
  • قم بإرفاق البرنامج النصي SC_RigidbodyWalker بالكائن "Player" (ستلاحظ أنه سيضيف مكونات إضافية مثل Rigidbody وCapsule Collider).
  • تغيير ارتفاع مصادم الكبسولة إلى 2 والمركز إلى (0، 1، 0)
  • قم بتعيين الكاميرا الرئيسية لمتغير كاميرا المشغل في SC_RigidbodyWalker
  • أخيرًا، أرفق البرنامج النصي SC_PlanetGravity بالكائن "Player" وقم بتعيين نموذج الكوكب الخاص بك إلى متغير Planet

اضغط على تشغيل ولاحظ محاذاة اللاعب لسطح الكوكب:

Sharp Coder مشغل فديوهات

المقالات المقترحة
إنشاء حركة اللاعب في الوحدة
وحدة التحكم في الشخصية كيفية إضافة القدرة على دفع الأجسام الصلبة في الوحدة
الوحدة كيفية جعل عناصر التحكم باللمس المحمول
وحدة تحكم السيارة للوحدة
تحكم طائرات الهليكوبتر للوحدة
وحدة تحكم الطائرة للوحدة
تنفيذ نظام الباركور في الوحدة