OmniInteraction

نظام تفاعل مرن وسهل الاستخدام مع Blueprint. اكتشف الكائنات القريبة، وتنقّل بينها، وتفاعل معها فورًا أو بالضغط المطوّل، مع أحداث واجهة مستخدم مدمجة.

نظرة عامة

يمنح OmniInteraction أي Actor القدرة على العثور على الكائنات القابلة للتفاعل من حوله واستخدامها. أضِف مكوّنًا واحدًا إلى شخصيتك، وطبّق واجهة واحدة على كائناتك، لتحصل على الاكتشاف، وفحوصات خط الرؤية، وقائمة قابلة للتحديد، والتفاعل بالضغط المطوّل، وأحداث واجهة المستخدم.

الاكتشاف بالنطاقمسح كروي حول المالك بنصف قطر قابل للضبط.
خط الرؤيةيتم تجاهل الكائنات المخفية خلف الجدران تلقائيًا.
تحديد عدة عناصرتنقّل بين عدة عناصر قريبة باستخدام ⁦IndexUp / IndexDown⁩، مع إمكانية التفاف التحديد اختياريًا.
فوري أو مطوّليحدد كل كائن مدة تفاعله بنفسه. يتم توفير نسبة التقدّم لأشرطة واجهة المستخدم.
أحداث جاهزة لواجهة المستخدممفوّضات (Delegates) للدخول والإزالة والتحديد وتحديث النص مباشرةً لعناصر الواجهة.
تصحيح مدمجارسم نصف القطر واطبع حالة التفاعل الكاملة على الشاشة.

البدء السريع

  1. فعِّل الإضافة
    من القائمة Edit → Plugins، فعِّل OmniInteraction، ثم أعد تشغيل المحرر.
  2. أضِف المكوّن
    افتح Blueprint الخاص بشخصيتك (Character) أو أي Actor، وأضِف Interaction System.
  3. طبّق الواجهة
    في الكائن الذي تريد التفاعل معه: Class Settings → Interfaces → أضِف Interactable.
  4. املأ الدوال
    تجاوز (Override) Interact، Get Interact Text، Get Interact Icon، Get Interaction Duration وShould Remove On Interact.
  5. اربط الإدخال
    استدعِ Interact(Get Current Index) عند الضغط، وStop Interact عند الإفلات، وIndex Up / Down عند التمرير.
  6. العب
    اقترب من الكائن، وسيتم اكتشافه وتمييزه تلقائيًا.
متطلب التصادم: يجب أن يحتوي الـ Actors القابلة للتفاعل على مكوّن تصادم يتداخل مع قناة Visibility أو يحجبها، وإلا فلن يعثر عليها المسح.

واجهة Interactable

طبّق IInteractable على أي Actor. جميع الدوال هي Blueprint Native Events، لذا يمكنك تنفيذها في Blueprint أو تجاوز _Implementation في C++.

الدالةالقيمة المُرجَعةالغرض
Interact(Interactor)voidيُستدعى عند نجاح التفاعل. Interactor هو مالك المكوّن.
GetInteractTextStringالتسمية المعروضة في واجهة المستخدم، مثل «التقط السيف». يتم استطلاعها في كل إطار، لذا يمكن أن تكون ديناميكية.
GetInteractIconTexture2Dأيقونة اختيارية لعنصر واجهة المستخدم.
GetInteractionDurationfloat0 = فوري. أكبر من 0 = عدد الثواني التي يجب على اللاعب الضغط خلالها.
ShouldRemoveOnInteractboolإذا كانت true، يغادر العنصر القائمة بعد تفاعل ناجح (العناصر الملتقطة، المستهلكات).
OnHighlightStartvoidيُستدعى عندما يصبح العنصر هو المحدَّد. استخدمه للحواف المضيئة أو التوهّج.
OnHighlightEndvoidيُستدعى عند إلغاء تحديده أو خروجه من النطاق.

مثال C++

class AMyPickup : public AActor, public IInteractable
{
    GENERATED_BODY()
public:
    virtual void Interact_Implementation(AActor* Interactor) override;
    virtual FString GetInteractText_Implementation() override { return TEXT("Pick up"); }
    virtual float GetInteractionDuration_Implementation() override { return 0.0f; }
    virtual bool ShouldRemoveOnInteract_Implementation() override { return true; }
};

مرجع المكوّن

الفئة: UInteractionSystem (مكوّن Actor). أضِفه إلى الـ Actor الذي يقوم بالتفاعل.

الخصائص

