في هذه السلسلة من الدروس النعليمية سنتعلم سويا طريقة أنشاء " terrain " في لعبتنا مع التحكم الكامل في التضاريس الخاصة بهذا " terrain "، حيث سوف نتحكم عبر السكربت في الأرتفاعات والإنخفاضات، أي سنحدد الجبال والتلال وشكلها، وكذلك المنخفضات التي تصلح لتكون بحيرات مياه، وذلك عبر بعض من الأسطر البرمجية.
وبالطبع في البداية دعونا نبدأ في أنشاء مشروع جديد على برنامج يونتي 3 دي.
الفكرة العامة في أنشاء تلك التضاريس هي ستكون عبر أستخدام دالة الأختيار العشوائي، أو ما يعرف تحديدا بدالة " noise functions " فهي دالة تنشيء قيم عشوائية عبر مجموعة من العمليات الحسابية المعقدة، وهنا في هذة السلسلة التعليمية لم نقوم بشرح فكرة عمل مثل هذه الدوال بل سنقوم بشرح التطبيقات العملية لطريقة أستخدام تلك الدوال داخل اليونتي.
وهنا في درسنا هذا سوف تكون القيم العشوائية الناتجة من هذه الداله هي المتغير الذي سوف نستخدمه في تحديد أماكن المرتفعات والمنخفضات.
هناك بالطبع العديد من الدوال التي تقوم بمثل هذه الوظائف ولكننا هنا في يونتي توفر لنا دالة " Perlin Noise " وهي دالة رائعة يمكننا الأعتماد عليها للحصول على أفضل النتائج، وهي موضوع تلك السلسلة من الدروس.
ويمكن شرح دالة " PerlinNoise " بشكل مبسط وسريع على أنها دالة من النوع " float" وهي ترجع لنا قيمتان عشوائيتان من النوع " float "، أي أنها دالة ثنائية الأبعاد " 2D "، ولكن هي تستخدم في الثري دي أيضا، حيث يمكن أستخدامها عبر تحديد الأرتفاعات والانخفاضات، وهي رغم كنها دالة ترجع قيم عشوائية، إلى أنها ليست عشوائية تماما حيث هي ترجع قيم أشبه بالموجات، أي ترتفع وتنخفض بشكل شبة منتظم وفقا للمدخلات، لذلك هي جيدة جده في الأستخدام في عمل خريطة لللعبة بشكل عشوائي، تتغير في كل مرة يلعب فيها اللاعب من جديد، الأمر الذي يعطي التنوع وعدم الملل.
public static float PerlinNoise(float x, float y);
وهي ترجع لنا قيم تتراوح قيمتها بين ( 0.0 ، 1.0 )، وللمزيد من الأمثلة على هذة الدالة يمكنك هذا عبر هذه الصفحة " PerlinNoise "
فالنبدأ بأنشاء سكربت جديد بأسم " GenerateTerrain " حيث سيقوم هذا السكربت بأحتساب القيم العشوائية التي نحتاجها لتحديد الأرتفاعات والإنخفاضات.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenerateTerrain : MonoBehaviour
{
public int heightScale = 5;
public float detailScaie = 5.0f;
void Start()
{
Mesh mesh =this.GetComponent<MeshFilter>().mesh;
Vector3 [] vertices = mesh.vertices;
for (int v = 0; v < vertices.Length; v++)
{
vertices[v].y = Mathf.PerlinNoise((vertices[v].x + this.transform.position.x) / detailScaie,
(vertices[v].z + this.transform.position.z) / detailScaie) * heightScale;
}
mesh.vertices=vertices;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
this.gameObject.AddComponent<MeshCollider>();
}
// Update is called once per frame
void Update()
{
}
}

0 تعليقات