[Resolved][FIBER] I cannot move my NPCs

Drewen
edited December 2010 in Photon Server
Hi all,

I am trying to give some movement to my NPCs (following NPC example), but I am not sure if I am understanding the fiber "thing". It is a thread safety way to schedule actions to NPCs... the thing is: how does it work? I have searched a lot but I didn´t see any example of it.

My idea is this one:

Inside the NPC constructor class (it is just for testing)...
            this.fiber.ScheduleOnInterval(() => Move(100, 0, 0), 1000, 3000);
            this.fiber.Start();
I think I am telling to the fiber to move by 100 in the X axis direction, starting at 1000MS, and doing that every 3000MS.

This is the function Move()
        private void Move(int x_move, int y_move, int z_move)
        {
            Coordinate new_position = new Coordinate();

            float[] pos = new float[3];
            pos[0] += x_move;
            pos[1] += y_move;
            pos[2] += z_move;

            new_position.Value.SetValue(pos,pos.Length);

            this.representation.Move(new_position);
        }

Are these assumptions correct? what am I missing?

Thank you

Comments

  • that is correct. you should store the return value of scheduleOnInterval somewhere to avoid that it's being cleared by the garbage collector (which would stop the timer).
    Fibers do not surround your code with a try-catch block, so make sure to add that to your Move method. (since Move runs in a background thread an exception would stay invisible otherwise).
  • Hi Boris and thank you for your response,

    Now, I am able to move my NPCs...the problem is that i cannot see it in real time: to see the NPCs moving I have to shoot or exit and enter the interest area...

    Why? Is it necessary make an event to receive the NPC update?

    Thanks and sorry for my ignorance...I am a totally begginer.
  • Maybe is because the interest area? Do I Have to subscribe the clients to the NPCInterestArea?
  • It sounds like you get the subscribe event, but no move events.
    Do you still get movement updates from other players?
  • can you please post your fixed NPC Move code?
  • Hi Boris and thank you again for your help,

    Here is the fixed code:
            private void Move(int x_move, int z_move, int y_move)
            {
                try
                {
                    Coordinate new_position = (Coordinate) this.representation.Coordinate;
    
                    float[] pos = this.representation.Position.ToFloatArray();
                    pos[0] += x_move;
                    pos[1] += z_move;
                    pos[2] += y_move;
    
                    new_position.Value.SetValue(pos[0], 0);
                    new_position.Value.SetValue(pos[1], 1);
                    new_position.Value.SetValue(pos[2], 2);
    
                    this.representation.Move(new_position);
                }
                catch (Exception e) {
                    log.Error(e.StackTrace);
                }
            }
    

    About my problem...yes, I get the movement updates from other players but never from the NPCs...

    I'll keep searching...
  • Hi Boris,

    I found the NpcItem"Move" definition and says:

    "Publishes a Photon.SocketServer.Mmo.Messages.ItemPositionMessage in the Photon.SocketServer.Mmo.Item.PositionUpdateChannel and in the current Photon.SocketServer.Mmo.Region if it changes and then updates the Photon.SocketServer.Mmo.Item.Position, Photon.SocketServer.Mmo.Item.Coordinate and Photon.SocketServer.Mmo.Item.CurrentWorldRegion."


    That means that is sending the ItemPostionMessage ONLY if the Region changes???
  • Hi again,

    Well, now it is working. I have added this function to NpcItem and now works:
            public new void Move(ICoordinate newPosition)
            {
                base.Move(newPosition);
    
                var eventInstance = new ItemMoved { ItemId = this.Id, ItemType = this.Type, OldPosition = this.Position.ToFloatArray(), Position = newPosition.ToVector().ToFloatArray() };
    
                var message = new ItemEventMessage(this, eventInstance.GetEventData((byte)EventCode.ItemMoved, Reliability.Reliable, Settings.ItemEventChannel));
    
                this.EventChannel.Publish(message);
            }
    

    It seems that I needed to publish the message by myself, not only with the base Move() function. I am using the base.Move() function just to update the new position. Is it ok or can I do it in a better way?


    Thank you
  • Drewen wrote:
    That means that is sending the ItemPostionMessage ONLY if the Region changes???
    This is about subscriptions:The interest area gets an ItemPostionMessage through the region and subscribes to the sender's position update channel if not already done so earlier. One message every 5 seconds (default) from the position update channel is evaluated to determine whether to unsubscribe.
  • Drewen wrote:
    Hi again,

    Well, now it is working. I have added this function to NpcItem and now works:
            public new void Move(ICoordinate newPosition)
            {
                base.Move(newPosition);
    
                var eventInstance = new ItemMoved { ItemId = this.Id, ItemType = this.Type, OldPosition = this.Position.ToFloatArray(), Position = newPosition.ToVector().ToFloatArray() };
    
                var message = new ItemEventMessage(this, eventInstance.GetEventData((byte)EventCode.ItemMoved, Reliability.Reliable, Settings.ItemEventChannel));
    
                this.EventChannel.Publish(message);
            }
    

    It seems that I needed to publish the message by myself, not only with the base Move() function. I am using the base.Move() function just to update the new position. Is it ok or can I do it in a better way?


    Thank you
    Very good, sorry that I overlooked that earlier.
    The move event for normal items is sent at MmoActor.ItemOperationMove.
    It's not in the base class to give the developer the power to decide if and what content he wants to send.
    The previous mentioned ItemPositionMessages do not contain the event and are used just for subscription management.
  • Hi,

    I have another question regarding Fiber...

    If I want to create a "route" for my NPCs like this (in a smoothly way, like transitions):

    O ----> O
    ^ xxxx |
    | xxxx v
    O <---O

    But all the time... while the server is running... what is the best idea?

    Because, scheduleOnInterval overlaps the scheduled actions. For example, I want to move NPC1 from 0,0,0 to 5,5,0 moving 1,1,0 every 100ms...but when the NPC arribes to 5,5,0, I want it back to the 0,0,0 ... if I create an action to move back to 0,0,0 , it overlaps with the first one and it becomes a loop between 4,4,0 and 5,5,0.....

    I don´t know if you can understand the case, I could explain it better I think...

    Any idea?


    Thank you.
  • If it's really a fixed path that never changes you could calculate the route's coordinates once and add them all to a queue. scheduleOnInterval can then always Dequeue a coordinate, Move, and Enqueue the dequeued coordinate again.
    The queue for your example would look like this:
    0,0,0 / 1,1,0 / 2,2,0 / 3,3,0 / 4,4,0 / 5,5,0 / 4,4,0 / 3,3,0 / 2,2,0 / 1,1,0

    If you need more intelligent path finding you should look into algorithms like A*.
    I just found this article that might be of interest for you: http://www.codeproject.com/KB/recipes/f ... rithm.aspx
  • Thank you Boris!

    That worked pretty good, you are the best!!
  • One more question:

    I wanna see my NPC as a Game Object in Unity and with animations...this is my idea:

    - Update the NPC (position, rotation and state) in the Server and send this information to the attached peers-> then each attached peer translates this information to update position, rotation and animation (this is the "state" value) of the sender.

    How can I send the "state" value to the peers attached? Do I Have to create a new "Event" for this?

    Is this the same process to animate other players?

    Any idea?


    Thank you,
  • You can add this information to the existing move event or create a new one.
    If the state does not change as often you could also set it as a property.
    It would be the same for player animations.
  • Hi again Boris,

    Just a silly question... where are "move events" handled in the client side?? I cannot see where :(

    I am sending the state of the of the NPCs in the Move event...but I don´t know where is handled! arggg!
  • Solved. Now my NPCs have AI and move wherever I want.

    Thanks.