-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAdditiveUiViewController.cs
More file actions
84 lines (75 loc) · 4.58 KB
/
AdditiveUiViewController.cs
File metadata and controls
84 lines (75 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using VContainer;
namespace MyGame
{
// Интерфейс для использования в соответствующем Presenter
public interface IAdditiveUiViewController
{
AdditiveScenePresenter Presenter { get; set; }
void SetSpecText(string text);
}
public class AdditiveUiViewController : MonoBehaviour, IAdditiveUiViewController
{
// Так не будет работать потому, что у нас presenter должен создаваться фабрикой,
// а стандартный механизм не знает где достать значения параметров для фабрики.
// [Inject]
// Ещё одна особенность, которую нужно решить - на стороне presenter интерфейс должен
// быть WeakReference, чтобы позволить Unity удалить элемент из памяти.
private AdditiveScenePresenter presenter;
string sceneName;
AdditiveScenePresenter IAdditiveUiViewController.Presenter
{
get => presenter;
set
{
presenter = value;
// Не удаляем имя сцены после первого успешного определения. См. OnDestroy
sceneName = presenter?.sceneName ?? sceneName;
}
}
public Text specText;
// Сегрегируем функционал, используя общий контекст MonoBehaviour
void IAdditiveUiViewController.SetSpecText(string text)
{
specText.text = text;
}
// Use this for initialization
void Start()
{
// Статичный метод GameObject.Find не работает при одинаково загружаемых сценах одновременно
// и не очень хорошо работает, когда надо заменить одну сцену на другую, у которых могут пересекаться объекты по имени и тэгу.
// Можно сделать моно-"сундучок" и все необходимые ссылки, которые нужно быстро
var rgoArray = this.gameObject.scene.GetRootGameObjects();
foreach (GameObject go in rgoArray)
{
// Вот поэтому и должно быть в начальной сцене мало корневых объектов.
// Даже можно какие-то игровые области, если их немного, формировать в корне сцены, а все остальные как дочерние.
// Если областей много, то лучше их располагать под каким-то общим "пустым" объектом, выравненным по "нулю"
// с глобальными координатами.
// Можно искать по тэгу. В целом обычный поиск подойдёт, если только одна сцена будет загружена дополнительная,
// но это сильное ограничение стурктуры.
// Можно сформировать компоненту "карта ссылок", навесить на объект с компонентой области видимости (LifetimeScope)
// и использовать его для быстрого получения и проверки всё ли инициализировано, что нужно функционалу сцены.
if (go.name == "Canvas")
{
specText = go.transform.Find("SpecText").GetComponent<Text>();
}
}
presenter.SayHello();
}
void Update()
{
// Размещаем постоянную анимацию дополнения сцены здесь
}
void OnDestroy()
{
// presenter может быть null и поэтому имя сцены нельзя будет получить.
Debug.Log(String.Format("Additive scene '{0}' view controller disposed!", this.sceneName));
this.presenter = null;
}
}
}