пересылка обьекта

Тема в разделе "Кодинг", создана пользователем idpro2, 4 дек 2016.

Метки:
  1. idpro2

    idpro2 Соучастник

    Доброго времени!
    задался следующим вопросом - как передать специальный обьект внутрь BroadcastLocalizedMessage (метод для вывода HUD сообщения на экране у игрока)

    Обычно вызов BroadcastLocalizedMessage выглядит примерно так:
    Код:
    BroadcastLocalizedMessage(class'LocalMessageTest', , CtrlOne.PlayerReplicationInfo, CtrlTwo.PlayerReplicationInfo);
    Где первый параметр - класс унаследованный от LocalMessage, остальные параметры передают PlayerReplicationInfo, и последний параметр - опциональный обьект (который и нужен)

    Сам класс LocalMessageTest:

    Код:
    class LocalMessageTest extends LocalMessage;
    
    static function string GetString(optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject)
    {
        local string S;
        local MyObject MO;
       
        MO = MyObject(OptionalObject);
       
        if (MO == None)
            return "none";
       
        S = MO.Message;
       
        default.Lifetime = MO.Lifetime;
       
        return S;
    }
    
    defaultproperties
    {
        Lifetime=15
        DrawColor=(R=255,G=255,B=255)
        PosY=0.450000
    }
    
    И сам опциональный обьект (не уверен что я его сделал правильно):

    Код:
    class MyObject extends Object;
    
    var int Lifetime;
    var string Message;
    
    defaultproperties
    {
        Lifetime=33
        Message="Test12345"
    }
    Помогите пожалуйста разобраться, как правильно сделать этот опциональный обьект, который можно будет создать/заполнить и передать извне в BroadcastLocalizedMessage
    Хочу в итоге добиться типа такого:

    Код:
    local MyObject MO;
    
    MO.Message = "To show";
    MO.Lifetime = 25;
    
    BroadcastLocalizedMessage(class'LocalMessageTest', , , ,MO);
     
  2. Flame

    Flame -Заслуженый кодер форума-

    idpro2 нравится это.
  3. idpro2

    idpro2 Соучастник

    Спасибо! Изучил :)

    Но все-равно не выходит(

    Я нашел статейку по Localmessage - https://wiki.beyondunreal.com/Legacy:Using_LocalMessages
    Там пишут мол опциональный обьект должен уже существовать у всех игроков прежде чем его можно отсылать, если я все правильно понял.

    По коду выше у меня всегда выдает "MO is none", т.е. обьект не приходит

    Пробовал делать так:

    Код:
    local MyObject MO;
    
    MO = new class'MyObject';
    MO.Lifetime = 10;
    MO.R = 0;
    MO.G = 255;
    MO.B = 0;
    MO.PosY = 0.200000;
    MO.Message = txt;
    BroadcastLocalizedMessage(class'LocalMessageTest', , , , MO);
     
  4. gall87

    gall87 Капо

    ну в слотмашин мутаторе было что то похожее, глянь там
     
  5. gall87

    gall87 Капо

    ну как пример, мы выиграли банку блевотины в рулетке!Карта вызывает сообшение и эффект!
    static function float ExecuteCard( Pawn Target )
    {
    Target.TakeDamage(30,None,Target.Location,vect(0,0,0),Class'DamTypeVomit');
    PlayerController(Target.Controller).ReceiveLocalizedMessage(Class'ToxicMessage');
    return 0;
    }

    defaultproperties
    {
    CardMaterial=Texture'KillingFloorHUD.Achievements.Achievement_4'
    }

    class ToxicMessage extends LocalMessage;

    var localized string Message;

    static function string GetString(
    optional int Switch,
    optional PlayerReplicationInfo RelatedPRI_1,
    optional PlayerReplicationInfo RelatedPRI_2,
    optional Object OptionalObject )
    {
    return Default.Message;
    }

    defaultproperties
    {
    Message="Уххх... Плохое чувство..."
    bIsUnique=True
    bFadeMessage=True
    Lifetime=4
    DrawColor=(B=0,R=0)
    StackMode=SM_Down
    PosY=0.800000
    }
     
  6. Flame

    Flame -Заслуженый кодер форума-

    Не. Тут не передаётся объект)
    Ближе к ночи напишу что-нибудь о этой теме
     
    idpro2 нравится это.
  7. idpro2

    idpro2 Соучастник

    gall87, спасибо за помощь, но к сожалению это не то, суть темы немного в другом
     
  8. Flame

    Flame -Заслуженый кодер форума-

    Так. Всё руки не дойдут.
    Я тебе сейчас так скажу по примеру какого-то моего мутатора.
    Смотри как я сделал:
    Код:
    class PatHPLeftObject extends Actor;
    var int Damage;
    var string PlayerName;
    replication
    {
        reliable if(bNetDirty && Role == Role_Authority)
            Damage,PlayerName;
    }
    
    То есть не буквально воспринял мысль - что надо именно объект
    Actor этож тоже Object - я и передал класс унаследованный от Actor
    А Actor чем хорош? Правильно - там можно делать репликацию.
    С передачей этого объекта обычно одна беда - передаётся он на сервере, а используется на клиенте
    Правда не знаю успеет ли произойти репликация - сейчас лень думать. В моём мутаторе все нормально в этом плане)
    В общем может поможет. Сам гляну завтра
     
  9. Flame

    Flame -Заслуженый кодер форума-

    Так. Держи мутатор.
    Мутатор выводит в начале волны сообщения игрокам, если они упомянуты в ini.
    Используем объект для передачи данных. У разных игроков - разные сообщения.
    Зашёл вот под двумя аккаунтами
    [​IMG]
    [​IMG]
    Там в комментариях вроде всё расписал.
    Код:
    Код:
    class MessageMut extends Mutator config(MessageMut);
    
    struct MessageStruct
    {
        var config string Hash;
        var config string PlayerName;
        var config string Message;
    };
    var config array<MessageStruct> Messages;
    
    var bool bMessageSent;
    var bool bMessageCreated;
    
    //Запускаем таймер
    function PostBeginPlay()
    {
        SaveConfig();
        SetTimer(0.5,true);
    }
    
    //В таймере отлавливаем начало волны. Если началась волна, то на 1 этапе мы создаём объекты в if(!bMessageCreated)
    //Для каждого игрока создаются разные сообщения
    //После этого даём мутатору время на репликацию этих сообщений на клиент
    //В следующем вызове таймера мы выполняем рассылку сообщений игрокам
    function Timer()
    {
        local bool bWaveInProgress;
        bWaveInProgress=bool(Level.Game.GetPropertyText("bWaveInProgress"));
        if(!bWaveInProgress)
            return;
        //1 этап
        if(!bMessageCreated)
        {
            CreateMessage();
            bMessageCreated = true;
            return;
        }
        //2 этап
        if(bMessageCreated && !bMessageSent)
        {
            SendMessage();
            bMessageSent = true;
        }
        //Больше нам мутатор не нужен - удаляем его
        if(bMessageSent)
            Destroy();
    }
    
    //В данной функции для всех игроков создаётся объект в котором содержится сообщение
    function CreateMessage()
    {
        local Controller C;
        for(C=Level.ControllerList;C!=none;C=C.NextController)
        {
            if(PlayerController(C)!=none && C.PlayerReplicationInfo!=none && C.PlayerReplicationInfo.PlayerID>0)
                CreateObject(PlayerController(C));
        }
    }
    
    //Создаём объект MyObject. Получаем в функции GetMessageIndexFromList индекс сообщения для данного игрока из ини файла
    //Прописываем значение полей для atObject
    //Цепляем этот объект прямо к PlayerController игрока. Просто для удобства. Можно запомнить какой объект соотв. какому игроку любым другим способом.
    function CreateObject(PlayerController PC)
    {
        local int N;
        local MyObject atObject;
    
        N=GetMessageIndexFromList(PC);
        if(N<0)
            return;
    
        atObject=Spawn(class'MyObject');
        atObject.PlayerName=Messages[N].PlayerName;
        atObject.Message=Messages[N].Message;
        PC.Attached[PC.Attached.Length]=atObject;
    }
    
    //Функция тащит индекс нужного элемента массива. Сравнение идёт по хэшу прописанному в ини файле
    function int GetMessageIndexFromList(PlayerController PC)
    {
        local string Hash;
        local int i;
        Hash=PC.GetPlayerIDHash();
        for(i=0;i<Messages.Length;i++)
        {
            if(Hash~=Messages[i].Hash)
                return i;
        }
        return -1;
    }
    
    //Функция отсылает сообщение игрокам. GetObjectIndex позволяет нам получить именно нужный нам объект MyObject из массива Attached
    //Вообще говоря по умолчанию этот массив содержит только наш объект. И можно просто прописать N=0, но мало ли. Перестрахуемся
    function SendMessage()
    {
        local Controller C;
        local PlayerController PC;
        local Actor atObject;
        local int N;
        for(C=Level.ControllerList;C!=none;C=C.NextController)
        {
            if(PlayerController(C)!=none && C.PlayerReplicationInfo!=none && C.PlayerReplicationInfo.PlayerID>0)
            {
                PC=PlayerController(C);
                N=GetObjectIndex(PC);
                if(N>=0)
                    atObject=PC.Attached[N];
                PC.ReceiveLocalizedMessage(class'MyMessage',0,,,atObject);
            }
        }
    }
    //Функция получает индекс MyObject объекта среди всех присоединённых объектов
    function int GetObjectIndex(PlayerController PC)
    {
        local int i;
        for(i=0;i<PC.Attached.Length;i++)
        {
            if(PC.Attached[i].IsA('MyObject'))
                return i;
        }
        return -1;
    }
    
    defaultproperties
    {
        Messages(0)=(Hash="76561198051378449",PlayerName="Flame",Message="Happy Birthday")
        bAddToServerPackages=true
        GroupName="KF-Message"
        FriendlyName="MessageMut"
        Description="MessageMut"
    }
    
    Код:
    class MyMessage extends CriticalEventPlus
        abstract;
    
    var(Message) localized string InfoText[2];
    
    static function string GetString(
        optional int Switch,
        optional PlayerReplicationInfo RelatedPRI_1,
        optional PlayerReplicationInfo RelatedPRI_2,
        optional Object OptionalObject
        )
    {
        //Если объект передан и если длина сообщения не 0 - отправляем сообщение в формате Имя: Сообщение
        if(MyObject(OptionalObject)!=none && Len(MyObject(OptionalObject).Message)>0)
            return MyObject(OptionalObject).PlayerName$":"@MyObject(OptionalObject).Message;
        //Иначе идёт обычный вызов
        return Default.InfoText[Switch];
    }
    
    defaultproperties
    {
        InfoText(0)="Hi"
        bIsUnique=False
        Lifetime=20
        DrawColor=(R=245,G=10,B=69)
        DrawPivot=DP_UpperLeft
        StackMode=SM_Down
        PosX=0.300000
        PosY=0.300000
    }
    
    Код:
    class MyObject extends Actor;
    
    var string Message,PlayerName;
    
    replication
    {
        reliable if(bNetDirty && Role == Role_Authority)
            Message,PlayerName;
    }
    
    defaultproperties
    {
        //Важно
        bAlwaysRelevant=True
    }
    

    Ссылка
     
    idpro2 и Essence нравится это.
  10. idpro2

    idpro2 Соучастник

    Flame, спасибо!
    Реально ли сделать тоже самое через LocalMessage а не CriticalEventPlus, если допустим нужно опционально установить цвет сообщения и другие свойства из defaultproperties в LocalMessage?
    У меня просто не срабатывает в таком случае, даже обьект не передается.
    Вот мой код:

    Код:
    // функция в которой устанавливаем параметры и отсылаем игрокам
    
    static function SendToPlayers()
    {
        local LocalMessageObject LMO;
        LMO = Spawn(class'LocalMessageObject');
        LMO.Lifetime = 3;
        LMO.R = 255;
        LMO.G = 255;
        LMO.B = 0;
        LMO.PosY = 0.500000;
        LMO.Message = PlayerName @ "receive bonus";
        BroadcastLocalizedMessage(class'LocalMessageEx', 0, , , LMO);
    }
    
    // обьект который будет отослан
    
    class LocalMessageObject extends Actor;
    
    var string Message;
    var byte R, G, B;
    var float PosY;
    var int Lifetime;
    var bool bFade;
    
    replication
    {
        reliable if (bNetDirty && Role == Role_Authority)
            Message,
            R, G, B,
            PosY,
            Lifetime,
            bFade;
    }
    
    defaultproperties
    {
        bAlwaysRelevant=True
    }
    
    // сам класс-наследник LocalMessage который проверяет опциональный обьект и отправляет сообщения
    
    class LocalMessageEx extends LocalMessage;
    
    var(Message) localized string DefaultText[2];
    
    static function string GetString(
        optional int Switch, 
        optional PlayerReplicationInfo RelatedPRI_1, 
        optional PlayerReplicationInfo RelatedPRI_2, 
        optional Object OptionalObject)
    {
        local LocalMessageObject LMO;
       
        if (LocalMessageObject(OptionalObject) == none)
        {
            return default.DefaultText[Switch];
        }
       
        LMO = LocalMessageObject(OptionalObject);
       
        if (LMO.Lifetime > 0)
            default.Lifetime = LMO.Lifetime;
       
        default.DrawColor.R = LMO.R;
        default.DrawColor.G = LMO.G;
        default.DrawColor.B = LMO.B;
       
        default.PosY = LMO.PosY;
       
        default.bFadeMessage = LMO.bFade;
       
        return LMO.Message;
    }
    
    defaultproperties
    {
        DefaultText(0)="Test"
        Lifetime=5
        DrawColor=(R=255,G=0,B=0)
        PosY=0.50000
        bFadeMessage=True
    }
    
     
  11. idpro2

    idpro2 Соучастник

    Вопрос еще актуален. Заранее спасибо
     
  12. idpro2

    idpro2 Соучастник

    ап, очень прошу подсказать
     
  13. Flame

    Flame -Заслуженый кодер форума-

    Подскажу, чуть позже
    Чтобы ускорить это - мог бы уже давно сделать какой-то мутатор, который можно запустить, убедиться, что не работает и поправить)
    Мне же лень самому эт писать)