Данный раздел пока в разработке
Player Input and Pawns 1 часть
Настройка Pawn(Customize a Pawn
Серия уроков по программированию на unreal 4.
Данный урок должен дать общее представление о настройке объектов и игроке.
1) Первоначально мы создадим новый проект с базовым кодом на С++ . После мы добавим кастомизированный класс через визард и назовём его MyPawn.
Pawn – является типом актёра которым управляет игрок
2) Во первых мы научим наш MyPawn автоматически реагировать при входе нашего игрока в игру. Pawn класс обеспечивает нас переменные которые инициализируются для нас. В MyPawn.cpp добавляем следующий код в участок AMyPawn::AMyPawn (Это контролёр нашего класса)
// Установим в pawn контролёр игрока с наименьшим числом AutoPossessPlayer = EAutoReceiveInput::Player0;
3) Далее мы создадим несколько базовых компонентов. Если вы хотите почитать побольше о добавлении и управлении компонентами в коде, то вам необходимо почитать руководство по компонентам и коллизиям в unreal engine .Чтобы отслеживать компоненты, необходимо добавить в следующий код нашего класса следующий класс для определения.
UPROPERTY(EditAnywhere) USceneComponent* OurVisibleComponent;
Для того чтобы переменная была видна в движке, её необходимо пометить макросом UPROPERTY, который предотвращает сбрасывание переменной при закрытии уровня или перезагрузке.
И снова мы должны добавить в контролёр нашего MyPawn.cpp следующий код AMyPawn::AMyPawn
// Создаём корневой элемент куда добавим новый объект RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); // Создаём камеру и видимый объект UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera")); OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent")); // крепим нашу камеру и отображаемый объект к корневому элементу. // смещаем и вращаем нашу камеру. OurCamera->AttachTo(RootComponent); OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f)); OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); OurVisibleComponent->AttachTo(RootComponent);
4) Теперь у нас всё настроено и Pawn реагирует на вход игрока при входе в игру. Теперь мы должны определить что будет у нас входом. Чтобы сделать вход, мы должны настроить наш проект в Unreal Engine.
MyPawn.h
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. #pragma once #include "GameFramework/Pawn.h" #include "MyPawn.generated.h" UCLASS() class HOWTO_PLAYERINPUT_API AMyPawn : public APawn { GENERATED_BODY() public: // Sets default values AMyPawn(); // Called when the game starts or when spawned virtual void BeginPlay() override; // Called every frame virtual void Tick( float DeltaSeconds ) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override; UPROPERTY(EditAnywhere) USceneComponent* OurVisibleComponent; };
MyPawn.cpp
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. #include "HowTo_PlayerInput.h" #include "MyPawn.h" // Sets default values AMyPawn::AMyPawn() { // Set this pawn to call Tick() every frame. // Эту опцию можно отключить, если нет в ней необходимости // Это даст прирост производительности PrimaryActorTick.bCanEverTick = true; // Set this pawn to be controlled by the lowest-numbered player AutoPossessPlayer = EAutoReceiveInput::Player0; // Создаём корневой элемент куда добавим новый объект RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent")); // Создаём камеру и видимый объект UCameraComponent* OurCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("OurCamera")); OurVisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("OurVisibleComponent")); // Прикрепляем нашу камеру к корневому объекту // Устанавливаем вмещение и вращение камеры OurCamera->AttachTo(RootComponent); OurCamera->SetRelativeLocation(FVector(-250.0f, 0.0f, 250.0f)); OurCamera->SetRelativeRotation(FRotator(-45.0f, 0.0f, 0.0f)); OurVisibleComponent->AttachTo(RootComponent); } // Вызывается при старте игры или при продолжении void AMyPawn::BeginPlay() { Super::BeginPlay(); } // Вызывается каждый кадр void AMyPawn::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); } // Вызывается, чтобы связать функциональность для ввода void AMyPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent) { Super::SetupPlayerInputComponent(InputComponent); }
Продолжение урока по ссылке
FTransform::SetScale3D
FTransform::SetScale3D
Изменение масштаба объекта через установку нового значения.
Синтаксис
void SetScale3D ( const FVector & NewScale3D )
Установка Scale3D компонент
Параметры
NewScale3D – новое значение для Scale3D компонента
Рекомендации
Module – core
Header – Runtime/Core/Public/Math/TransformVectorized.h
FObjectInitializer::CreateDefaultSubobject API UE4
FObjectInitializer::CreateDefaultSubobject
Функция объявлена как шаблон.
Первым аргументом передаётся объект, на который опирается система при формировании мира. Объекту можно задать условия при котором он будет содержать в себе свойства скажем “сферы” или “куба”.
Создаёт компонент или подобъект.
template<class TReturnType, class TClassToConstructByDefault> TReturnType * CreateDefaultSubobject ( UObject * Outer, FName SubobjectName, bool bTransient )
Параметры:
Возвращаемый тип – Класс возвращает тип, все переопределения класса должны возвращать тип класса
TClassToConstructByDefault – Класс является конструктором по умолчанию
Outer – внешний конструктор это подобъект
SubobjectName – новое имя компонента
bTransient – TRUE если компонент переходит в свойство.
Пример кода
AMyStaticMeshActor::AMyStaticMeshActor(const FObjectInitializer& ObjectInitializer) { //Make our mesh component (named 'MyMesh') and set it up to be our root component MyMesh = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this,TEXT("MyMesh")); RootComponent = MyMesh; }
Рекомендации(References)
Module – CoreUObject
Header – Runtime/CoreUObject/Public/UObject/UObjectGlobals.h
Actors в Unreal Engine программирование на C++
Actors – Это элемент который можно разместить на уровне. Являясь основным классом предметов, он поддерживает различные преобразования, такие как:перемещение, масштабирование и вращение. AActor является базовым классом который можно создать как через блюпринты и программный код, так и и уничтожить таким же способом.
Есть несколько видов актёров, включающие в себя StaticMeshActor, CameraActor, и PlayerStartActor.
Actors не хранит в корневом элементе метод и своиства трансформации, такие как: (местоположение, вращение и масштабирование).
Создание Actor
Создание нового экземляра Actor происходит методом наследования вызова spawning
AActor* UWorld::SpawnActor ( UClass* Class, FName InName, FVector const* Location, FRotator const* Rotation, AActor* Template, bool bNoCollisionFail, bool bRemoteOwned, AActor* Owner, APawn* Instigator, bool bNoFail, ULevel* OverrideLevel, bool bDeferConstruction )
Components(Компоненты)
Actor можно рассматривать как объект содержащий в себе вызова различных компонентов. Различные типы компонентов можно использовать для передвижения и манипуляции объектом. Основной функцией компонентов является репликация и сетевой вызов во время игры.
Некоторые из ключевых компонентов:
UActorComponent – базовый компонент. Его можно вызвать в методе Tick
USceneComponent – Компонент для управления физикой объекта, передвижения и взаимодействия с другими объектами. Можно так же собирать в некую иерархическую структуру.
UPrimitiveComponent – Этот компонент предназначен больше для взаимодейтсвия с другими объектами. большинство физики и взаимодействия создаётся здесь.
Actor поддерживает иерархию в SceneComponents. Каждый компонент поддерживате корневой элемент который является в своём роде основным компонентом. Актёры сами по себе не могут быть преобразованными и не могут изменить свой вес, местоположение или повернуться. Для этого этим управляют через компоненты, если быть точнее из корневого компонента. Этим компонентом является SceneComponent.
Пример иерархии может выглядеть так:
- Root – SceneComponent: Базовый компонент в котором установлена местоположение объекта
- StaticMeshComponent – сетка представляющая золотую руду
- ParticleSystemComponent игристый излучатель исходящий из золотой руды
- AudioComponent – цикл мелодий звона металлического звучания
- BoxComponent – окно коллизии использующее для сбора золотопри определённом событии.
- StaticMeshComponent – сетка представляющая золотую руду
Ticking (циклически повторяющееся событие)
Ticking – это событие которое повторяется каждый кадр и необходимое для проведения расчётов по отношению к объекту для изменения действия.
Все актёры имеют возможность вызывать TickActor()
ActorComponents имеют возможность обновления по умолчанию
Lifecycle (жизненный цикл)
Смотреть здесь:
Replication (Репликация)
Репликация необходима для поддержки сети, например при сетевом взаимодействии клиентов в многопользовательской игре.
Ссылка на оригинал статьи docs.unrealengine.com
Введение в C ++ Программирование на UE4 2 часть
Введение в C ++ Программирование на UE4 1 часть
Перевод начинается с (Gameplay Classes: Objects, Actors, and Components) ссылка
Классы геймплея: предметы, актёры, компоненты.
В Unreal Есть 4 основных класса которые вы будете использовать постоянно, это UObject, AActor, UActorComponent, и UStruct. Каждый блок описан в разделах ниже. Конечно можно создавать свои блоки, но тогда они не будут участвовать в движке. Простое создание классов которые создаются за пределами ираркии это UObject
Unreal Objects (UObject) (Unreal Объекты)
Базовая структура движка Unreal Вызывает UObject. Этот класс в сочитании с классом UClass предоставляет ряд важных базовых сервисов движка:
- Reflection of properties and methods (Отражение своиств и методов)
- Serialization of properties (Сериализация своиств)
- Garbage collection (Очистка коллекций)
- Finding UObjects by name (Поиск объектов по имени)
- Configurable values for properties (Конфигурация значений для свойств)
- Networking support for properties and methods (Поддержка методов и свойтсв для сети)
Каждый класс являющийся производным от UObject создаёт синглтон UClass контейнер который содержт все данные о экземпляре класса. UObject и UClass отвечают за работу объекта за всё время существования объекта во время геймплея. Разница между UClass и UObject заключается в том, что UClass описывает как будет выглядеть экземпляр класса UObjects и какие своиства доступны для сериализации, взаимодействия и так далее. Вам не обязательно знать какие детали UClass/UObject работы, при написани игрового кода, но знать о существовании таких классов необходимо.
AActor (Актёр)
AActor предназначен для того что-бы быть частью игрового процесса. AActor либо помещаются дизайнером при создании уровня или создаются в геймплей системе при работе геймплей системы. Все объекты которые создаются на игровом уровне унаследованы от этого класса. Например такие классы как AStaticMeshActor, ACameraActor и APointLight. AActor наследуется от UObject и использует весь стандартный функционал описанный в прошлом разделе. AActors может быть уничтожен с помощью кода в С++ или в Blueprint, а так же стандартным сборщиком мусора (деструктор). AActor отвечает за поведение объектов во время игры. AActor так же является базовым типом который можно реплицировать в течении игры по сети. При репликации, AActor может распространять информацию о всех компонентах UActorComponents которые принадлежат AActor требующие поддержку сети.
AActors имеет свои собственные модели поведения (которые наследуются), но они так же выступают в качестве контейнера для иерархий UActorComponents. Делается это с помощью RootComponent который является членом AActor’s и который в свою очередь содержит UActorComponent и может содержать множество других объектов. Перед тем как AActor вы разместите на уровне, он должен содержать USceneComponent , который должен содержать информацию о вращении, масштабе, координатах расположения для AActor. Кто не понял приведу на английском
This is done through the AActor’s RootComponent member, which contains a single UActorComponent that, in turn, can contain many others. Before an AActor can be placed in a level, that AActor must contain at least a USceneComponent which contains the translation, rotation, and scale for that AActor.
AActors содержит ряд событий которые вызываются в течении всего жизненного цикла AActor:
- BeginPlay – вызывается при первом появлении объекта в игровом движке
- Tick – вызывается каждый кадр, при геймплее
- EndPlay – вызывается когда объект покидает игровое поле.
Познакомиться со всеми Actors можно детально по ссылке на английском
Runtime Lifecycle(жизненный цикл)
Создание актёра достаточно сложный процесс. Первоначально должны быть загружены все своиства , такие как расположение актёра, вращение и так далее. Должна проёти первоначальная регистрация всех компонентов. Создание актёров идёт через порождение объекта AActor. Физика движка должна знать о том что произойдёт после создания. За порождение актёра отвечает UWorld::SpawnActor().После создания актёра вызывается метод BeginPlay() , а следом вызывается Tick().
После того как актёр выполнил свою работу, его можно уничтожить вызовом Destroy(). При выполнении этого процесса будет вызван метод EndPlay() где можно задать пользовательскую логику. Ещё один вариант уничтожения является задание времени жизни текущего актёра через контролер и объект так же будет уничтожен через Destroy().
UActorComponent
UActorComponents имеет свои собственные модели поведения и как правило отвечает за функциональность, которая совместно используется с AActors, например предоставление визуальных сетки, эффекты частиц, перспективы камеры, и физика взаимодействий. В то время как AActors даёт низкоуровневое связывание всех ролей в вашей игры, UActorComponents как правило выполняет индивидуальные задачи, которые поддерживаются на высоком уровне. Компоненты можно прикрепить к другим компонентам или может быть корнем компонентам Actor. Компоненты можно прикрепить только к одному родительскому компоненту, тогда как Actor может иметь много дочерних компонентов являясь родителем.
- RootComponent – Это член AActor который является компонентом высокого уровня и содержит в себе дерево других компонентов
- Ticking – это компоненты которые являются частью наследуемого AActor’s Tick()
Анализируем персонаж от первого лица
Что бы проанализировать и понять принцип взаимодействия AActor и UActorComponents давайте посмотрим в blueprint в шаблоне от первого лица, который есть при создании проекта. На рисунке ниже показано дерево компонентов для FirstPersonCharacter. Корневым компонентом является CapsuleComponent. К CapsuleComponent прикреплён ArrowComponent, Mesh компонент, и FirstPersonCameraComponent (камера от первого лица). В свою очередь у Mesh1P родителем является FirstPersonCameraComponent.
Визуально на рисунке ниже можно наблюдать как в 3д пространсте распологаются и выглядят компоненты, за исключением компонента Mesh.
Это дерево компонентов присоединено к одному классу actor. Используя наследование можно наследовать и настроить существующие классы AActor или UActorComponent. Так же на текущем примере вы можете создавать сложные уровни наследуя классы или используя паттерн композиция, подключая другие классы.
UStruct
При использовании UStruct, вы не можете наследовать какой то класс, вы просто должны отметить должны отметить структуру с USTRUCT() и ваши тулзы при сборке проекта будут делать основную работу за вас.
Unlike a UObject, UStructs are not garbage collected. If you create dynamic instances of them, you must manage their lifecycle yourself. UStructs are meant to be plain old data types that have the UObject reflection support for editing within the Unreal Editor, Blueprint manipulation, serialization, networking, etc.
Unreal Reflection System(Unreal рефлексия)
Классы геймплея используют специальную разметку, позволяющую реализовать собственный сборщик муссора, сериализацию, поддержку сети и так далее.Особенности выбора гарантируют то что Unreal правильно обработает ваши типы и функции и не проигнорирует их при сборке проекта.
- UCLASS() сообщает Unreal, что тот должен сгенерировать данные для отражения класса, который в свою очередь является производным от UObject
- STRUCT() -говорит Unreal, что должны быть сгенерированы данные для структуры.
- GENERATED_BODY() – заменяет шаблонный код
- UPROPERTY()
- UFUNCTION()
Не до переведена
Введение в C ++ Программирование на UE4 -1 часть
Данный перевод является вольным переводом страницы по документации Unreal 4.Я не гарантирую что он на 100% подойдёт или будет корректным. В первую очередь я перевожу для себя с целью изучить данный движек, который я считаю лучшим среди существующих на текущий момент времени.
Спасибо за понимание.
Баг в unrial engine
При создании проекта в вложенных папках, папка не должна иметь отличительное от английского. Эта рекомендация не относится если проект создаётся на блюпринтах, а только относится к С++.
VS просто не сможет стартануть.
Баг заметил в VS2013 и UE4.9.*
Да, и UE4.* -UE4.10 не поддерживают vs2015 до UE.11.*
Запрос на получения последних сообщений в MYSQL в личной переписке пользователей
Есть две таблица:
Таблица с личными сообщениями
CREATE TABLE IF NOT EXISTS `messages` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'message_id', `user_in` int(11) NOT NULL COMMENT 'user who sended message', `user_out` int(11) NOT NULL COMMENT 'user who ged message', `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '"1" if new message', `img` text, `msgtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `sign` int(11) NOT NULL, `foreign_key` int(11) NOT NULL, `message` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=258 ;
И таблица с пользователями
-- -- Структура таблицы `user` -- CREATE TABLE IF NOT EXISTS `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(256) COLLATE utf8_bin NOT NULL, `email` varchar(256) COLLATE utf8_bin NOT NULL, `url` varchar(256) COLLATE utf8_bin NOT NULL, `phone` varchar(256) COLLATE utf8_bin NOT NULL, `img` text COLLATE utf8_bin NOT NULL, `role` int(2) NOT NULL, `password` varchar(256) COLLATE utf8_bin NOT NULL, `password_reset_token` varchar(256) COLLATE utf8_bin NOT NULL, `password_reset_time` int(10) NOT NULL, `discounts_stain_roof` int(2) NOT NULL, `discounts_paint` int(2) NOT NULL, `discounts_parts` int(2) NOT NULL, `work_time` varchar(256) COLLATE utf8_bin NOT NULL, `type` int(11) NOT NULL, `about` text COLLATE utf8_bin NOT NULL, `pricefree` text COLLATE utf8_bin NOT NULL, `address` varchar(256) COLLATE utf8_bin NOT NULL, `geo` point NOT NULL, `status` int(1) NOT NULL, `properties` varchar(256) COLLATE utf8_bin NOT NULL, `oauth_yandex` varchar(126) CHARACTER SET utf8 DEFAULT NULL, `oauth_google` varchar(126) CHARACTER SET utf8 DEFAULT NULL, `oauth_vkontakte` varchar(126) CHARACTER SET utf8 DEFAULT NULL, `oauth_facebook` varchar(126) CHARACTER SET utf8 DEFAULT NULL, `oauth_twitter` varchar(126) CHARACTER SET utf8 DEFAULT NULL, `oauth_odnoklassniki` varchar(126) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `pricefree` (`pricefree`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Нобходимо вывести список последних сообщений и пользователей с которыми ведёт переписку один из пользователей.
Так же необходимо чтобы в запросе присутствовали аваторки пользователей и изображения.
Дамп базы данных для запросов
-- -- Дамп данных таблицы `messages` -- INSERT INTO `messages` (`id`, `user_in`, `user_out`, `status`, `img`, `msgtime`, `sign`, `foreign_key`, `message`) VALUES (222, 302, 311, 1, 'a:2:{s:5:"domen";a:1:{i:0;s:28:"http://img.uber/user/2015/08";}s:6:"images";a:1:{i:0;s:36:"3ad7a25ae403e89ce8803e0c7c15d2b7.jpg";}}', '2015-08-26 06:10:52', 1, 0, '3'), (223, 302, 311, 2, 'a:2:{s:5:"domen";a:1:{i:0;s:28:"http://img.uber/user/2015/08";}s:6:"images";a:1:{i:0;s:36:"3ad7a25ae403e89ce8803e0c7c15d2b7.jpg";}}', '2015-08-26 17:11:37', 1, 0, 'рутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт заявка на ремонт\n14:07\nКрутецкий автосервис\nОтправлена заявка на ремонт'), (224, 223, 311, 1, NULL, '2015-08-26 13:42:05', 0, 0, 'ads fasdf asd fasd fasd'), (225, 223, 311, 1, NULL, '2015-08-26 13:42:13', 0, 0, 'ds fasd fasd fdas'), (226, 0, 315, 1, NULL, '2015-08-26 13:45:46', 2, 213, 'Отправлена заявка на ремонт'), (240, 302, 311, 1, NULL, '2015-08-26 16:34:57', 0, 0, 'Соо6'), (241, 302, 311, 1, NULL, '2015-08-26 16:35:11', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (242, 322, 311, 1, NULL, '2015-08-27 06:27:46', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (243, 302, 311, 1, NULL, '2015-08-26 16:36:35', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (244, 311, 225, 1, NULL, '2015-08-27 05:24:38', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (245, 302, 311, 1, NULL, '2015-08-26 16:36:39', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (246, 302, 311, 1, NULL, '2015-08-26 16:36:41', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (247, 302, 311, 1, NULL, '2015-08-26 16:37:06', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (248, 311, 318, 1, NULL, '2015-08-27 06:26:05', 0, 0, 'pСообщение для тестирования чата более 5 символов brp94'), (249, 317, 311, 1, NULL, '2015-08-27 06:25:43', 0, 0, 'Сообщение для тестирования чата более 5 символов'), (250, 302, 311, 1, NULL, '2015-08-26 16:46:27', 0, 0, 'Сообщение для тестирования чата более 5 символов'), (251, 311, 302, 1, NULL, '2015-08-26 17:08:14', 0, 0, 'Сообщение для тестирования чата более 5 символов'), (252, 302, 311, 2, NULL, '2015-08-26 17:08:06', 0, 0, 'Сообщение для тестирования чата более 5 символов'), (253, 302, 311, 1, NULL, '2015-08-26 16:46:50', 0, 0, 'Сообщение для тестирования чата более 5 символов'), (254, 302, 311, 0, NULL, '2015-08-27 06:08:53', 0, 0, 'echo string\n echo string'), (255, 225, 311, 0, NULL, '2015-08-26 17:19:10', 0, 0, 'echo string\n echo string\n echo string'), (256, 225, 311, 0, NULL, '2015-08-26 17:19:46', 0, 0, '225225225225'), (257, 225, 311, 0, NULL, '2015-08-26 17:19:54', 0, 0, '225225225225'); -- -- Дамп данных таблицы `user` -- , (311, 'Кон', 'ko7657su', '', 'a:1:{i:0;s:10:"8955256658";}', 'a:4:{s:4:"home";a:5:{i:0;i:0;i:1;i:0;i:2;i:0;i:3;i:0;i:4;i:0;}s:3:"img";a:5:{i:0;s:73:"http://img.uber/user/2015/08/166_126/4a99fd3348a02f28b8fdb842082087e1.jpg";i:1;s:73:"http://img.uber/user/2015/08/166_126/c8d6208ad68f5fa0f84b10b21db1b597.jpg";i:2;s:73:"http://img.uber/user/2015/08/166_126/032a51b688c62878b18c7d57f1f27350.jpg";i:3;s:73:"http://img.uber/user/2015/08/166_126/ba3850d4b16d237a553df2c3ebfcf113.jpg";i:4;s:73:"http://img.uber/user/2015/08/166_126/6375adc86492440b407a58316d410d37.jpg";}s:9:"img_domen";a:5:{i:0;s:21:"img.uber/user/2015/08";i:1;s:21:"img.uber/user/2015/08";i:2;s:21:"img.uber/user/2015/08";i:3;s:21:"img.uber/user/2015/08";i:4;s:21:"img.uber/user/2015/08";}s:8:"img_name";a:5:{i:0;s:36:"4a99fd3348a02f28b8fdb842082087e1.jpg";i:1;s:36:"c8d6208ad68f5fa0f84b10b21db1b597.jpg";i:2;s:36:"032a51b688c62878b18c7d57f1f27350.jpg";i:3;s:36:"ba3850d4b16d237a553df2c3ebfcf113.jpg";i:4;s:36:"6375adc86492440b407a58316d410d37.jpg";}}', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (313, 'Констанв', 'inf3o@y567.ru', '', 'b:0;', 'a:3:{s:5:"domen";a:1:{i:0;s:56:"https://pp.vk.me/c319625/v319625100/3ae5/MkxbxZtS3l8.jpg";}s:3:"img";a:1:{i:0;s:56:"https://pp.vk.me/c319625/v319625100/3ae5/MkxbxZtS3l8.jpg";}s:4:"sign";a:1:{i:0;s:9:"vkontakte";}}', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 0, '', '', '', '', 1, '', NULL, NULL, '15960610031', NULL, NULL, NULL), (314, 'Рандомное Контактное имя 68800', 'abcdef17230@80047testuser.ru', '', 'a:2:{i:0;s:9:"960206552";i:1;s:9:"901322924";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '960206552', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (315, 'Рандомное Контактное имя 89947', 'abcdef33885@12807testuser.ru', '', 'a:2:{i:0;s:9:"846378350";i:1;s:9:"904651243";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '846378350', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (302, 'Рандомное Контактное имя 68176', 'abcdef53346@70096testuser.ru', '', 'a:2:{i:0;s:9:"922580966";i:1;s:9:"973964714";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '922580966', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (317, 'Рандомное Контактное имя 67895', 'abcdef38033@13426testuser.ru', '', 'a:2:{i:0;s:9:"908888374";i:1;s:9:"905518470";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '908888374', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (318, 'Рандомное Контактное имя 22506', 'abcdef8520@83592testuser.ru', '', 'a:2:{i:0;s:9:"950258012";i:1;s:9:"829869552";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '950258012', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (319, 'Рандомное Контактное имя 86045', 'abcdef38635@40598testuser.ru', '', 'a:2:{i:0;s:9:"945582042";i:1;s:9:"903580492";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '945582042', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (320, 'Рандомное Контактное имя 83427', 'abcdef65029@49539testuser.ru', '', 'a:2:{i:0;s:9:"990326823";i:1;s:9:"860306539";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '990326823', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (321, 'Рандомное Контактное имя 11817', 'abcdef64799@71488testuser.ru', '', 'a:2:{i:0;s:9:"999483053";i:1;s:9:"873676255";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '999483053', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (322, 'Рандомное Контактное имя 47635', 'abcdef42573@28317testuser.ru', '', 'a:2:{i:0;s:9:"886465123";i:1;s:9:"904100595";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '886465123', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (323, 'Рандомное Контактное имя 76719', 'abcdef7105@74431testuser.ru', '', 'a:2:{i:0;s:9:"946038479";i:1;s:9:"869544521";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '946038479', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (324, 'Рандомное Контактное имя 80570', 'abcdef74810@19703testuser.ru', '', 'a:2:{i:0;s:9:"829361810";i:1;s:9:"815513959";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '829361810', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (325, 'Рандомное Контактное имя 43421', 'abcdef28180@43623testuser.ru', '', 'a:2:{i:0;s:9:"969695712";i:1;s:9:"827652140";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '969695712', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (326, 'Рандомное Контактное имя 7289', 'abcdef49770@13367testuser.ru', '', 'a:2:{i:0;s:9:"940780431";i:1;s:9:"869285235";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '940780431', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (327, 'Рандомное Контактное имя 2152', 'abcdef18269@23022testuser.ru', '', 'a:2:{i:0;s:9:"876329192";i:1;s:9:"889154022";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '876329192', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (225, 'Рандомное Контактное имя 16473', 'abcdef15387@17321testuser.ru', '', 'a:2:{i:0;s:9:"822223607";i:1;s:9:"988998128";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '822223607', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (223, 'Рандомное Контактное имя 50087', 'abcdef97164@41165testuser.ru', '', 'a:2:{i:0;s:9:"812804591";i:1;s:9:"937684902";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '812804591', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (330, 'Рандомное Контактное имя 15469', 'abcdef92967@71693testuser.ru', '', 'a:2:{i:0;s:9:"999676836";i:1;s:9:"905451402";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '999676836', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (331, 'Рандомное Контактное имя 2138', 'abcdef30480@15060testuser.ru', '', 'a:2:{i:0;s:9:"853802881";i:1;s:9:"940295122";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '853802881', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (332, 'Рандомное Контактное имя 79731', 'abcdef74478@62063testuser.ru', '', 'a:2:{i:0;s:9:"912541550";i:1;s:9:"847577032";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '912541550', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (333, 'Рандомное Контактное имя 64452', 'abcdef2602@71965testuser.ru', '', 'a:2:{i:0;s:9:"824112203";i:1;s:9:"947048871";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '824112203', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (334, 'Рандомное Контактное имя 91863', 'abcdef69976@77725testuser.ru', '', 'a:2:{i:0;s:9:"825539052";i:1;s:9:"994295389";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '825539052', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (335, 'Рандомное Контактное имя 57183', 'abcdef86008@88097testuser.ru', '', 'a:2:{i:0;s:9:"999264449";i:1;s:9:"997485114";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '999264449', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (336, 'Рандомное Контактное имя 37467', 'abcdef17135@21013testuser.ru', '', 'a:2:{i:0;s:9:"835603281";i:1;s:9:"995571226";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '835603281', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (337, 'Рандомное Контактное имя 96952', 'abcdef59584@87089testuser.ru', '', 'a:2:{i:0;s:9:"826826465";i:1;s:9:"990040807";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '826826465', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (338, 'Рандомное Контактное имя 91861', 'abcdef34868@56251testuser.ru', '', 'a:2:{i:0;s:9:"827363824";i:1;s:9:"815790125";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '827363824', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (339, 'Рандомное Контактное имя 39259', 'abcdef63493@78490testuser.ru', '', 'a:2:{i:0;s:9:"906194526";i:1;s:9:"952331291";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '906194526', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (340, 'Рандомное Контактное имя 18329', 'abcdef96210@19756testuser.ru', '', 'a:2:{i:0;s:9:"897965740";i:1;s:9:"914696686";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '897965740', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (341, 'Рандомное Контактное имя 36707', 'abcdef82177@13737testuser.ru', '', 'a:2:{i:0;s:9:"947296311";i:1;s:9:"972736066";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '947296311', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (253, 'Рандомное Контактное имя 17378', 'abcdef12254@67409testuser.ru', '', 'a:2:{i:0;s:9:"933453206";i:1;s:9:"961035239";}', 'a:3:{s:5:"domen";a:1:{i:0;s:56:"https://pp.vk.me/c319625/v319625100/3ae5/MkxbxZtS3l8.jpg";}s:3:"img";a:1:{i:0;s:56:"https://pp.vk.me/c319625/v319625100/3ae5/MkxbxZtS3l8.jpg";}s:4:"sign";a:1:{i:0;s:9:"vkontakte";}}', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '933453206', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (343, 'Рандомное Контактное имя 63913', 'abcdef51328@88073testuser.ru', '', 'a:2:{i:0;s:9:"865515720";i:1;s:9:"894967846";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '865515720', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (344, 'Рандомное Контактное имя 2721', 'abcdef85295@34349testuser.ru', '', 'a:2:{i:0;s:9:"843192058";i:1;s:9:"869856905";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '843192058', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (345, 'Рандомное Контактное имя 9032', 'abcdef79577@31504testuser.ru', '', 'a:2:{i:0;s:9:"820310369";i:1;s:9:"888735893";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '820310369', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (346, 'Рандомное Контактное имя 93298', 'abcdef49075@38593testuser.ru', '', 'a:2:{i:0;s:9:"866924240";i:1;s:9:"887307730";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '866924240', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (347, 'Рандомное Контактное имя 3672', 'abcdef3754@11091testuser.ru', '', 'a:2:{i:0;s:9:"869387126";i:1;s:9:"852079826";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '869387126', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (348, 'Рандомное Контактное имя 58056', 'abcdef59048@15428testuser.ru', '', 'a:2:{i:0;s:9:"863520591";i:1;s:9:"870831539";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '863520591', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL), (349, 'Рандомное Контактное имя 26495', 'abcdef72834@61101testuser.ru', '', 'a:2:{i:0;s:9:"872873295";i:1;s:9:"858861165";}', '', 1, '263fec58861449aacc1c328a4aff64aff4c62df4a2d50b3f207fa89b6e242c9aa778e7a8baeffef85b6ca6d2e7dc16ff0a760d59c13c238f6bcdc32f8ce9cc62', '', 0, 0, 0, 0, '', 1, '872873295', '', '', '', 0, '', NULL, NULL, NULL, NULL, NULL, NULL);
Ответ:
Если мы ищем всех пользователей с которыми общался пользователь 311
SELECT * from ( SELECT messages.id mes_id, messages.msgtime, IF( messages.user_out = 311, messages.user_in, messages.user_out) `userid`, IF( messages.user_out = 311, u_in.name, u_out.name ) name, IF( messages.user_out = 311, u_out.img, u_in.img) as `avatar`, IF( messages.user_out = 311, u_out.role,u_in.role) as `role`, messages.message FROM `messages` LEFT JOIN `user` `u_in` ON messages.user_in = u_in.id LEFT JOIN `user` `u_out` ON messages.user_out = u_out.id WHERE (`messages`.`user_out`=311) OR (`messages`.`user_in`=311) ORDER BY `messages`.`id` DESC) data group by `userid`
Unit тесты проверка значений
Написание Unit тестоя является очень хорошей практикой при поддержке, рефакторинге и форматировании кода.
Постоянно приходится искать примеры проверки значений про написании тестов. Здесь я хочу привести основной функционал при написнии тестов.
1) assertTrue – Проверка на существование переменной
assertTrue($val,$messages)
$val – переменная
$messages – сообщение при ошибке.
2) assertSame – Проверка на ожидаемое значение
assertSame($val1,$val2,$messages)
$val1 – ожидаемое значение
$val2 – текущее значение
$messages – сообщение которое появится во время появления ошибки
Если $val1 $val2 это INT я советую сделать так assertSame((int)$val1, (int)$val2, $messages)