الخاصيةالافتراضيالوصف
InteractionRadius90.0نصف قطر الاكتشاف بوحدات Unreal. قابل للقراءة والكتابة في Blueprint.
bWrapSelectionfalseيلتف التحديد من الأخير إلى الأول (والعكس) عند التمرير.
bShowDebugRadiusfalseيرسم كرة الاكتشاف. أخضر عند الخمول، وأحمر أثناء الضغط المطوّل.
bShowDebugStatefalseيطبع الفهرس المحدَّد وقائمة العناصر وتقدّم الضغط المطوّل على الشاشة.

الدوال

الدالةالنوعالوصف
Interact(Index)Callableتتفاعل مع العنصر عند الفهرس Index. تُنفَّذ العناصر الفورية على الفور؛ أما عناصر الضغط المطوّل فتبدأ مؤقّت الضغط.
StopInteractCallableتلغي الضغط المطوّل الحالي وتعيد ضبط التقدّم. استدعِها عند تحرير الإدخال.
IndexUp / IndexDownCallableتنقل التحديد وتُطلق بداية/نهاية التمييز.
InteractAll(bOnlyInstant)Callableتتفاعل مع كل عنصر قريب. الافتراضي هو العناصر الفورية فقط.
ClearAllInteractablesCallableتمسح القائمة وتلغي أي ضغط مطوّل.
RegisterWidgetReference(Widget)Callableتربط عنصر واجهة تم إنشاؤه بخانة العنصر التالي ليتمكن من إزالته بشكل صحيح لاحقًا.
GetHoldProgressPureمن ⁦0⁩ إلى ⁦1⁩. اربطها بشريط تقدّم.
GetCurrentIndexPureالفهرس المحدَّد حاليًا.
GetSelectedActorPureالـ Actor المحدَّد، أو null.
IsHoldInteractionAtIndex(Index)Pureتكون true إذا كان العنصر يتطلب ضغطًا مطوّلًا.
GetUpdatedTextAtIndex(Index)Pureنص التفاعل الحالي لعنصر ما.
GetDistanceToInteractable(Index)Pureالمسافة من المالك إلى العنصر.

الأحداث

اربطها في Blueprint (عبر عُقد Assign) أو في C++ باستخدام AddDynamic.

الحدثالمعاملاتمتى يُطلَق
OnItemEnteredItemName, ItemIconعند دخول كائن جديد قابل للتفاعل إلى النطاق وكونه مرئيًا.
OnItemRemovedWidgetRef, Indexعند خروج عنصر من النطاق أو استهلاكه. استخدمه لتدمير عنصر الواجهة.
OnSelectionChangedNewSelectedIndexعند تغيّر الفهرس المحدَّد.
OnUpdateInteractionTextIndex, NewTextفي كل إطار لكل عنصر، ليبقى النص الديناميكي متزامنًا.

إعداد واجهة المستخدم (Blueprint)

  1. اربط OnItemEntered. أنشئ عنصر الواجهة الخاص بالإدخال (الاسم + الأيقونة) وأضِفه إلى Vertical Box.
  2. استدعِ فورًا RegisterWidgetReference مع عنصر الواجهة ذلك. افعل ذلك مباشرةً بعد إنشائه، بواقع عنصر واجهة واحد لكل عنصر داخل.
  3. اربط OnItemRemoved. استدعِ Remove From Parent على WidgetRef.
  4. اربط OnSelectionChanged لتمييز الإدخال عند NewSelectedIndex.
  5. اربط OnUpdateInteractionText لتحديث التسمية عند Index.
  6. لإجراءات الضغط المطوّل، شغِّل شريط تقدّم من GetHoldProgress.

نصائح وأفضل الممارسات

اجعل نصف القطر صغيرًايعمل المسح في كل إطار. أنصاف الأقطار الصغيرة أقل كلفة وتبدو أكثر دقة.
استخدم مفاتيح التصحيحفعِّل bShowDebugState لترى بالضبط ما الذي يتتبّعه النظام.
النص الديناميكيأرجِع نصوصًا تراعي الحالة، مثل «افتح الباب» أو «أغلق الباب»، من ⁦GetInteractText⁩.
التمييز بأماننفِّذ أعمال التمييز فقط داخل ⁦OnHighlightStart/End⁩ ليبقى التحديد متسقًا.

الأسئلة الشائعة

كائني لا يتم اكتشافه.

هل يمكنني استخدامه مع الذكاء الاصطناعي أو الـ Actors غير اللاعبين؟

كيف أصنع تفاعلًا بالضغط المطوّل؟

هل يعمل مع Enhanced Input؟


Copyright KhalidBen 2026. All rights reserved.