14 Apr 12:09 avatar

Создание C++ плагина для Unity3D

C++ in Unity3D tutorial (C# Marshaling)
www.youtube.com/watch?v=w3jGgTHJoCY

ericeastwood.com/blog/17/unity-and-dlls-c-managed-and-c-unmanaged

www.gamedev.net/articles/programming/general-and-gameplay-programming/c-plugin-debug-log-with-unity-r3349/?tab=comments

www.snowbolt.com/index.php/blog/28-tech/91-pinvoke

www.alanzucconi.com/2015/10/11/how-to-write-native-plugins-for-unity/#step1

  • При создании проекта в VS2017 надо выбирать тип проекта C++ -> библиотека DLL
  • Следить за тем, чтобы была установлена правильная разрядность и Build type — Release
  • Возможно играет роль то, какие параметры установлены для dll в редакторе Unity (зайти в редакторе в папку плагинс кликнуть на длл и проверить в инспекторе параметры)
  • Проекты CallCppFromUnity и CallUnityFromCpp загружены на гугл диск в папку работы с террасой и имеют минимальную функциональность
15 Mar 18:29 avatar

Профайлер в Unity3d

Для далеких из мира Unity3d: Update вызывается каждый кадр! Вместо того, чтобы просто обновить один раз вьюшку, когда модель обновится, мы устраиваем маленький ddos мобильника. И вообще, нужно минимизировать количество Update/FixedUpdate и переходить к event-логике, а еще лучше к конечным автоматам.


23 Jan 02:30 avatar

Preserving Object References

www.newtonsoft.com/json/help/html/PreserveObjectReferences.htm

By default Json.NET will serialize all objects it encounters by value. If a list contains two Person references and both references point to the same object, then the JsonSerializer will write out all the names and values for each reference.

Person p = new Person
 2{
 3    BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
 4    LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
 5    Name = "James"
 6};
 7
 8List<Person> people = new List<Person>();
 9people.Add(p);
10people.Add(p);
11
12string json = JsonConvert.SerializeObject(people, Formatting.Indented);
13//[
14//  {
15//    "Name": "James",
16//    "BirthDate": "1980-12-23T00:00:00Z",
17//    "LastModified": "2009-02-20T12:59:21Z"
18//  },
19//  {
20//    "Name": "James",
21//    "BirthDate": "1980-12-23T00:00:00Z",
22//    "LastModified": "2009-02-20T12:59:21Z"
23//  }
24//]


In most cases this is the desired result, but in certain scenarios writing the second item in the list as a reference to the first is a better solution. If the above JSON was deserialized now, then the returned list would contain two completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a circular reference occurs.

PreserveReferencesHandling
Setting PreserveReferencesHandling will track object references when serializing and deserializing JSON.
24 Dec 13:18 avatar

Good Coding Practices in Unity

It’s not something a lot of new developers to Unity think about, but it’s still an incredibly important topic. It’s about coding practices, and it can make your life much easier.

The idea behind coding practices is that you keep in mind a set of guidelines when you write your code. These guidelines are often designed to keep your code maintainable, extensible, and readable, which in turn helps reduce the pain of refactoring.

How many times have you wanted to change some code in your project, which turned out to be much harder than you thought because there’s a bunch of classes relying on that code – it’s like when you go to unplug your keyboard, and you find that the back of your computer is a horror-inducing tangled mess of cables and there’s almost no hope of picking out just the one.

So, here’s some general guidelines to help you keep code untangled and tidy.

Single Responsibility
A given class should be, ideally, responsible for just one task.

The idea behind Single Responsibility is that each class does its own little task, and then you can solve larger goals by combining these little tasks together. If that sounds like I’m describing components, that’s because the two work perfectly together.

Unity being designed around separation of functionality into reusable parts, Single Responsibility is perhaps the most important principle of the ones I’m going to present in this post.

To give an example of this principle, let’s say we have a Player class. Player handles input, physics, weapons, health, and inventory.

That’s a rather long list of things the Player is responsible for. We should break this into multiple different components that each do just one thing.

PlayerInput – responsible for handling input

PlayerPhysics – responsible for driving physics simulation

WeaponManager – responsible for managing player weapons

Health – responsible for player health

PlayerInventory – responsible for player inventory

Ah, much better. Now, these classes are all largely dependent on each other, and that still poses some issues. Let’s take a look at resolving this.

Dependency Inversion
If a class relies on another class, abstract that reliance.

The idea behind Dependency Inversion is that whenever one class calls into another class, we should replace that call with some kind of abstraction to better insulate the classes from each other.

Most preferable is to replace the class dependence with an interface. So class A instead of calling methods in class B, actually calls methods of ISomeInterface which class B implements.

Another way is to introduce an abstract base class which class B inherits from. So class A treats class B as the base class instead of directly relying on class B itself.

The least preferable reliance, of course, is to have class A directly relying on class B. This is the one we want to avoid.

So in our previous example, those components may have a fairly tight coupling with each other. PlayerInput may rely on the presence of PlayerPhysics, WeaponManager may rely on the presence of Inventory, and so on.

Let’s abstract these.

IActorPhysics – Interface for classes which can accept input and presumably affect physics simulation

IDamageable – Interface for classes which can accept damage

IInventory – Interface for classes which can store and retrieve items

Now our PlayerPhysics implements IActorPhysics, our Health implements IDamageable, and our PlayerInventory implements IInventory.

So then PlayerInput just relies on the presence of some IActorPhysics, WeaponManager relies on the presence of some IInventory, and perhaps something which deals damage to our player relies on the presence of some IDamageable.

Dependency Inversion helps reinforce Single Responsibility to some extent. PlayerInput shouldn’t care how the player moves, nor should it care what is going to move the player. Just that there’s something which promises that functionality.

Another thing to keep in mind is that SendMessage can accomplish the same goals in some cases.

Modularization
I’ve personally seen code like this a lot in Unity:

Copy codeC#
switch( behavior )
{
case 1: // some behavior
case 2: // another behavior
case 3: // yet another behavior
case 4: // the last behavior
}
1
2
3
4
5
6
7
Sure it works, but we can do better. This code is practically screaming to be modularized. Each of those behaviors would be a module, and then “behavior” goes from being an enum or what have you to just being an instance of a module (lets say our module in this case is a delegate, although it could just as easily be a class or struct). So then that code just becomes:

Copy codeC#
behavior();
1
And somewhere else you can assign the current module like:

Copy codeC#
MyClass.behavior = someBehavior;
1
Where presumably someBehavior is a function (or, if our module is a class, an instance of that class, or whatever)

This is particularly useful if we’re making something like a state machine or a menu system. While we could have a big enum of all of the possible states, or of all of the possible menus, etc it makes a lot of sense to have state and menu be modules we can swap in and out. That way, we don’t have to keep adding new entries to the enum, and we don’t have to keep expanding our switch case statement every time we want to add something.

Conclusion
These are not by any means the only coding practices available. But, they are some very important ones to follow.

You don’t always have to follow them – sometimes, it’s just overkill and doesn’t make sense. But, do exercise critical thinking and determine whether your code could benefit from them (chances are, it can). Remember, it’s usually not about saving yourself a few lines of code now – it’s about saving yourself a headache later.

blog.theknightsofunity.com/unitytoolbag-library-overview/
1 Dec 17:15 avatar

Перевод статьи Mastering Unity Project Folder Structure - Version Control Systems

Перевод статьи Mastering Unity Project Folder Structure — Version Control Systems

unity3d.com/ru/learn/tutorials/topics/production/mastering-unity-project-folder-structure-version-control-systems?playlist=17117
9 Nov 00:10 avatar

Работа с Unity UI

habrahabr.ru/post/248273/

xgm.guru/p/unity/ui-manual

docs.unity3d.com/ru/520/Manual/HOWTO-UIMultiResolution.html

docs.unity3d.com/ru/520/Manual/HOWTO-UICreateFromScripting.html

sgteam.ru/%D0%BA%D1%80%D1%83%D1%87%D1%83-%D0%B2%D0%B5%D1%80%D1%87%D1%83-%D0%B7%D0%B0%D0%BF%D1%83%D1%82%D0%B0%D1%82%D1%8C-%D1%85%D0%BE%D1%87%D1%83-%D1%83%D0%B3%D0%BB%D1%8B-%D1%8D%D0%B9%D0%BB%D0%B5%D1%80%D0%B0/

www.youtube.com/watch?v=gqLmoKpeWhQ
Элементы интерфейса по-умолчанию привязаны к центру родительского прямоугольника. 
Данное означает что они сохраняют постоянное смещение относительно центра.

Если с данной настройкой разрешение было изменено под альбомное соотношение сторон, кнопки могут выпасть из своих прямоугольных областей, где они изначально должны были быть расположены.Одним из способов сохранить расположение кнопок в области экрана является изменение компоновки таким образом, чтобы места их расположения были связаны с их соответствующими углами на экране. Привязка левой верхней кнопки может быть также установлена в левом верхнем углу при использовании в инспекторе выпадающего списка Anchors Preset (наборы привязок), или путём перетаскивания треугольных ручек привязок в видовом окне сцены (Scene View). Лучше сделать это пока текущее разрешение экрана, установленное в игровом режиме (Game View) является тем разрешением, для которого изначально всё и было задумано, где места расположения кнопок были бы подобраны более разумно и как говориться к месту.(Ознакомьтесь со страницей UI Basic Layout для получения более подробной информации по привязкам.). 
Так же например привязки для левой нижней и правой нижней кнопок могут быть выставлены в левый нижний и правый нижний угол соответственно.

Как только кнопки были привязаны к своим углам, то при дальнейших изменениях разрешений экрана и соотношений сторон они будут сохранять свою позиции относительно этих углов.










Thread {
    try {
      val user = githubApi.user()
      userRepository.store(user)
      handler.post {
        threadsTV.text = "threads: [$user]"
      }
    } catch(e: IOException) {
      handler.post {
        threadsTV.text = "threads: [User retrieval failed.]"
      }
    }
  }.start()
1 Oct 02:02 avatar

Реализуем перемещение объектов во время выполнения как в редакторе (Unity 3d runtime transform gizmos). Часть 1.

Данной статьей начинается цикл о создании гизмо, пригодных к использованию во время выполнения unity-приложения