catbein Опубликовано 7 июня, 2014 Поделиться Опубликовано 7 июня, 2014 Доброго времени суток всем.Решил я попробовать найти координаты игрока в игре "Lifeless Planet", сначала я пробовал найти высоту то есть ось Z, но среди адресов которые остались в процессе отсева я нашел ось X, после заморозки этой оси я не смог в игре идти назад или вперед. Я поставил бряк на доступ и вот что получилось: Странно то, что адрес который я нашел не получает доступ ни к одной из этих инструкций.И моего адреса там нет, нигде, ни в единой инструкции, вот что получалось когда я находил адреса получающие доступ к любой инструкции что выше, моего адреса там не оказалось (мой адрес 0EA2D244):Я сначала подумал что возможно это другие оси, но заморозка этих значений мне ничего не дало. Я попробовал заглянуть в структуру одной из тех инструкций и вот что получилось: Как вы видите мой адрес находиться со смещением 14, я взял адрес со смещением 10,8,4,0,18,1С и тд. и тп. но среди них не оказалось нужных мне осей Y и Z, почему же в игре координаты не находятся рядом друг от друга с интервалом по смещению и почему когда я хотел найти адреса которые получают доступ к любой инструкции ,- своего адреса я там не нашел???? ну и как мне найти остальные координаты??? Потом после этого я пробовал найти остальные координаты вручную но в итоге после отсева оставалось адресов 400-600. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Никогда с таким не сталкивался, возможно мастера помогут... Может посмотреть на инструкции выше/ниже, в отладчике, вдруг там есть что-то, за что можно зацепиться? Ссылка на комментарий Поделиться на другие сайты Поделиться
A1t0r Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Никогда с таким не сталкивался, возможно мастера помогут... Может посмотреть на инструкции выше/ниже, в отладчике, вдруг там есть что-то, за что можно зацепиться? Сначала дайте новичку попробовать Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Типичная путаница в типах значений.Адрес найденный - 0EA2D244.Инструкции нашлись правильно, но при проверке оказалось, что, оказывается, с этим адресом якобы инструкция не работает. Но, если посмотреть на один адрес из списка, то мы видим0EA2D240, отличающийся от найденного на четыре байта. Отсюда можно сделать вывод, что тип значения найденного был задан неверно, и нужно брать тип вдвое больше заданного. Стало быть, правильный тип координаты получается double, и настоящий адрес координаты именно 0EA2D240. Это же подтверждает и найденная отладчиком инструкцияmovq xmm0,[esi+00000108], что значит move quad word. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Типичная путаница в типах значений.Адрес найденный - 0EA2D244.Инструкции нашлись правильно, но при проверке оказалось, что, оказывается, с этим адресом якобы инструкция не работает. Но, если посмотреть на один адрес из списка, то мы видим0EA2D240, отличающийся от найденного на четыре байта. Отсюда можно сделать вывод, что тип значения найденного был задан неверно, и нужно брать тип вдвое больше заданного. Стало быть, правильный тип координаты получается double, и настоящий адрес координаты именно 0EA2D240. Это же подтверждает и найденная отладчиком инструкцияmovq xmm0,[esi+00000108], что значит move quad word.Ну вот, как я и говорил, мастера помогут А у меня вопрос по поводу проблемы ТС - почему адреса при заморозке не хотели замораживаться? Это также связано с типами? Но мы ведь меняем тип найденного значения в СЕ, а не в самой игре, то есть, отослав значение - игра, как мне кажется, должна "подогнать" это значение под то, какое ей больше подходит (целочисленное, с плавающей точкой и т.д.).Или проблема кроется именно в СЕ, что из-за неверного типа, он работает с адресом неправильно? Ссылка на комментарий Поделиться на другие сайты Поделиться
A1t0r Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Типичная путаница в типах значений.Адрес найденный - 0EA2D244.Инструкции нашлись правильно, но при проверке оказалось, что, оказывается, с этим адресом якобы инструкция не работает. Но, если посмотреть на один адрес из списка, то мы видим0EA2D240, отличающийся от найденного на четыре байта. Отсюда можно сделать вывод, что тип значения найденного был задан неверно, и нужно брать тип вдвое больше заданного. Стало быть, правильный тип координаты получается double, и настоящий адрес координаты именно 0EA2D240. Это же подтверждает и найденная отладчиком инструкцияmovq xmm0,[esi+00000108], что значит move quad word.А нужные инструкции, которые загружают значения координат XYZ соответственно:004842EB - DD 00 - fld qword ptr [eax]004842F3 - DD 40 08 - fld qword ptr [eax+08]004842F9 - DD 40 10 - fld qword ptr [eax+10]Если править значения double по адресам eax 0 +8 +10 происходит перемещение в заданные мировые координаты.Можно писать телепорт)Ну вот, как я и говорил, мастера помогут А у меня вопрос по поводу проблемы ТС - почему адреса при заморозке не хотели замораживаться? Это также связано с типами? Но мы ведь меняем тип найденного значения в СЕ, а не в самой игре, то есть, отослав значение - игра, как мне кажется, должна "подогнать" это значение под то, какое ей больше подходит (целочисленное, с плавающей точкой и т.д.).Или проблема кроется именно в СЕ, что из-за неверного типа, он работает с адресом неправильно?Всё морозится нормально в типе double Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Я сначала подумал что возможно это другие оси, но заморозка этих значений мне ничего не дало. Я попробовал заглянуть в структуру одной из тех инструкций и вот что получилось:Получается, что не морозилось.У меня в общем-то тоже была похожая проблема, что находил вроде правильный адрес (т.е. менял его - в игре это все правилось), а вот не замораживался он, и все тут... Потом, сменив тип (вроде-бы... не помню уже ), адрес заморозился правильно. Вот мне и интересно узнать было бы о данном явлении, кто виноват Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Если в СЕ задан тип неправильно, то и заморозить он не сможет в тех случаях, когда тип, как и в данном случае, вдвое больше указанного. Часть одна замораживается, а вторая - нет. Или же просто вообще заморозка не срабатывает. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Если в СЕ задан тип неправильно, то и заморозить он не сможет в тех случаях, когда тип, как и в данном случае, вдвое больше указанного. Часть одна замораживается, а вторая - нет. Или же просто вообще заморозка не срабатывает.Я в принципе так и думал, что корень зла в путанице работы адреса кроется в типе, указанном в СЕ. Правда, кроме этой мысли, я чуть-ли не целую теорию слепил, вплоть до бракованных планок ОЗУ Ссылка на комментарий Поделиться на другие сайты Поделиться
catbein Опубликовано 8 июня, 2014 Автор Поделиться Опубликовано 8 июня, 2014 От души спасибо за помощь, я просто читал ваши статьи и про такие проблемы там ни слова не было и это загнало меня в тупик. Большое спасибо теперь разобрался))))) Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Игра сделана на Unity3d. В каталоге с игрой обычно одна папка "название игры_Data" в ней папка "Managed" и там обязательно есть файл "Assembly-CSharp.dll" Это .net сборка, которая содержит практически всю логику игры и её объектов. Обычно она декомпилируется, но часто её обратно перекомпоновать нельзя из-за большого количества ошибок. Если научится загружать .net сборки в саму игру, то предположительно можно наделать много интересных читов к игре сделанной на Unity3d.У меня уже же есть два скрипта, которые могут работать на играх Unity3d с видом от первого лица. Это полет камерой и телепорт.Я сегодня пол дня проковырялся и ни как не могу подгрузить Cheat.dll (.net сборку) с читами изнутри этой игры.По идее надо выполнить код ниже внутри самой игры с вызовом функции (на C++ аналог функции - точки входа в dll-ку) Assembly a = Assembly.Load("Cheat.dll"); System.Type myType = a.GetType("Cheats"); MethodInfo myMethod = myType.GetMethod("Main"); object obj = System.Activator.CreateInstance(myType); myMethod.Invoke(obj, null);Я вызывал этот код из самой Unity3d на тестовом проекте и dll-ка дотнетовская загружалась, чит работал, надпись зеленная горела. Значит осталось как-то исполнить этот код изнутри самой игры... Если кто в курсе как это сделать, то дайте знать.Что делает вызов Майн-функции? Эта функция должна создать пустой GameObject и прицепить на него него поведение-скрипт позволяющий сохранять и загружать позиции.public class Cheats{ public static void Main(){ GameObject go = new GameObject(); go.name = "Cheats"; go.AddComponent<Teleport>(); }}Ну и вот класс телепорта в этой ддлке, который предположительно должен заработать или хотя бы загореться зеленная надпись в левом верхнем углу экрана. Функции Update() и OnGUI() уже будут вызываться самой игрой за кадр отрисовки.using UnityEngine;using System.Collections;public class Teleport : MonoBehaviour {Transform trCharacter;#region MonoBehaviourvoid Start() { trCharacter = FindFirstCharacterController().transform;}void OnGUI(){ GUI.color = Color.green; GUILayout.Label("Gamehacklab.ru");}void Update() { //Save : "KeyCode.F1" if(Input.GetKey(KeyCode.F1)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null){ PlayerPrefs.SetString("Character Position", Vector3ToString(trCharacter.position)); PlayerPrefs.SetString("Character Rotation", Vector3ToString(trCharacter.eulerAngles)); } } //Load : "KeyCode.F2" if(Input.GetKey(KeyCode.F2)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null && PlayerPrefs.HasKey("Character Position") && PlayerPrefs.HasKey("Character Rotation")){ trCharacter.position = StringToVector3(PlayerPrefs.GetString("Character Position")); trCharacter.eulerAngles = StringToVector3(PlayerPrefs.GetString("Character Rotation")); } }}#endregionCharacterController FindFirstCharacterController(){ Object[] gos = GameObject.FindObjectsOfType(typeof(GameObject)); foreach (Object item in gos) { if((item as GameObject).GetComponent<CharacterController>() != null){ return (item as GameObject).GetComponent<CharacterController>(); } } return null;}Vector3 StringToVector3(string argString){ string[] values = argString.Split(';'); return new Vector3 (float.Parse(values[0]), float.Parse(values[1]),float.Parse(values[2]));}string Vector3ToString(Vector3 argVector3){ return string.Format("{0};{1};{2}", argVector3.x, argVector3.y, argVector3.z);}}-----Есть программа Titanium 0.01. Поковырявшись в ней я так понял, что она использует моно функции, которые подгружают ддлки из той же папки Managed. Но мне кажется есть несколько способов и этот не самый лучший. Ссылка на комментарий Поделиться на другие сайты Поделиться
Coder Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 MasterGH, remote code injection или dll injection не подойдёт для твоих целей? Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 За подсказку спасибо. Я посмотрю позже, сейчас на отдых.Как говориться если долго мучиться, что-нибудь получиться. В общем телепорт получился. Летающая камера получилась криво, но летает. С камерой надо будет уточнять, какой игровой скрипт выключить, чтобы он не двигал камеру....Устав искать решение по загрузчику, я использовал титаниум. Поковырял его, нашел имя процесса. Переименовал игру в rust.exe и папку на "rust_Data" . В файле настроек Loader.ini ввел[Titanium]module_name=Cheat.dllnamespace=NamespaceCheatsclass=Cheatsfunction=MainСкрипт создающий чит-объектusing System;using UnityEngine;namespace NamespaceCheats{public class Cheats{ public static void Main(){ GameObject go = new GameObject(); go.name = "Cheats"; go.AddComponent<Teleport>(); go.AddComponent<CheatFlyCamera>(); }}}Два чита сделанные можно сказать "по интуиции", т.к. нет исходников игры (телепорт прокатил, а камера нет):using UnityEngine;using System.Collections;public class Teleport : MonoBehaviour {Transform trCharacter;string savePosition = "unknow position";#region MonoBehaviourvoid Awake(){ DontDestroyOnLoad(this);}void Start() { trCharacter = FindFirstCharacterController().transform;}void OnGUI(){ GUI.color = Color.green;a GUILayout.BeginHorizontal(); GUILayout.Label("Teleport: "); GUILayout.Label(savePosition); GUILayout.EndHorizontal();}void Update() { //Save : "KeyCode.F1" if(Input.GetKey(KeyCode.F1)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null){ savePosition = Vector3ToString(trCharacter.position); PlayerPrefs.SetString("Character Position", Vector3ToString(trCharacter.position)); PlayerPrefs.SetString("Character Rotation", Vector3ToString(trCharacter.eulerAngles)); } } //Load : "KeyCode.F2" if(Input.GetKey(KeyCode.F2)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null && PlayerPrefs.HasKey("Character Position") && PlayerPrefs.HasKey("Character Rotation")){ trCharacter.position = StringToVector3(PlayerPrefs.GetString("Character Position")); trCharacter.eulerAngles = StringToVector3(PlayerPrefs.GetString("Character Rotation")); } }}#endregionCharacterController FindFirstCharacterController(){ Object[] gos = GameObject.FindSceneObjectsOfType(typeof(GameObject)); foreach (Object item in gos) { if((item as GameObject).GetComponent<CharacterController>() != null){ return (item as GameObject).GetComponent<CharacterController>(); } } return null;}Vector3 StringToVector3(string argString){ string[] values = argString.Split(';'); return new Vector3 (float.Parse(values[0]), float.Parse(values[1]),float.Parse(values[2]));}string Vector3ToString(Vector3 argVector3){ return string.Format("{0};{1};{2}", argVector3.x, argVector3.y, argVector3.z);}}using UnityEngine;using System.Collections;public class CheatFlyCamera : MonoBehaviour {public KeyCode keyActivated = KeyCode.CapsLock;public float acceleration = 2f, minSpeed = 1f, maxSpeed = 20f;public float mouseSensitivityX = 1f, mouseSensitivityY = 1f;//public GUIStyle guiStyle;float speed = 1f, rotationY = 0f;Transform cameraTransform;bool isActive;GameObject goPerson = null;bool[] lastState = null;void UpdateFindObjects(){ if(cameraTransform == null){ cameraTransform = Camera.main.transform; if(cameraTransform == null){ cameraTransform = Camera.mainCamera.transform; } } if(goPerson == null){ //goPerson = GameObject.Find("3rd Person Controller"); goPerson = CheatBaseFunction.FindFirstComponent<CharacterController>().gameObject; }}#region MonoBehaviorvoid Awake(){ DontDestroyOnLoad(this);}void Start(){ UpdateFindObjects();}void OnGUI(){ GUILayout.BeginVertical(); GUILayout.Space(20f); GUILayout.Label("Press \"Caps Lock\" Button"); //guiStyle GUILayout.EndVertical();}void Update(){// if(Input.GetKeyDown(KeyCode.Escape)){// Application.Quit();// } if(Input.GetKeyDown(keyActivated)){ UpdateFindObjects(); if(goPerson != null && cameraTransform != null){ isActive = !isActive; goPerson.SetActiveRecursively(!isActive); if(goPerson.active){ if(lastState != null && lastState.Length > 0){ CheatBaseFunction.RestoreStateComponents(cameraTransform.gameObject, lastState); } }else{ CheatBaseFunction.SetStateComponents(cameraTransform.gameObject, false, out lastState); } } } if(isActive){ bool isSomeKey = false; float timePerFrame = Time.deltaTime; if(Input.GetKey(KeyCode.W)){ UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } isSomeKey = true; speed += acceleration * timePerFrame; speed = Mathf.Clamp(speed + timePerFrame, minSpeed, maxSpeed); cameraTransform.position += ImullQuaternionToPpoint(cameraTransform.localRotation, Vector3.forward * speed * timePerFrame); } if(Input.GetKey(KeyCode.A)){ UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } isSomeKey = true; speed += acceleration * timePerFrame; speed = Mathf.Clamp(speed + timePerFrame, minSpeed, maxSpeed); cameraTransform.position += ImullQuaternionToPpoint(cameraTransform.localRotation, Vector3.left * speed * timePerFrame); } if(Input.GetKey(KeyCode.D)){ UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } isSomeKey = true; speed += acceleration * timePerFrame; speed = Mathf.Clamp(speed + timePerFrame, minSpeed, maxSpeed); cameraTransform.position += ImullQuaternionToPpoint(cameraTransform.localRotation, Vector3.right * speed * timePerFrame); } if(Input.GetKey(KeyCode.S)){ UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } isSomeKey = true; speed += acceleration * timePerFrame; speed = Mathf.Clamp(speed + timePerFrame, minSpeed, maxSpeed); cameraTransform.position += ImullQuaternionToPpoint(cameraTransform.localRotation, Vector3.back * speed * timePerFrame); } if(Input.GetKey(KeyCode.Space)){ UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } isSomeKey = true; speed += acceleration * timePerFrame; speed = Mathf.Clamp(speed + timePerFrame, minSpeed, maxSpeed); Vector3 pos = cameraTransform.position; pos.y += speed * timePerFrame; cameraTransform.position = pos; } if(!isSomeKey){ speed = Mathf.Lerp(speed, minSpeed, timePerFrame); } UpdateFindObjects(); if(goPerson == null || cameraTransform == null){ return; } float rotationX = cameraTransform.localEulerAngles.y + Input.GetAxis("Mouse X") * mouseSensitivityX; rotationY += Input.GetAxis("Mouse Y") * mouseSensitivityY; rotationY = Mathf.Clamp (rotationY, -90f, 90f); cameraTransform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); }}#endregionpublic Vector3 ImullQuaternionToPpoint(Quaternion rotation, Vector3 point){ float num = rotation.x * 2f; float num2 = rotation.y * 2f; float num3 = rotation.z * 2f; float num4 = rotation.x * num; float num5 = rotation.y * num2; float num6 = rotation.z * num3; float num7 = rotation.x * num2; float num8 = rotation.x * num3; float num9 = rotation.y * num3; float num10 = rotation.w * num; float num11 = rotation.w * num2; float num12 = rotation.w * num3; Vector3 result; result.x = (1f - (num5 + num6)) * point.x + (num7 - num12) * point.y + (num8 + num11) * point.z; result.y = (num7 + num12) * point.x + (1f - (num4 + num6)) * point.y + (num9 - num10) * point.z; result.z = (num8 - num11) * point.x + (num9 + num10) * point.y + (1f - (num4 + num5)) * point.z; return result;}}using UnityEngine;using System.Collections;public static class CheatBaseFunction {public static T FindFirstComponent<T>() where T : Component{ Object[] gos = GameObject.FindSceneObjectsOfType(typeof(GameObject)); foreach (Object item in gos) { if((item as GameObject).GetComponent<T>() != null){ return (item as GameObject).GetComponent<T>(); } } return null;}public static void SetStateComponents(GameObject go, bool newState, out bool[] lastState){ Component[] components = go.GetComponents(typeof(Behaviour)); int max = components.Length; lastState = new bool[max]; for (int i = 0; i < max; i++) { lastState[i] = (components[i] as Behaviour).enabled; (components[i] as Behaviour).enabled = newState; }}public static void RestoreStateComponents(GameObject go, bool[] lastState){ Component[] components = go.GetComponents(typeof(Behaviour)); int max = lastState.Length; if(components.Length == max){ for (int i = 0; i < max; i++) { (components[i] as Behaviour).enabled = lastState[i]; } }}}Кстати этот код выше, который я написал на самом деле только кажется большим. Я на работе, когда задание дают пишу гораздо больше.А вот, что можно делать скриптами Unity3d в чужой игре вызывая стандартные скриптовые функции описанные в документации на официальном сайте. Кнопки, менюшки это все стандартные функции класса GUI На видео мультиплеррная игра Rust (вроде валяется на Стиме). Я знаю, что мы не ломаем мультиплеерные игры и не обсуждаем, но более наглядного видео я не нашел. В сингловых играх можно теоритически делать абсолютно тоже самое и даже еще больше и это будет прикольно.На данный момент количество игр на Unity3d растет. Думаю вскоре будут интересные игры и на Windows. Ссылка на комментарий Поделиться на другие сайты Поделиться
Maxs Опубликовано 8 июня, 2014 Поделиться Опубликовано 8 июня, 2014 Игра сделана на Unity3d. В каталоге с игрой обычно одна папка "название игры_Data" в ней папка "Managed" и там обязательно есть файл "Assembly-CSharp.dll" Это .net сборка, которая содержит практически всю логику игры и её объектов. Обычно она декомпилируется, но часто её обратно перекомпоновать нельзя из-за большого количества ошибок. Если научится загружать .net сборки в саму игру, то предположительно можно наделать много интересных читов к игре сделанной на Unity3d.У меня уже же есть два скрипта, которые могут работать на играх Unity3d с видом от первого лица. Это полет камерой и телепорт.Я сегодня пол дня проковырялся и ни как не могу подгрузить Cheat.dll (.net сборку) с читами изнутри этой игры.По идее надо выполнить код ниже внутри самой игры с вызовом функции (на C++ аналог функции - точки входа в dll-ку) Assembly a = Assembly.Load("Cheat.dll"); System.Type myType = a.GetType("Cheats"); MethodInfo myMethod = myType.GetMethod("Main"); object obj = System.Activator.CreateInstance(myType); myMethod.Invoke(obj, null);Я вызывал этот код из самой Unity3d на тестовом проекте и dll-ка дотнетовская загружалась, чит работал, надпись зеленная горела. Значит осталось как-то исполнить этот код изнутри самой игры... Если кто в курсе как это сделать, то дайте знать.Что делает вызов Майн-функции? Эта функция должна создать пустой GameObject и прицепить на него него поведение-скрипт позволяющий сохранять и загружать позиции.public class Cheats{ public static void Main(){ GameObject go = new GameObject(); go.name = "Cheats"; go.AddComponent<Teleport>(); }}Ну и вот класс телепорта в этой ддлке, который предположительно должен заработать или хотя бы загореться зеленная надпись в левом верхнем углу экрана. Функции Update() и OnGUI() уже будут вызываться самой игрой за кадр отрисовки.using UnityEngine;using System.Collections;public class Teleport : MonoBehaviour {Transform trCharacter;#region MonoBehaviourvoid Start() { trCharacter = FindFirstCharacterController().transform;}void OnGUI(){ GUI.color = Color.green; GUILayout.Label("Gamehacklab.ru");}void Update() { //Save : "KeyCode.F1" if(Input.GetKey(KeyCode.F1)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null){ PlayerPrefs.SetString("Character Position", Vector3ToString(trCharacter.position)); PlayerPrefs.SetString("Character Rotation", Vector3ToString(trCharacter.eulerAngles)); } } //Load : "KeyCode.F2" if(Input.GetKey(KeyCode.F2)){ if(trCharacter == null){ trCharacter = FindFirstCharacterController().transform; } if(trCharacter != null && PlayerPrefs.HasKey("Character Position") && PlayerPrefs.HasKey("Character Rotation")){ trCharacter.position = StringToVector3(PlayerPrefs.GetString("Character Position")); trCharacter.eulerAngles = StringToVector3(PlayerPrefs.GetString("Character Rotation")); } }}#endregionCharacterController FindFirstCharacterController(){ Object[] gos = GameObject.FindObjectsOfType(typeof(GameObject)); foreach (Object item in gos) { if((item as GameObject).GetComponent<CharacterController>() != null){ return (item as GameObject).GetComponent<CharacterController>(); } } return null;}Vector3 StringToVector3(string argString){ string[] values = argString.Split(';'); return new Vector3 (float.Parse(values[0]), float.Parse(values[1]),float.Parse(values[2]));}string Vector3ToString(Vector3 argVector3){ return string.Format("{0};{1};{2}", argVector3.x, argVector3.y, argVector3.z);}}-----Есть программа Titanium 0.01. Поковырявшись в ней я так понял, что она использует моно функции, которые подгружают ддлки из той же папки Managed. Но мне кажется есть несколько способов и этот не самый лучший.Пили видос по Unity3D Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 11 июня, 2014 Поделиться Опубликовано 11 июня, 2014 Привет детишки и взрослые! Сегодня после работы написал скриптец (ниже) показывающий иерархию объектов игры и связанные компоненты во время игры и на любой сцене с обновлением в 5 секунд + копирование лога данных. Лог в аттаче.Из компонентов можно найти стандартные и нестандартные. В данном случае видны названия объектов и связи между ними. Если отключить родительский, то отключатся и дочерние. У отключенных игровых объектов перестают работать скрипты.using UnityEngine;using System.Collections;using System.Collections.Generic;using System.Text;public class ProviderHierarchy : MonoBehaviour {#region Typespublic class Data{ public Transform tr; public bool isShow; public string caption; public List<Data> tree = new List<Data>(); public Data(Transform tr, string caption){ this.tr = tr; this.caption = caption;} public void Add(Data data){ tree.Add(data);} public void Add(Transform tr, string caption){tree.Add(new Data(tr, caption));} public void OnGUI(ref Rect parentRect, float dx, float dy, float dx1, float dy1){ float lastX = parentRect.x; parentRect.x = parentRect.x + dx; parentRect.y = parentRect.y + dy; GUI.Label(parentRect, caption); parentRect.x += dx1; foreach (Data item in tree) { parentRect.y += dy1; item.OnGUI(ref parentRect, dx, dy, dx1, dy1); } parentRect.x = lastX; }}#endregionpublic Rect rectWindow = new Rect(10f, 34.5f, 500f, 700f), rectBtnCopy; = new Rect(0f, 0f, 120f, 30f);public string caption = "Tree view";public float timeUpdate = 5f, dx = 0.7f, dy = 1.72f, dx1 = 10f, dy1 = 12.45f;float lstTime;List<Transform> trList = new List<Transform>();public Rect rectView, parentRect;Data treeData = null;Vector2 scrollView;#region MonoBehaviourvoid Awake(){ DontDestroyOnLoad(this);}void Start(){ rectView = rectWindow; rectView.x += 20f; rectView.y += 20f; rectView.width -= 40f; rectView.height -= 40f; UpdateTreeView();}void OnGUI(){ if(treeData == null || isCopyText) return; GUI.Box(rectView, caption); rectWindow.height = parentRect.y + 10f; scrollView = GUI.BeginScrollView(rectView, scrollView, rectWindow , true, true); parentRect = new Rect(rectView.x + 10f, rectView.y, rectView.width - 10f, rectView.height - 10f); treeData.OnGUI(ref parentRect, dx, dy, dx1, dy1); GUI.EndScrollView(); if(GUI.Button(rectBtnCopy, "Coppy To Buffer")){ System.Type T = typeof(GUIUtility); System.Reflection.PropertyInfo systemCopyBufferProperty = T.GetProperty("systemCopyBuffer", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); systemCopyBufferProperty.SetValue(null, GetTextInfo().ToString(), null); }}void Update(){ if(isCopyText){ return; } lstTime += Time.deltaTime; if(lstTime > timeUpdate){ lstTime = 0f; UpdateTreeView(); }}#endregion#region MyRegionvoid UpdateTreeView(){ Object[] objects = FindObjectsOfType(typeof(GameObject)); trList = new List<Transform>(); foreach (Object item in objects) trList.Add((item as GameObject).transform); //Собрать объекты у которых нет родителей и есть родители List<Transform> parentList = new List<Transform>(); List<Transform> childsList = new List<Transform>(); foreach (Transform item in trList){ if(item.parent == null) parentList.Add(item); else childsList.Add(item); } // Заполняем список treeData = new Data(null, "Game Objects"); foreach (Transform parent in parentList) { // Объект не имеющий родителей Data parentData = new Data(parent, parent.gameObject.name); treeData.Add(parentData); // Рекурсивный поиск детей объектов FindChilds(childsList, parentData); }}void FindChilds(List<Transform> childs, Data parentData){ Transform parent = parentData.tr; foreach (Transform mayByChild in childs){ if(mayByChild.parent == parent){ // Поиск детей у детей Data childData = new Data(mayByChild, mayByChild.gameObject.name); parentData.Add(childData); FindChilds(childs, childData); } }}bool isCopyText;StringBuilder GetTextInfo(){ StringBuilder sb = new StringBuilder(); isCopyText = true; Object[] objects = FindObjectsOfType(typeof(GameObject)); trList = new List<Transform>(); foreach (Object item in objects) trList.Add((item as GameObject).transform); //Собрать объекты у которых нет родителей и есть родители List<Transform> parentList = new List<Transform>(); List<Transform> childsList = new List<Transform>(); foreach (Transform item in trList){ if(item.parent == null) parentList.Add(item); else childsList.Add(item); } treeData = new Data(null, "Game Objects"); int innerCount = 0; foreach (Transform parent in parentList) { // Объект не имеющий родителей //sb.AppendLine(parent.gameObject.name); sb.AppendLine(string.Format(" {0}", parent.gameObject.name)); // Рекурсивный поиск детей объектов innerCount = 0; FindChildsStringToBuilder(childsList, parent, ref sb, ref innerCount); } isCopyText = false; return sb;}#endregionbool FindChildsStringToBuilder(List<Transform> childs, Transform parent, ref StringBuilder sb, ref int innerCount){ int firstInnerCount = innerCount; bool someFind = false; innerCount++; string empty = string.Empty; for (int i = 0; i < innerCount; i++) empty += " "; foreach (Transform mayByChild in childs){ if(mayByChild.parent == parent){ // Поиск детей у детей sb.Append(string.Format(" {0}|_{1}", empty, mayByChild.gameObject.name)); FindComponentsStringToBuilder(mayByChild, ref sb); FindChildsStringToBuilder(childs, mayByChild, ref sb, ref innerCount); someFind = true; } } innerCount = firstInnerCount; return someFind;}void FindComponentsStringToBuilder(Transform parent, ref StringBuilder sb){ sb.Append(" ("); Component[] comps = parent.GetComponents(typeof(Component)); foreach (Component item in comps) { sb.Append(item.ToString()); sb.Append(", "); } sb.AppendLine(" )");}}В архиве полный текстовый лог из буфера обменаHierarchy Lifeless.rarКак это все можно использовать?Пока собственно пользы никакой. Только просмотреть какие связи между объектами, компонентами. Роль объектов и компонентов можно предположить по названию. Стандартные компоненты можно увидеть на официальном сайте движка.В будущем можно сделать так. Выделив объект камера может к нему подлететь и можно этот объект рассмотреть в полете. Так можно исследовать всю игровую сцену. Она вроде там большая и бегать по ней замучаешься. Так что исследовать все лазейки можно этим способом....Невольно задумаешься, что у всех игровых движков есть набор базовых функций, которыми можно так же всю иерархию игровых объектов вывести на обзорCheat.rar Ссылка на комментарий Поделиться на другие сайты Поделиться
Maxs Опубликовано 13 июня, 2014 Поделиться Опубликовано 13 июня, 2014 ...Вопрос глупый... но сталкивался я часто... как вы находите координаты игрока?Допустим автор темы нашел координату X... Как?Как он нашел где 0? Где он нашел, что если идти в право X прибавляется, а не уменьшается? Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения