相机投影

内容准备

RenderTexture

在Assets问价目录下一个合适的位置创建该内容

image-20240820164227129

UI

这一步需要注意,选用的image必须是Raw Image,这样才会有对应的Texture选项

image-20240820164352886

Camera

场景中需要存在两个相机,一个相机使用该会导致画面只会渲染到之前的给定UI上,窗口主要内容丢失,对于需要使用虚拟相机的场景,建议按照原来的方法创建完成后直接复制原有的Camera(注意不是虚拟相机),在新创建的相机进行下图操作即可。

image-20240820164518550

最终效果

image-20240820164829825

Transform追踪

如该方法的名字所示,最终的效果实现就是在update函数中对指定的Transform改变值进行一个追踪,视频的方法暂且不论,使用FindTag方法在拥有大量对象的场景中会导致地图加载慢,在个人demo中,存在对应的GameEvent系统,可以通过该系统将需要被追踪的对象的数据发送过去

实际代码

image-20240820174912687

image-20240820180447245

image-20240820180559210

这里的disX之前计算的x,disY同理

image-20240820183105219

最为关键的是这个转换操作

注意以下操作,是在UI中移动的关键

1
image.rectlransform.anchoredPosition

下面是在个人项目Light中可以有效使用的MinMap控制代码

依托于自己实现的事件系统,在需要显示在地图上的实体初始化的时候选择合适的事件类型发送即可,不需要去全局查找对应的tag,

建议在事件的发送自start()函数中进行,注册则是在awake()函数,资源加载同样,目前这样使用是可以的

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using Cysharp.Threading.Tasks;
using Light.Assets.Scripts.EventManager;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Light
{
public class MInMapController : MonoBehaviour
{
private Vector2 sizeData = new Vector2(20, 20);

//比例计算的公共vector2
private Vector2 originVector2 = Vector2.zero;

private Vector2 targetVector2 = Vector2.one; //公共v

//准备实例化的数据
private Sprite playerPointSprite;

private Sprite enemyPointSprite;

private Transform player;

private GameObject mapUi;

private GameObject playerPointUI;

//需要跟踪的PlayerTransform
private Transform playerTrasform;

//需要保持的敌人
private List<(Transform, RectTransform)> enemyTransformToObjectDic = new();

private async void Awake()
{
mapUi = transform.Find("Map").gameObject;

playerPointUI = transform.Find("PlayerPoint").gameObject;

EventManager.Register<PlayerRegisterEvent>(OnPlayerRegisterEventHandle);
EventManager.Register<EnemyRegisterEvnet>(OnEnemyRegisterEventHandle);

//加载图标
ResManager.Instance.LoadAsync<Sprite>("RedPoint", (s) =>
{
enemyPointSprite = s;
});
ResManager.Instance.LoadAsync<Sprite>("BluePoint", (s) =>
{
playerPointSprite = s;
},LoadType.AddressAbles);

await UniTask.WaitUntil(() => playerPointSprite != null);
await UniTask.WaitUntil(() => enemyPointSprite != null);

playerPointUI.GetComponent<Image>().sprite = playerPointSprite;
}

private void Start()
{

}

private void Update()
{
PlayerPointMove();

EnemyPointsMove();
}

/// <summary>
/// 按照视频中那点讲解移动就行
/// </summary>
private void EnemyPointsMove()
{
foreach (var item in enemyTransformToObjectDic)
{
float dis = Vector3.Distance(playerTrasform.position, item.Item1.position);
if (dis > 50)
{
item.Item2.gameObject.SetActive(false);
}
else
{
item.Item2.gameObject.SetActive(true);
}

originVector2.x = item.Item1.position.x - playerTrasform.position.x;
originVector2.y = item.Item1.position.y - playerTrasform.position.y;


RatioCalculation();

item.Item2.anchoredPosition = targetVector2;
}
}

/// <summary>
/// 移动map图层
/// </summary>
private void PlayerPointMove()
{
if(playerTrasform == null) return;
originVector2 = playerTrasform.position;
originVector2.y = playerTrasform.position.z;

RatioCalculation();

//mapUi.transform.anchoredPosition = Vector2.zero - targetVector2;
}

/// <summary>
/// 比例换算,地图UI的尺寸设计是200*200,摄像机的范围是50*30,视野半径范围是25,小地图的目的是给玩家提前发现敌人做准备,因此采用比例1 : 2,将地图显示范围拉到50,扩大一倍
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void RatioCalculation()
{
targetVector2 = originVector2 * 2;
}

/// <summary>
/// 对每一个成功注册的敌人进行区分和保存
/// </summary>
/// <param name="event"></param>
private void OnEnemyRegisterEventHandle(EnemyRegisterEvnet @event)
{
Debug.Log("cur--Map记录enemy");


Image image = Instantiate(playerPointUI, mapUi.transform).GetComponent<Image>();

image.sprite = enemyPointSprite;
image.rectTransform.sizeDelta = this.sizeData;
image.gameObject.SetActive(false);


this.enemyTransformToObjectDic.Add((@event.transform, image.rectTransform));
}

private void OnPlayerRegisterEventHandle(PlayerRegisterEvent @event)
{
Debug.Log("cur--Map记录Player");
playerTrasform = @event.transform;
}
}
}

效果

image-20240821162111294