ترجمة هذه النصوص إلى اللغة العربية: بناء كاميرا Unity الشخصية الثالثة (الجزء الأول)
أرغب في إنشاء كاميرا شخص ثالث في Unity ، يتم تعمليها بمراجعة كاميرا شخص ثالث في لعبة "World of Warcraft" ، متطلبات العمل محددة كالتالي:
النقر الأيسر للفأرة: التحكم في دوران الكاميرا حول الشخصية، دون دوران الشخصية استعمل زر الماوس الأيمن: للتحكم في دوران الكاميرا حول الشخصية، حيث يتم دوران اتجاه الشخصية الأمامي (transform.forward في Unity) بالتالي، مع الحفاظ على اتجاه الشخصية العلوي. بعد تحويل الزر الأيسر للماوس، ادور مرة أخرى بالزر الأيمن، تتم ضبط اتجاه الشخصية أمامي على الفور وفقًا لتحويلة الزر الأيسر، ثم بناءً على تحويلة الزر الأيمن، يعادل هذا التصرف تحويلة الزر الأيمن مرتين. عجلة التمرير: التحكم في تكبير وتصغير الكاميرا الكاميرا لا يمكن أن تخترق أي جسم صلب بعد مرور الكاميرا من جسم صلب ، ستعود ببطء إلى المسافة الأصلية. إذا تصادفت الكاميرا بجسم ما، استخدم عجلة الماوس لتقريب الكاميرا، يجب على الكاميرا الاستجابة فورًا، وبعدها لن يحدث النقطة السادسة مرة أخرى. الكاميرا اصطدمت بالأرض أثناء الدوران، مما أدى إلى توقف دورانها حول الشخص بشكل رأسي، وتغيرت الآن لدوران حول نفسها بشكل رأسي، أما الدوران الأفقي فما زال حول الشخص.
هذا المطلب يمكن تقسيمه إلى جزأين: دوران الكاميرا، وصلابة الكاميرا. لبساطة الأمور، سنعمل أولاً على حل مشكلة دوران الكاميرا، وهي النقط الثلاث الأولى في المطلب.
عرض موقع الكاميرا
قبل حل مشكلة تشغيل الكاميرا بشكل رسمي، هناك مسألة أخرى يجب حلها: تمثيل موقع الكاميرا. ويمكن القيام بذلك بعدة طرق:
إحداثيات العالم الخاصة بالكاميرا موقع الكاميرا بالنسبة لإحداثيات الشخصية اتجاه ومسافة الكاميرا في نظام الإحداثيات الشخصي
نظرًا لأن الكاميرا في احتياجاتنا تتحول وفقًا لمواقع الشخصيات، فقد قمت هنا باستخدام الطريقة الثالثة، كما أن الكاميرا تستهدف الشخص دائمًا في التحكم، لذا الكاميرا تحتاج فقط لحفظ معلومات المسافة في داخلها.
تدوير الكاميرا
من خلال تفصيل سلوك دوران الكاميرا، يمكن تقسيمه إلى دوران يمينٍ ودوران يسار. سنقوم بإتمام هذين الدورانين خطوة بخطوة. أولاً، سأقوم بتعيين الكاميرا كجسم فرعي لشخصية، بحيث سيقوم الكاميرا تلقائيًا بتتبع بعض حركات الشخصية الأساسية.
يرجى تقديم نص مكتوب باللغة العربية.
ترجمة النص إلى اللغة العربية:
عند النظر فقط إلى دوران الزر الأيسر، الاحتياج بسيط جدًا: دوران الكاميرا، دون دوران الشخصية، هذا يعني وجود كاميرا تحرص على رصد الكائن المركزي من أي زاوية.
في Unity ، يمكنك الحصول على حالة النقر الأيسر للفأرة باستخدام البيان: Input.GetMouseButton(0)
(ملاحظة: في جميع الأماكن التي تشير إلى الشيفرة، نحن نستخدم C#). بوضوح، بالنسبة للزر الأيمن هو Input.GetMouseButton(1)
. يمكنك الحصول على موقع حركة المؤشر للفأرة (يمكن فهمه على أنه الانحراف في محوري الـX والـY بين الإطارين) بواسطة: Input.GetAxis("Mouse X"); Input.GetAxis("Mouse Y")
. لذا يمكننا أولاً الحصول على معلومات حركة المؤشر بعد النقر بالزر الأيسر للفأرة:
if (Input.GetMouseButton(0))
{
float x = Input.GetAxis("Mouse X");
float y = Input.GetAxis("Mouse Y");
}
الكود بسيط جداً، وهنا النقطة الحاسمة: كيفية التحكم في تدوير الكاميرا. لفهم التدوير، يلزم بعض المعرفة عن الأربعينيات (هناك العديد من المواد على الإنترنت، لذا لن أذكرها هنا). إحدى النقاط الهامة في الأربعينيات هي أنها يمكن بناء التدوير بسهولة، خاصة حول تدوير حول بعض الناقلات، بعد فهم الأربعينيات، لن تكون من الصعب تنفيذ تدوير الكاميرا حول الشخص.
ثانيًا، يجب الانتباه إلى أمر آخر، وهو أن محور دوران المتجهات الرباعية هو مجرد متجه، يبدأ من النقطة الصفر، إذا أردت أن تأخذ نقطة معينة O
في نظام الإحداثيات العالمي كنقطة انطلاق، واتجاه المتجه V
الذي يبدأ من تلك النقطة يكون محور الدوران، يجب عليك إجراء تحويل لنظام الإحداثيات، ببساطة، يجب تحويل النقطة التي ترغب في دورانها P
إلى نظام الإحداثيات الذي يبدأ من O
، ثم الدوران حسب V
، ثم العكس إلى النظام الإحداثيات العالمي. استنادًا إلى هذه العمليات، يمكن كتابة وظيفة عملية:
Vector3 MyRotate(Vector3 oldPosition, float angle, Vector3 axis, Vector3 axisPosition)
{
إنشاء الرباعي، حيث يكون محور الدوران الخط المعين، وهذا الدوران يتم في نظام الإحداثيات الخاص بالشخصية.
Quaternion rotation = Quaternion.AngleAxis(angle, axis);
هنا يتم تغيير نظام الإحداثيات، حيث يتم تحويل إحداثيات العالم للكاميرا إلى إحداثيات تحت نظام إحداثيات الشخصية.
Vector3 offset = oldPosition - axisPosition;
// حساب الدوران وتحويلها إلى نظام الإحداثيات العالمي
return axisPosition + (rotation * offset);
}
يمكن توفير رمز التحكم في دوران الكاميرا يمينًا ويسارًا عند تحريك الماوس يمينًا ويسارًا:
بما أنه هنا يتم تدوير الفيكتور الأمامي فقط دون تحويل نظام الإحداثيات، لذا يتم تعيين القيمة الرابعة كـVector3.zero
.
التحكم في الدوران العمودي والأفقي قد يكون أكثر صعوبة في الفهم قليلاً، لأن محور الدوران في هذه الحالة سيكون متغيرًا باستمرار (نفترض هنا أن الاتجاه "أعلى" للشخصية دائما محور Y إيجابي). من الجيد أن نلاحظ أن الكاميرا أيضًا تدور باستمرار، ويتوجب أن يكون مركز الرؤية موجهًا دائمًا نحو الشخصية، وبالتالي، اتجاه الكاميرا اليمين (right) هو المحور الذي نود الدوران حوله (قم بتصور اتجاه يمين الكاميرا كما لو كان يمين الشخصية)، بفهم من هذا القبيل، يصبح كود الدوران العمودي والأفقي بسيطًا جدًا:
يرجى تحريك النص إلى اليمين
قم بتحريك الماوس لليمين لتدور يمينًا، الأمر سيكون بسيطًا، كل ما عليك فعله هو ضبط اتجاه الشخصية أثناء الدوران يمينًا ويسارًا.
ترانسلت لها إلى اللغة العربية:
الجزء الخاص بتدوير لأعلى ولأسفل مشابه للجزء الخاص بالزر الأيسر.
يرجى تحويل هذه النصوص إلى اللغة العربية:
先左键,后右键### على الرغم من أنه يمكن تدوير الشخصية بزر الفأرة الأيسر والأيمن منفصلة، إلا أنه عند تدوير الشخصية أولا بالزر الأيسر، ثم القيام بعملية تشغيل بزر الأيمن، سيظهر مشكلة: اتجاه الشخصية واتجاه الكاميرا سيصبحان مختلفين! سينفصل بذلك اتجاه الكاميرا والشخصية، مما يجعل التشغيل الفعلي غريبًا للغاية. لذا علينا أن نضبط اتجاه الشخصية ليتماشى مع اتجاه الكاميرا عند تدويرها بزر الأيمن.
欧拉角万向锁
حتى الآن، تقريبا اكتملت عملية دوران الكاميرا، لكن هناك مشكلة واحدة يجب التركيز عليها: قفل زوايا الأويلر. لن ندخل في التفاصيل الآن، يمكن للأصدقاء المهتمين البحث بأنفسهم، بالنسبة لظروف الكاميرا هنا، عندما تدور الكاميرا لتكون في الاتجاه العلوي نحو الشخص، ستحدث تغيرات مفاجئة في زاوية الرؤية للكاميرا. هذا يحدث لأن عندما تصل الكاميرا إلى أعلى رأس الشخص أو أسفل قدميه، ستحدث تغيرات مفاجئة في اتجاه الكاميرا العلوي (لأن قيمة Y لاتجاه الكاميرا دائمًا يجب أن تكون أكبر من الصفر)، لذلك نحن بحاجة إلى تحديد نطاق الدوران العلوي والسفلي للكاميرا، لتجنب حدوث قفل زوايا الأويلر. العملية بسيطة جدًا، وهي تقييد زاوية الانحراف بين اتجاه الكاميرا الأمامي واتجاه الكاميرا العلوي للشخص:
if ((Vector3.Dot(transform.forward, transform.parent.up) >= -0.95F || y > 0) &&
(Vector3.Dot(transform.forward, transform.parent.up) <= 0.95F || y < 0))
الرمز الكامل
// rotate oldPosition around a axis starting at axisPosition
Vector3 MyRotate(Vector3 oldPosition, float angle, Vector3 axis, Vector3 axisPosition)
{
Quaternion rotation = Quaternion.AngleAxis(angle, axis);
Vector3 offset = oldPosition - axisPosition;
return axisPosition + (rotation * offset);
}
// rotate oldForward, player forward may change when use mouse RB
Vector3 RotateIt(Vector3 oldForward, Vector3 up, Vector3 right, Transform player)
{
Vector3 newForward = -oldForward;
// mouse LB RB rotate camera and character
if (Input.GetMouseButton(0) ^ Input.GetMouseButton(1))
{
float x = Input.GetAxis("Mouse X") * rotateSpeed;
float y = Input.GetAxis("Mouse Y") * rotateSpeed;
if (x != 0F)
{
newForward = MyRotate(newForward, x, up, Vector3.zero);
// mouse RB, character rotate together
if (Input.GetMouseButton(1))
{
player.forward = Vector3.Normalize(new Vector3(oldForward.x, 0,
oldForward.z));
}
}
if (y != 0F)
{
if ((Vector3.Dot(transform.forward, up) >= -0.95F || y > 0)
&& (Vector3.Dot(transform.forward, up) <= 0.95F || y < 0))
{
newForward = MyRotate(newForward, -y, transform.right, Vector3.zero);
}
}
}
return -newForward;
}
Original: https://wiki.disenone.site/ar
This post is protected by CC BY-NC-SA 4.0 agreement, should be reproduced with attribution.
Visitors. Total Visits. Page Visits.
هذه المشاركة تمت ترجمتها باستخدام ChatGPT، يُرجى تقديم ردود فعلأشر على أية نقصانات.