آموزش تاچ/مالتی تاچ در یونیتی/آموزش کلاس Input و تشخیص لمس یا Touch در unity
پنجشنبه, ۲ مهر ۱۳۹۴، ۱۰:۲۸ ب.ظ
منبع:gameover.blog.ir
برای اینکار از کلاس Input استفاده میشه و تعداد(count) انگشت ها رو هم میشه شمرد.
قبل از هرچیزی باید بررسی کنیم که دستگاه ما آیا از multi touch ساپورت می کنه یا نه.
bool supportsMultiTouch = Input.multiTouchEnabled; print("MultiTouchSupport : " + supportsMultiTouch);
این آموزش فرضش اینه که موبایل لمسی شما از مالتی تاچ حمایت می کنه.برای گوشی های single-touch کافیه توی هر تایم یک تاچ رو چک کنیم.
مثال زیر همه ی تاچ(لمس) ها و موقعیت اونا رو نمایش تشخیص می ده :
void Update () { int nbTouches = Input.touchCount; if(nbTouches > 0) { print(nbTouches + " touch(es) detected"); for (int i = 0; i < nbTouches; i++) { Touch touch = Input.GetTouch(i); print("Touch index " + touch.fingerId + " detected at position " + touch.position); } } }
Input.touchCount تعداد تاچ ها رو تشخیص می ده.
می تونیمبا یک loop و تکرار با استفاده از Input.GetTouch تمام لمس ها رو تشخیص بدیم.
هر ساختار Touch شامل یک fingerId هست که یک نمونه یا موجودیت(instance ) برای آن lifetime(زمان) را شناسایی می کند و این کار را ادامه می دهد تا اینکه تاچ (لمس) stop کند(متوقف شود) با این امکان می توان برای تخیص تاچ های یکسان در فریم های مختلف استفاده کرد.
با استفاده از touch.position می تونیم مختصات ناحیه ی لمس شده روی screen(صفحه) رو تشخیص بدیم.
نکته بسیار مهم : یادتون باشه،مبداء بردار لمسی در پایین ترین گوشه ی سمت چپ صفحه می باشد.
متد دیگه برای تشخیص تاچ ها ، Input.touches است که یک لیست از ابجکت های لمس شده ی صفحه رو به ما میده.
با اینکه متد اول باید استفاده شود همانند Input.touches متغیرهای موقت و ممکن است کارایی بازی را کاهش دهند.
داده های ورودی ، دقیقا قبل ار تابع Update()، در هر فریم refresh می شوند.
به طوری که در آن شما باید تمام کدهای لازم مدیریت ورودی(input-management logic)را در آن قرار دهید.
انجام این کار اگر در تابع FixedUpdate انجام بشه،جلوی catching (یا خطایابی) داده های ورودی کاربر رو از ما می گیره.زیرا FixedUpdate اگرچه در گام های مختلف ولی در هر فریم از زمان اجرا نمیشه.
Touch Phases(فاز های لمسی):
در کد زیر با استفاده از خصوصیت phase شروع و پایان و لحظه ی تاچ را تشخیص می دهیم :
void Update () { int nbTouches = Input.touchCount; if(nbTouches > 0) { for (int i = 0; i < nbTouches; i++) { Touch touch = Input.GetTouch(i); TouchPhase phase = touch.phase; switch(phase) { case TouchPhase.Began: print("New touch detected at position " + touch.position + " , index " + touch.fingerId); break; case TouchPhase.Moved: print("Touch index " + touch.fingerId + " has moved by " + touch.deltaPosition); break; case TouchPhase.Stationary: print("Touch index " + touch.fingerId + " is stationary at position " + touch.position); break; case TouchPhase.Ended: print("Touch index " + touch.fingerId + " ended at position " + touch.position); break; case TouchPhase.Canceled: print("Touch index " + touch.fingerId + " cancelled"); break; } } } }
زمانی که کاربر در کشیدن انگشت خود(swipping) بر روی صفحه نمایش است،ما به جای موقعیت واقعی،تغییرات دلتای موقعیت(position) را دنبال می کنیم.این برای زمانی مفید است که عمل درگ(Drag=کشیدن و انداختن چیزی با ماوس یا لمس)را انجام می دهیم.
سپس با استفاده از deltaTime سرعت حرکت touch input رو محاسبه می کنیم :
float touchSpeed = touch.deltaPosition.magnitude / touch.deltaTime;
اگه اشتباهی رخ بده تاچ کنسل(cancel) می شه.به عنوان مثال هنگامی که یک منطقه بزرگ در برابر صفحه نمایش فشرده یا تاچ های بیش از آنچه دستگاه ساپورت می کنه انجام بشه.برای تشخیص موقعیت شروع لمس صفحه توسط کاربر از "Began" استفاده می کنیم.سپس می تونیم یک ray(اشعه) رو از موقعیت ورودی با اتفاده از دوربین،cast(پرتاب) و با استفاده از Raycast collision اشیایی رو که در امتداد اشعه هستند چک کنیم.
void Update () { int nbTouches = Input.touchCount; if(nbTouches > 0) { for (int i = 0; i < nbTouches; i++) { Touch touch = Input.GetTouch(i); if(touch.phase == TouchPhase.Began) { Ray screenRay = Camera.main.ScreenPointToRay(touch.position); RaycastHit hit; if (Physics.Raycast(screenRay, out hit)) { print("User tapped on game object " + hit.collider.gameObject.name); handleTap(hit.collider.gameObject); } } } } }
در بعضی مواقع می خوایم دوبار لمس سریع کاربر رو بررسی کنیم.برای مثال یه وقتی می خوایم وقتی کاربر با انگشت به صفحه ضربه(tap) زد Player راه بره و اگه دوبار سریع ضربه زد(double tap) کاراکتر Player با سرعت راه بره.
void Update () { int nbTouches = Input.touchCount; if(nbTouches > 0) { for (int i = 0; i < nbTouches; i++) { Touch touch = Input.GetTouch(i); if(touch.phase == TouchPhase.Began) { if(touch.tapCount >= 2) { Run(); } else { Walk(); } } } } else { StopMoving(); } }
وقتی touch ما Begin می کنه(وقتی لمس آغاز میشه)، player با تک ضرب انگشت حرکت و با چند ضرب شروع به دویدن می کنه.
اگه هم هیچ تاچ یا لمسی صورت نگیره game character متوقف می شه.
زمانیکه متدهای مختلف مثل Walk را اجرا می کنیم شما همچنین بررسی می کنید کاربر در حال حاضر در حال راه رفتن است یا خیر.
نکته: بعضی اوقات unity نمی تونه لمس های سریع رو درست تشخیص بده.(سعی کنید یادتون باشه)
۹۴/۰۷/۰۲