اگه بازی سونیک یادتون باشه یه فنری داشت که میپریدیم روش و موقعی که فنر بالا میرفت، سونیک رو هم به سمت بالا هول میداد. حالا تو این مطلب، اسکریپتی رو برای شما عزیزان نوشتیم که تا حدودی کار این فنر رو انجام میده… بنابراین در ادامه با فول کده همراه باشید.
مراحل انجام کار
برای شروع، اسکریپتی به نام Spring ایجاد میکنیم که این اسکریپت رو قراره به گیم آبجکت فنر اختصاص بدیم. و داخل اسکریپت، از رویدادهای OnTriggerEnter2D یا OnCollisionEnter2D میتونیم برای تشخیص برخورد بازیکن به فنر استفاده کنیم. «مطالعه بیشتر در مورد برخورد در یونیتی»
بنابراین ما در اینجا یک Collider و ترجیحا Box Collider به گیم آبجکت فنر اضافه کرده و کمی اون رو به بالا انتقال میدیم تا فقط سطح فنر رو بپوشونه. طبق تصویر زیر:
حالا یک Collider به پای اسپرایت کاراکترمون اضافه میکنیم و اون رو کمی بیرونتر از Collider اصلی کاراکتر قرار میدیم تا بتونه به فنر بخوره. و در نهایت تیک Is Trigger رو برای اون فعال میکنیم.
به اسکریپت Spring برمیگردیم و در متد OnTriggerEnter2D بررسی میکنیم که اگه کلایدر وارد شده به فنر، همون کلایدری بود که توی پای بازیکن قرار دادیم، پس انیمیشن مربوط به باز و بسته شدن فنر رو اجرا کنه. (انیمیشنی که طی اون فنر به پایین و سپس بالا میره و در نهایت به جای اولش برمیگرده که خودتون باید برای فنرتون پیاده کرده باشید.)
حالا بعد از تنظیم انیمیشن، یک ویژگی به نام playerGameObject قراره تو فنر داشته باشیم تا داخلش، آبجکت وارد شده به روی فنر رو نگهداریم که فعلا فقط بازیکنه. (البته بعدا هدف از این کار معلوم میشه):
void OnTriggerEnter2D(Collider2D target) { if (target.gameObject.Equals("Player")) { animator.SetInteger ("AnimState", 1); playerGameObject = target.gameObject; } }
حالا متدی به اسم OnFullOpened ایجاد میکنیم که قراره از طریق Animation و در زمان اجرای فریم بالا رفتن کامل فنر اجرا بشه. بنابراین باید این متد رو از داخل انیمیشنتون صدا بزنید. در واقع زمانی که این متد اجرا شد، قراره به Rigidbody بازیکن، نیرویی به سمت بالا وارد بشه و برای اینکه بازیکن رو در اختیار داشته باشیم، اون رو قبلا داخل playerGameObject قرار دادیم. و همچنین میتونیم داخل متد OnFullOpened، صدایی برای فنر پخش کنیم. (کار با صدا در یونیتی)
در نهایت اسکریپت ما به صورت زیر در میاد:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spring : MonoBehaviour { public float force = 5.0f; private Animator animator; private GameObject playerGameObject; void Start() { animator = GetComponent<Animator> (); } void OnTriggerEnter2D(Collider2D target) { if (target.gameObject.Equals("Player")) { animator.SetInteger ("AnimState", 1); playerGameObject = target.gameObject; } } void sound() { GetComponent<AudioSource> ().Play (); } void OnFullOpened() { try { Rigidbody2D rb2d = playerGameObject.GetComponent<Rigidbody2D> (); rb2d.velocity = new Vector2(rb2d.velocity.x, force); } catch { } animator.SetInteger ("AnimState", 0); } }
همونطور که میبینید، نیرویی رو به شتاب Rigidbody بازیکن اضافه کردیم (همون velocity). و البته میتونستیم از AddForce هم استفاده کنیم. اما در کل این شروع ساخت یک فنره و البته یک باگ کوچیکی داره و اونم اینه که ممکنه کاراکتر قبل وارد شدن نیرو از طرف فنر، خودش به سمت بالا بپره و چون آبجکتش داخل فنر نگه داشته شده، کاراکتر تو هوا بهش نیرو وارد میشه! برای جلوگیری از این میتونین رویداد خروجی Trigger رو هم تعریف کنین تا اگه کاراکتر از روی فنر پرید، مقدار playerGameObject رو نال کنیه و همچنین داخل OnFullOpened بررسی کنیم که آیا playerGameObject پره یا خالی. البته این روش سادهترین روش جلوگیری از این باگه و خودتون میتونین با روشهای دیگهای از جمله Rayscast یا شتاب فعلی کاراکتر، بررسی درستتری رو انجام بدین.
نظرات ثبت شده بدون دیدگاه