Не знаю считается ли это уроком, но все же. Наверное почти все видели 3d рендеры браузеров в игре на телевизорах, что выглядит довольно таки круто и вполне интересно для ваших игроков.
Решил сделать себе на коленке такое же оставлю копию тут (Код хромает не ругайтесь)0)
Первое создаем класс Browser и наследуем ему Scripts, после вставляем данный код p.s оставил пару команд для того чтоб вы могли сразу посмотреть на результат
Далее создаем класс BrowserModel и вставляем в его следующее
И так же нам нужен browser.js и в него мы вставляем этот код
Вуаля у нас есть телевизор, но есть несколько нюансов, о которых вам нужно знать.
1. Это качество изображений на объектах, на большинстве объектов качество хромает и это не поправить об этом сказал сам Георг (Владелец рейджа)
2. К сожалению данный браузер нельзя синхронизировать в явном нам понимании. Так что придется пользоваться прямыми трансляциями это единственный известный мне вариант.
3. Все объекты на которых можно рендерить можно найти тут => https://wiki.rage.mp/index.php?title=Render_Targets
4. Есть нюансы при использовании, на одном объекте одного типа можно назначить только один браузер
То есть если я создам два телевизора prop_x17dlc_monitor_wall_01a, и задам им разные ссылки рендер будет навешивать один и тот же браузер на каждый из них при пуше новой ссылки на один из телевизоров.
Далее по функционалу кода.
createobj - Создаст объект телевизора
updaterender - Команда не описывает её действия, но тем не менее дает возможность отключить/включить рендер данного браузера.
pushurl - Задаст новую ссылку на рендер для выбранного командой объекта. (Над каждым телевизором будет видеть информация о нем, видно на скрине)
removeobj - Удаляет телевизор
Вроде бы все код работает 100 из 100, если будут проблемы или будут предложения по улучшению прошу в комментарии
P.s И да если это может идти в конкурс который вроде еще не закончился было бы здорово)0|
UPD: Если у вас браузер перевернут, на клиенте в функции RenderThings замените строчку
mp.game.graphics.drawSprite(browser.headlessTextureDict, browser.headlessTextureName, 0.5, 0.5, 1, -1, 0, 255, 255, 255, 255, true);
На это mp.game.graphics.drawSprite(browser.headlessTextureDict, browser.headlessTextureName, 0.5, 0.5, 1, 1, 0, 255, 255, 255, 255, true);
И все должно быть гуд
Решил сделать себе на коленке такое же оставлю копию тут (Код хромает не ругайтесь)0)
Первое создаем класс Browser и наследуем ему Scripts, после вставляем данный код p.s оставил пару команд для того чтоб вы могли сразу посмотреть на результат
C#:
private readonly List<BrowserModel> _objects = new();
// /createobj prop_x17dlc_monitor_wall_01a xm_prop_x17dlc_monitor_wall_01a
// /createobj prop_x17_tv_scrn_12 xm_prop_x17_tv_scrn_12
// /pushurl 0 https://www.youtube.com/watch?v=dQw4w9WgXcQ
[Command("createobj")]
public void CreateObject(Player player, string name, string model)
{
var objectData = NAPI.Object.CreateObject(NAPI.Util.GetHashKey(model), player.Position, player.Rotation, 255, player.Dimension);
var data = new BrowserModel(objectData.Id, objectData, name, model)
{
Url = "",
Active = true
};
_objects.Add(data);
objectData.SetSharedData("ServerObject", data);
}
[Command("updaterender")]
private void _offTvRender(Player player, int id)
{
var objectData = _objects.FirstOrDefault(x => x.Id == id);
if (objectData == null)
{
player.SendChatMessage("Object not found!");
return;
}
objectData.Active = !objectData.Active;
objectData.Object.SetSharedData("ServerObject", objectData);
}
[Command("pushurl")]
private void _pushUrl(Player player, int id, string url)
{
var objectData = _objects.FirstOrDefault(x => x.Id == id);
if (objectData == null)
{
player.SendChatMessage("Object not found!");
return;
}
objectData.Url = url;
objectData.Object.SetSharedData("ServerObject", objectData);
}
[Command("removeobj")]
private void _deleteObject(Player player, int id)
{
var objectData = _objects.FirstOrDefault(x => x.Id == id);
if (objectData == null)
{
player.SendChatMessage("Object not found!");
return;
}
objectData.Active = false;
objectData.Object.SetSharedData("ServerObject", objectData);
NAPI.Task.Run(() =>
{
objectData.Object.Delete();
_objects.Remove(objectData);
}, 250);
_objects.Remove(objectData);
}
Далее создаем класс BrowserModel и вставляем в его следующее
C#:
public ushort Id { get; set; }
public Object Object { get; set; }
public string ObjectName { get; set; }
public string ObjectModel { get; set; }
public string Url { get; set; } ;
public bool Active { get; set; };
public BrowserModel()
{
}
public BrowserModel(ushort id, Object obj, string objectName, string objectModel)
{
Id = id;
Object = obj;
ObjectName = objectName;
ObjectModel = objectModel;
}
И так же нам нужен browser.js и в него мы вставляем этот код
JavaScript:
let player = mp.players.local;
mp.events.add("render", () =>
{
renderObject();
})
let renderBrowsers = new Map();
function renderObject()
{
mp.objects.forEachInRange(player.position, 30, (obj) =>
{
let serverData = obj.getVariable("ServerObject");
if (!serverData) return;
mp.game.graphics.drawText(`Телевизор ${obj.remoteId } [${serverData.Url}]`, [obj.position.x, obj.position.y, obj.position.z + 2], {
font: 0,
color: [255, 255, 255, 185],
scale: [0.20, 0.20],
outline: true
});
let browser = renderBrowsers.get(obj.remoteId);
let render = CreateRenderTarget(serverData.ObjectName, serverData.ObjectModel);
if (serverData.Active == false)
{
if (browser != null)
{
browser.destroy();
renderBrowsers.delete(obj.remoteId);
}
return;
}
if (browser == null)
{
renderBrowsers.set(obj.remoteId, mp.browsers.newHeadless(serverData.Url, 1920, 1080, false));
}
if (browser.url !== serverData.Url)
{
browser.url = serverData.Url;
}
browser.inputEnabled = false;
RenderThings(render, browser)
})
}
function RenderThings(render, browser)
{
mp.game.ui.setTextRenderId(render); //Set render ID of render target
mp.game.graphics.set2dLayer(4); //Only layer 4 works
if (browser && mp.browsers.exists(browser)) {
mp.game.graphics.drawSprite(browser.headlessTextureDict, browser.headlessTextureName, 0.5, 0.5, 1, -1, 0, 255, 255, 255, 255, true);
//mp.game.graphics.drawSprite(test.headlessTextureDict, test.headlessTextureName, 0.5, 0.5, 1, 1, 0, 255, 255, 255, 100, true);
}
mp.game.ui.setTextRenderId(1); //Do not forget to reset the render ID. 1 is always the default render target the game uses
}
function CreateRenderTarget(name, model)
{
if(!mp.game.ui.isNamedRendertargetRegistered(name))
mp.game.ui.registerNamedRendertarget(name, false); //Register render target
if(!mp.game.ui.isNamedRendertargetLinked(mp.game.joaat(model)))
mp.game.ui.linkNamedRendertarget(mp.game.joaat(model)); //Link it to all models
if(mp.game.ui.isNamedRendertargetRegistered(name))
return mp.game.ui.getNamedRendertargetRenderId(name); //Get the handle
return -1;
}
Вуаля у нас есть телевизор, но есть несколько нюансов, о которых вам нужно знать.
1. Это качество изображений на объектах, на большинстве объектов качество хромает и это не поправить об этом сказал сам Георг (Владелец рейджа)
3. Все объекты на которых можно рендерить можно найти тут => https://wiki.rage.mp/index.php?title=Render_Targets
4. Есть нюансы при использовании, на одном объекте одного типа можно назначить только один браузер
То есть если я создам два телевизора prop_x17dlc_monitor_wall_01a, и задам им разные ссылки рендер будет навешивать один и тот же браузер на каждый из них при пуше новой ссылки на один из телевизоров.
Далее по функционалу кода.
createobj - Создаст объект телевизора
updaterender - Команда не описывает её действия, но тем не менее дает возможность отключить/включить рендер данного браузера.
pushurl - Задаст новую ссылку на рендер для выбранного командой объекта. (Над каждым телевизором будет видеть информация о нем, видно на скрине)
removeobj - Удаляет телевизор
Вроде бы все код работает 100 из 100, если будут проблемы или будут предложения по улучшению прошу в комментарии
P.s И да если это может идти в конкурс который вроде еще не закончился было бы здорово)0|
UPD: Если у вас браузер перевернут, на клиенте в функции RenderThings замените строчку
mp.game.graphics.drawSprite(browser.headlessTextureDict, browser.headlessTextureName, 0.5, 0.5, 1, -1, 0, 255, 255, 255, 255, true);
На это mp.game.graphics.drawSprite(browser.headlessTextureDict, browser.headlessTextureName, 0.5, 0.5, 1, 1, 0, 255, 255, 255, 255, true);
И все должно быть гуд
Последнее редактирование: