Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by kot2202 · Aug 10, 2020 at 09:30 AM · eventslistenerweapon systemserializefieldweaponchanging

Listen to changes on attached by serializefield script?

I have weapon switch script that detects finger swipe on screen but I feel I designed it the wrong way.

Now the weapon switch has serializefield of type PlayerAttack to switch weapon on and I want to get it the other way as it will be multiplayer game and each player will get own weapon switch swipe canvas - so - serializefield on playerAttack to set the weapon switch to listen to is what I want to achieve.

I hope it makes sense lol

 public class WeaponSwitchDetector : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
 {
     [SerializeField] PlayerAttack playerAttack;
     float _startXPos = 0f;
     float _endXPos = 0f;
 
 
     //TODO redo this, it's the player that should set it's weapon switcher ui, not the other way around.
     public void SetPlayerToSwitchWeaponOn(PlayerAttack thisPlayerAttack)
     {
         playerAttack = thisPlayerAttack;
     }
 
     public void OnBeginDrag(PointerEventData eventData)
     {
         _startXPos = eventData.position.x;
     }
 
     public void OnDrag(PointerEventData data)
     {
     }
 
 
     public void OnEndDrag(PointerEventData eventData)
     {
         _endXPos = eventData.position.x;
         if (_endXPos < _startXPos)
         {
             playerAttack.SwitchWeapon(0);
         }
         else
         {
             playerAttack.SwitchWeapon(1);
         }
     }
 }
Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image andrew-lukasik · Aug 12, 2020 at 11:13 AM 0
Share

A tak po polskiemu?

avatar image kot2202 andrew-lukasik · Aug 12, 2020 at 11:27 AM 1
Share

Teraz mój WeaponSwitchDetector ma pole SerializeField w którym ustawiam który PlayerAttack ma uruchamiać funkcję od zmiany broni

Ja chcę to zrobić odwrotnie, usunąć SerializeField z WeaponSwitchDetector, żeby w PlayerAttack zrobić SerializeField i dopiero tu ustawić który WeaponSwitchDetector mam nasłuchiwać (chciałbym zwróconą pozycję kliknięcia onBeginDrag i OnEndDrag a zmieniać broń prosto z PlayerAttack na podstawie tych dwóch) Nie wiem nawet czy tak się da zrobić ale chciałbym mieć lepszy design i strukturę a nie pomieszanie między ui a 'nie ui'

avatar image andrew-lukasik kot2202 · Aug 12, 2020 at 02:43 PM 1
Share

Warstwę UI od obiektów sceny można rozdzielić za pomocą eventów (tzw. observer pattern). Polega to na tym, że klasa UI wystawia publiczne pole event do którego inne klasy mogą dodawać swoje callbacki (tylko dodawana metoda musi pasować wzorem do wzoru eventu tj. mieć takie same argumenty). Czyli wtedy jedyną odpowiedzialnością klasy WeaponSwitchDetector staje się uruchamiania eventu onSwitchWeapon i nic więcej. Każda klasa może wtedy podpiąć swój callback pod zdarzenie WeaponSwitchDetector.onSwitchWeapon (zmiana broni, uruchomienie dźwięku, wysłanie analityki etc), jeśli tylko ma ku temu powód. Gdyby coś było niejasne to pytaj.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by andrew-lukasik · Aug 12, 2020 at 12:40 PM

Case: multiple WeaponSwitchDetector instances:

 /// 
 /// RESPONSIBILITY: Raise weapon switch event. Allow other scripts to subscribe.
 /// 
 public class WeaponSwitchDetector : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
 {
     float _startXPos = 0f;
     public event System.Action<int> onSwitchWeapon = (dir) =>
     {
         #if UNITY_EDITOR
         Debug.Log($"{nameof(onSwitchWeapon)}( {dir} ) event raised");
         #endif
     };
     void IBeginDragHandler.OnBeginDrag ( PointerEventData eventData )
         => _startXPos = eventData.position.x;
     void IDragHandler.OnDrag ( PointerEventData data ) {}
     void IEndDragHandler.OnEndDrag ( PointerEventData eventData )
         => onSwitchWeapon( eventData.position.x<_startXPos ? 0 : 1 );
 }


 /// 
 /// RESPONSIBILITY: Switch weapons I guess  ¯\_(ツ)_/¯
 /// 
 public class PlayerAttack : MonoBehaviour
 {
     [SerializeField] WeaponSwitchDetector _switchDetector = null;

     void OnEnable () => _switchDetector.onSwitchWeapon += SwitchWeapon;// subscribe
     void OnDisable () => _switchDetector.onSwitchWeapon -= SwitchWeapon;// unsubscribe
     public void SwitchWeapon ( int i ) => Debug.Log($"Weapon {i} selected!");
 }

