sneakyevil / IL2CPP_Resolver

A run-time API resolver for IL2CPP Unity.
https://sneakyevil.gitbook.io/il2cpp-resolver/
The Unlicense
323 stars 65 forks source link

Game crashes on AddComponent method. #52

Closed svorogaze closed 3 weeks ago

svorogaze commented 3 weeks ago

What is the game you are using with IL2CPP Resolver?

SCP:SL

Details:

I am trying to add UnityEngine.Light to the Game Object named "Default Camera", but the game crashes on linem_pObject->AddComponent(ptr);. Also, if I comment out m_pObject->AddComponent(ptr); line, auto m_pObject = Unity::GameObject::Find("Default Camera"); seems to drop my fps from 200+ to 20(if I iterate over gameobjects manually fps doesn't decrease)

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

void ourmain() {
    Unity::il2cppClass* cptr = IL2CPP::Class::Find("UnityEngine.Light");
    Unity::il2cppObject* ptr = nullptr;
    if (cptr) {
       ptr = Unity::Object::New(cptr);
    }
    auto m_pObject = Unity::GameObject::Find("Default Camera");
    if (m_pObject && ptr && cptr) {
        m_pObject->AddComponent(ptr);
    }
}

In main:

IL2CPP::Initialize();
IL2CPP::Callback::Initialize();
IL2CPP::Callback::OnLateUpdate::Add(ourmain);
sneakyevil commented 3 weeks ago

You're supposed to pass il2cppObject as type not create new object, the game creates it for you. The issue why GameObject::Find causes fps drop is based on the game and how many objects are in the scene, you should either cache the object ptr or itter through all objects and use hash name check or different approach to obtain the object.

svorogaze commented 3 weeks ago

Thank you for your answer! Could you please clarify what you mean by "You're supposed to pass il2cppObject as type"?

sneakyevil commented 3 weeks ago

Thank you for your answer! Could you please clarify what you mean by "You're supposed to pass il2cppObject as type"?

AddComponent takes il2cppObject pointer and the argument is called "SystemType" so you will need to use this to get the type: https://github.com/sneakyevil/IL2CPP_Resolver/blob/9cb0706360c46516a4fd8c6578d1d603ca90b90a/API/Class.hpp#L50

svorogaze commented 3 weeks ago

I rewrited my code, but now it always prints "component not found" even if I add it in the same update.

void ourmain() {
    static auto start = std::chrono::high_resolution_clock::now();
    auto cur = std::chrono::high_resolution_clock::now();
    if (std::chrono::duration<double, std::milli>(cur - start).count() > 1000) {
        start = cur;
        auto ptr = Unity::GameObject::Find("Default Camera");
        if (ptr) {
            Unity::il2cppClass* cptr = IL2CPP::Class::Find("UnityEngine.Light");
            if (cptr) {
                auto pt = ptr->GetComponent("UnityEngine.Light");
                if (!pt) {
                    ptr->AddComponent(IL2CPP::Class::GetSystemType(cptr));
                    pt = ptr->GetComponent("UnityEngine.Light");
                }
                if (pt) {
                    pt->SetPropertyValue("intensity", 1000.f);
                    std::cout << pt->GetPropertyValue<float>("intensity") << '\n';
                }
                else {
                    std::cout << "component not found\n";
                }
            }
        }
    }

}

EDIT:fixed by changing component name in getter from "UnityEngine.Light" to "Light"