sneakyevil / IL2CPP_Resolver

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

Game crashes on AddComponent method. #52

Closed svorogaze closed 5 months ago

svorogaze commented 5 months 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 5 months 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 5 months ago

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

sneakyevil commented 5 months 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 5 months 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"