Case: single WeaponSwitchDetector instance:

 /// 
 /// RESPONSIBILITY: Raise weapon switch event. Allow other scripts to subscribe.
 /// 
 public class WeaponSwitchDetector : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
 {
     float _startXPos = 0f;
     public static event System.Action<int> onSwitchWeapon = (dir) =>
     {
         #if UNITY_EDITOR
         Debug.Log($"{nameof(onSwitchWeapon)}( {dir} ) event raised");
         #endif
     };
     void IBeginDragHandler.OnBeginDrag ( PointerEventData eventData )
         => _startXPos = eventData.position.x;
     void IDragHandler.OnDrag ( PointerEventData data ) {}
     void IEndDragHandler.OnEndDrag ( PointerEventData eventData )
         => onSwitchWeapon( eventData.position.x<_startXPos ? 0 : 1 );
 }


 /// 
 /// RESPONSIBILITY: Switch weapons I guess  ¯\_(ツ)_/¯
 /// 
 public class PlayerAttack : MonoBehaviour
 {
     void OnEnable () => WeaponSwitchDetector.onSwitchWeapon += SwitchWeapon;// subscribe
     void OnDisable () => WeaponSwitchDetector.onSwitchWeapon -= SwitchWeapon;// unsubscribe
     public void SwitchWeapon ( int i ) => Debug.Log($"Weapon {i} selected!");
 }



Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image andrew-lukasik · Aug 13, 2020 at 08:24 AM 1
Share

If you find my code syntax somewhat confusing here is a vanilla, 1:1, 100% equivalent:

 /// 
 /// RESPONSIBILITY: Raise weapon switch event. Allow other scripts to subscribe.
 /// 
 public class WeaponSwitchDetector : $$anonymous$$onoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
 {
     float _startXPos = 0f;
     public event System.Action<int> onSwitchWeapon = onSwitchWeapon_InitialCallback;
     public void OnBeginDrag ( PointerEventData eventData )
     {
         _startXPos = eventData.position.x;
     }
     public void OnDrag ( PointerEventData data )
     {
         
     }
     public void OnEndDrag ( PointerEventData eventData )
     {
         if( eventData.position.x<_startXPos ) onSwitchWeapon( 0 );
         else onSwitchWeapon( 1 );
     }
     static void onSwitchWeapon_InitialCallback ( int dir )
     {
         #if UNITY_EDITOR
         Debug.Log( nameof(onSwitchWeapon) + "( " + dir + " ) event raised");
         #endif
     }
 }


 /// 
 /// RESPONSIBILITY: Switch weapons I guess  ¯\_(ツ)_/¯
 /// 
 public class PlayerAttack : $$anonymous$$onoBehaviour
 {
     [SerializeField] WeaponSwitchDetector _switchDetector = null;

     void OnEnable ()
     {
         _switchDetector.onSwitchWeapon += SwitchWeapon;// subscribe
     }
     void OnDisable ()
     {
         _switchDetector.onSwitchWeapon -= SwitchWeapon;// unsubscribe
     }
     public void SwitchWeapon ( int dir )
     {
         Debug.Log( "Weapon " + dir + " selected!" );
     }
 }
avatar image kot2202 andrew-lukasik · Aug 13, 2020 at 10:59 AM 1
Share

No właśnie nie wiedziałem jak działa większość tych '=>' , nigdy nie miałem okazji używać takiej konstrukcji. Dzięki za pomoc choć mam kilka pytań

public event System.Action<int> onSwitchWeapon = onSwitchWeapon_DefaultCallback;

To przypisanie do onSwitchWeapon_DefaultCallback faktycznie musi mieć jakąś domyślną funkcję? $$anonymous$$yślałem, że masz pomyłkę i to powinno być _InitialCallback ale wtedy metoda musi być statyczna i przy każdej próbie zmiany dostawałem info z konsoli o ustawieniu eventu.

Rozumiem więc, że można po prostu dodać dodatkową funkcję, która będzie wykonywana przy każdym wykonaniu eventu? (Ustawiłem na null i działa.)

Jak działa ta część przy triggerowaniu eventu ? 0 : 1)? To 0 i 1 to wartości do zwrócenia dla podpiętego listenera zależnie od spełnienia warunku, a czy ten pytajnik i dwukropek na coś wpływają czy taki po prostu jest syntax?

avatar image andrew-lukasik kot2202 · Aug 13, 2020 at 11:49 AM 1
Share

"Czy onSwitchWeapon musi mieć jakąś domyślną funkcję?"

Nie musi, możesz dać spokojnie null. Ale z tego względu że null może prowadzić do czasami do NullReferenceException to zainicjowanie go jakąś metodą po prostu pozwala się tym nie przejmować i tyle. Plus skoro ta metoda wykonywana jest przy każdym uruchomieniu eventu to czasami się przydaje przy debuggowaniu, wystarczy (jak tu) wrzucić do niej Debug.Log żeby móc wiedzieć kiedy ten event jest uruchamiany (łatwo taką linijkę wykomentować żeby wyłączyć loga jak nie potrzebny aktualnie).


"onSwitchWeapon( eventData.position.x<_startXPos ? 0 : 1 );"

Ah przeoczyłem. To jest tzw. conditional operator ?: i jest to po prostu skrót od:

 if( eventData.position.x<_startXPos )
     onSwitchWeapon( 0 );
 else
     onSwitchWeapon( 1 );
 
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

134 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Weapon shooting mechanism problem. 1 Answer

Unity first hang then Crashes when importing Paid Unity Asssest (fbx files (includes materials, animations .etc)) ? 0 Answers

Any references on how to handle RPG events in Unity? 1 Answer

Best weapon system for multiplayer FPS? 0 Answers

Animating a weapon into/out of player view 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges